Mercurial > public > ostc4
comparison Small_CPU/Src/batteryCharger.c @ 859:d32901746950 Evo_2_23
Improvment battery charger visualization:
In the previous version the green flash (charge complete) was shown even battery had not reached 100% charge. Root cause was that the pin signaling the end of charge could be raised for other reasons then a full battery. The new version will show the green flash only in case the battery is rated as full.
In addition the graph visualization has been updated to continously progress. In the previous version it only progressed in case the charge value changed. Especially at charging start the charger is doing some battery evaluation which does not increase the charge state. In such a case the graph seemed to be frozen.
author | Ideenmodellierer |
---|---|
date | Tue, 07 May 2024 21:20:33 +0200 |
parents | b1e24513b83e |
children |
comparison
equal
deleted
inserted
replaced
858:08ea8e9d6cfe | 859:d32901746950 |
---|---|
32 #include "batteryGasGauge.h" | 32 #include "batteryGasGauge.h" |
33 #include "stm32f4xx_hal.h" | 33 #include "stm32f4xx_hal.h" |
34 #include "scheduler.h" | 34 #include "scheduler.h" |
35 | 35 |
36 | 36 |
37 /* Use This compile switch to select the new charger status control implementation */ | |
38 #define ENABLE_CHARGER_STATUS_V2 | |
39 | |
40 #define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ | 37 #define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ |
41 | 38 |
42 static uint8_t battery_i_charge_status = 0; | |
43 static uint16_t battery_charger_counter = 0; | 39 static uint16_t battery_charger_counter = 0; |
44 | |
45 #ifdef ENABLE_CHARGER_STATUS_V2 | |
46 static chargerState_t batteryChargerState = Charger_NotConnected; | 40 static chargerState_t batteryChargerState = Charger_NotConnected; |
47 #endif | |
48 | |
49 /* can be 0, 1 or 255 | |
50 * 0 is disconnected | |
51 * 1 is charging | |
52 * 255 is full | |
53 */ | |
54 uint8_t get_charge_status(void) | |
55 { | |
56 return battery_i_charge_status; | |
57 } | |
58 | 41 |
59 void set_charge_state(uint8_t newState) | 42 void set_charge_state(uint8_t newState) |
60 { | 43 { |
61 #ifdef ENABLE_CHARGER_STATUS_V2 | |
62 if(newState < Charger_END) | 44 if(newState < Charger_END) |
63 { | 45 { |
64 batteryChargerState = newState; | 46 batteryChargerState = newState; |
65 } | 47 } |
66 #endif | |
67 } | 48 } |
68 | 49 |
69 uint8_t get_charge_state(void) | 50 uint8_t get_charge_state(void) |
70 { | 51 { |
71 return batteryChargerState; | 52 return batteryChargerState; |
122 | 103 |
123 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | 104 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; |
124 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | 105 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
125 } | 106 } |
126 | 107 |
127 /* static counter is used to avoid multiple counts of charge startings | |
128 and after that it is used, starting at 127 to count for the charge full signal | |
129 | |
130 there a short disconnections with the QI charger | |
131 therefore the battery_charger_counter has a countdown instead of = 0. | |
132 | |
133 battery_gas_gauge_set_charge_full and scheduleUpdateDeviceDataChargerFull are | |
134 set after disconnection as the charging process continues as long as not disconnected | |
135 to prevent the short disconnections the battery_charger_counter is used too including | |
136 upcounting again while battery_i_charge_status == 255 and the connection is established | |
137 | |
138 */ | |
139 | |
140 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) | 108 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) |
141 { | 109 { |
142 #ifdef ENABLE_CHARGER_STATUS_V2 | |
143 static uint8_t notifyChargeComplete = 0; | 110 static uint8_t notifyChargeComplete = 0; |
144 #endif | |
145 | 111 |
146 #ifdef OSTC_ON_DISCOVERY_HARDWARE | 112 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
147 return; | 113 return; |
148 #endif | 114 #endif |
149 | 115 |
150 #ifdef ENABLE_CHARGER_STATUS_V2 | |
151 | |
152 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ | 116 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ |
153 { | 117 { |
154 if((global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) && (global.lifeData.battery_voltage < BATTERY_CHARGER_CONNECTED_VOLTAGE)) | 118 if(global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) /* wait for first valid voltage value */ |
155 { | 119 { |
156 if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ | 120 if((global.lifeData.battery_voltage < BATTERY_CHARGER_CONNECTED_VOLTAGE) |
121 && (global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE)) /* Voltage close to full state => maybe new battery inserted */ | |
157 { | 122 { |
158 battery_gas_gauge_set_charge_full(); | 123 battery_gas_gauge_set_charge_full(); |
159 } | 124 } |
160 batteryChargerState = Charger_NotConnected; | 125 batteryChargerState = Charger_NotConnected; |
161 } | 126 } |
177 else | 142 else |
178 { | 143 { |
179 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | 144 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; |
180 } | 145 } |
181 break; | 146 break; |
182 case Charger_Finished: battery_charger_counter = 0; | 147 case Charger_Finished: if((get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) && (get_voltage() < BATTERY_CHARGER_CONNECTED_VOLTAGE)) /* stopping does not necessarily mean battery is full */ |
148 { | |
149 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
150 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
151 notifyChargeComplete = 1; | |
152 } | |
153 battery_charger_counter = 10; | |
183 batteryChargerState = Charger_LostConnection; | 154 batteryChargerState = Charger_LostConnection; |
184 /* no break */ | 155 /* no break */ |
185 case Charger_LostConnection: /* the charger stops charging when charge current is 1/10 */ | 156 case Charger_LostConnection: /* the charger stops charging when charge current is 1/10 */ |
186 /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ | 157 /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ |
187 if(((battery_gas_gauge_isChargeValueValid() == 0) || (global.lifeData.battery_charge < 90)) && (get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) && (get_voltage() < BATTERY_CHARGER_CONNECTED_VOLTAGE)) | 158 if(((battery_gas_gauge_isChargeValueValid() == 0) || (global.lifeData.battery_charge < 90)) && (get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) && (get_voltage() < BATTERY_CHARGER_CONNECTED_VOLTAGE)) |
188 { | 159 { |
189 notifyChargeComplete = 1; | 160 notifyChargeComplete = 1; |
190 } | 161 } |
162 if(battery_charger_counter >= cycleTimeBase) | |
163 { | |
164 battery_charger_counter -= cycleTimeBase; | |
165 } | |
191 else | 166 else |
192 { | 167 { |
193 notifyChargeComplete = 0; | |
194 } | |
195 if(battery_charger_counter >= cycleTimeBase) | |
196 { | |
197 battery_charger_counter -= cycleTimeBase; | |
198 } | |
199 else | |
200 { | |
201 battery_charger_counter = 0; | 168 battery_charger_counter = 0; |
202 battery_i_charge_status = 0; | 169 |
203 global.dataSendToMaster.chargeStatus = CHARGER_off; | 170 global.dataSendToMaster.chargeStatus = CHARGER_off; |
204 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | 171 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; |
205 | 172 |
206 if(notifyChargeComplete) | 173 if(notifyChargeComplete) |
207 { | 174 { |
208 battery_gas_gauge_set_charge_full(); | 175 battery_gas_gauge_set_charge_full(); |
209 scheduleUpdateDeviceDataChargerFull(); | 176 scheduleUpdateDeviceDataChargerFull(); |
210 notifyChargeComplete = 0; | |
211 } | 177 } |
178 notifyChargeComplete = 0; | |
212 batteryChargerState = Charger_NotConnected; | 179 batteryChargerState = Charger_NotConnected; |
213 } | 180 } |
214 break; | 181 break; |
215 default: break; | 182 default: batteryChargerState = Charger_NotConnected; /* unexpected state => reinitialize state machine */ |
183 break; | |
216 } | 184 } |
217 } | 185 } |
218 else | 186 else |
219 { | 187 { |
220 /* connected */ | 188 /* connected */ |
221 /* wait for disconnection to write and reset */ | 189 /* wait for disconnection to write and reset */ |
222 switch(batteryChargerState) | 190 switch(batteryChargerState) |
223 { | 191 { |
224 case Charger_NotConnected: battery_i_charge_status = 1; | 192 case Charger_NotConnected: battery_charger_counter = 0; |
225 battery_charger_counter = 0; | |
226 batteryChargerState = Charger_WarmUp; | 193 batteryChargerState = Charger_WarmUp; |
227 break; | 194 break; |
228 case Charger_LostConnection: batteryChargerState = Charger_Active; | 195 case Charger_LostConnection: batteryChargerState = Charger_Active; |
229 break; | 196 break; |
230 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; | 197 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; |
231 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) | 198 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) |
232 { | 199 { |
233 battery_i_charge_status = 2; | |
234 scheduleUpdateDeviceDataChargerCharging(); | 200 scheduleUpdateDeviceDataChargerCharging(); |
235 batteryChargerState = Charger_Active; | 201 batteryChargerState = Charger_Active; |
236 } | 202 } |
237 /* no break */ | 203 /* no break */ |
238 case Charger_Finished: | 204 case Charger_Finished: |
249 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | 215 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); |
250 HAL_Delay(1); | 216 HAL_Delay(1); |
251 | 217 |
252 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ | 218 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ |
253 { | 219 { |
220 battery_charger_counter = 30; | |
254 batteryChargerState = Charger_Finished; | 221 batteryChargerState = Charger_Finished; |
255 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
256 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
257 battery_charger_counter = 30; | |
258 notifyChargeComplete = 1; | |
259 } | 222 } |
260 else | 223 else |
261 { | 224 { |
262 if(global.lifeData.battery_charge > 100.0) /* still charging but indicator is set to full => decrease to 99% to keep count increasing */ | 225 if(global.lifeData.battery_charge > 100.0) /* still charging but indicator is set to full => decrease to 99% to keep count increasing */ |
263 { | 226 { |
277 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | 240 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; |
278 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | 241 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
279 HAL_Delay(1); | 242 HAL_Delay(1); |
280 break; | 243 break; |
281 | 244 |
282 default: /* wait for disconnection */ | 245 default: batteryChargerState = Charger_NotConnected; /* unexpected state => reinitialize state machine */ |
283 break; | 246 break; |
284 } | 247 } |
285 } | 248 } |
286 } | 249 } |
287 #else | |
288 /* on disconnection or while disconnected */ | |
289 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | |
290 { | |
291 if(battery_charger_counter) | |
292 { | |
293 battery_charger_counter--; | |
294 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
295 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
296 } | |
297 /* max count down to 127+5 or 127+20 */ | |
298 if((battery_i_charge_status == 255) && battery_charger_counter < 127) | |
299 { | |
300 // battery_gas_gauge_set_charge_full(); | |
301 // scheduleUpdateDeviceDataChargerFull(); | |
302 battery_charger_counter = 0; | |
303 } | |
304 | |
305 if(battery_charger_counter == 0) | |
306 { | |
307 battery_i_charge_status = 0; | |
308 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
309 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
310 | |
311 } | |
312 return; | |
313 } | |
314 | |
315 /* connected */ | |
316 | |
317 /* wait for disconnection to write and reset */ | |
318 if(battery_i_charge_status == 255) | |
319 { | |
320 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
321 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
322 | |
323 if(((cycleTimeBase > 1) && (battery_charger_counter < 127+5)) || (battery_charger_counter < 127+20)) | |
324 battery_charger_counter++; | |
325 return; | |
326 } | |
327 | |
328 if(battery_charger_counter == 0) | |
329 battery_i_charge_status = 1; | |
330 | |
331 /* charger is connected and didn't signal full yet */ | |
332 global.dataSendToMaster.chargeStatus = CHARGER_running; | |
333 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
334 | |
335 GPIO_InitTypeDef GPIO_InitStructure; | |
336 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
337 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; | |
338 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
339 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
340 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
341 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | |
342 HAL_Delay(1); | |
343 | |
344 | |
345 if(battery_charger_counter < 120) | |
346 { | |
347 if(cycleTimeBase == 1) | |
348 battery_charger_counter++; | |
349 else | |
350 { | |
351 battery_charger_counter += 30; | |
352 if(battery_charger_counter >= 127) | |
353 battery_charger_counter = 126; | |
354 } | |
355 } | |
356 else | |
357 if(battery_charger_counter < 127) | |
358 { | |
359 battery_charger_counter = 127; | |
360 if(battery_i_charge_status < 2) | |
361 { | |
362 battery_i_charge_status = 2; | |
363 scheduleUpdateDeviceDataChargerCharging(); | |
364 } | |
365 } | |
366 | |
367 if(battery_charger_counter >= 127) | |
368 { | |
369 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN) || (get_voltage() >= 4.1f)) | |
370 { | |
371 battery_charger_counter++; | |
372 if(((cycleTimeBase > 1) && (battery_charger_counter > 127+5)) || (battery_charger_counter > 127+20)) | |
373 { | |
374 battery_charger_counter = 127; | |
375 if(get_voltage() >= 4.1f) | |
376 { | |
377 battery_i_charge_status = 255; | |
378 battery_gas_gauge_set_charge_full(); | |
379 scheduleUpdateDeviceDataChargerFull(); | |
380 } | |
381 } | |
382 } | |
383 else | |
384 battery_charger_counter = 127; | |
385 } | |
386 | |
387 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
388 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
389 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
390 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
391 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
392 #endif | |
393 } | 250 } |
394 | 251 |
395 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ | 252 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ |