Mercurial > public > ostc4
annotate Small_CPU/Src/batteryCharger.c @ 682:8775d3dc6325 Betatest
Bugfix low ppO2 warning in bailout mode:
the code has different sources for divesettings (real and simulated). The ppo2 calculation code used the pointer to the real structure. As result in simulation mode an error occured caused by the ppo2 calculation which was not aware that a bailout happened (because the real structure was references instead of the simulator ones). The problem has been fixed by using the "stateUsed" pointer which is refering to the structure currenty in use.
author | Ideenmodellierer |
---|---|
date | Mon, 25 Apr 2022 21:15:01 +0200 |
parents | 079bb5b22c06 |
children | b1e24513b83e |
rev | line source |
---|---|
38 | 1 /** |
2 ****************************************************************************** | |
3 * @file batteryCharger.c | |
4 * @author heinrichs weikamp gmbh | |
5 * @date 09-Dec-2014 | |
6 * @version V0.0.1 | |
7 * @since 09-Dec-2014 | |
8 * @brief LTC4054 Battery Charger | |
9 * | |
10 @verbatim | |
11 ============================================================================== | |
12 ##### How to use ##### | |
13 ============================================================================== | |
14 | |
15 The bq5105x provides one status output, CHG. This output is an open-drain NMOS device that is rated to 20 V. | |
16 The open-drain FET connected to the CHG pin will be turned on whenever the output (BAT) of the charger is | |
17 enabled. As a note, the output of the charger supply will not be enabled if the VRECT-REG does not converge to the | |
18 no-load target voltage. | |
19 | |
644 | 20 CHG F4 7 O Open-drain output � active when BAT is enabled. Float if not used. |
38 | 21 |
22 @endverbatim | |
23 ****************************************************************************** | |
24 * @attention | |
25 * | |
26 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2> | |
27 * | |
28 ****************************************************************************** | |
29 */ | |
30 /* Includes ------------------------------------------------------------------*/ | |
31 #include "batteryCharger.h" | |
32 #include "batteryGasGauge.h" | |
33 #include "stm32f4xx_hal.h" | |
34 #include "scheduler.h" | |
35 | |
36 | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
37 /* Use This compile switch to select the new charger status control implementation */ |
644 | 38 #define ENABLE_CHARGER_STATUS_V2 |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
39 |
662 | 40 #define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ |
38 | 41 |
668 | 42 static uint8_t battery_i_charge_status = 0; |
43 static uint16_t battery_charger_counter = 0; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
44 |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
45 #ifdef ENABLE_CHARGER_STATUS_V2 |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
46 static chargerState_t batteryChargerState = Charger_NotConnected; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
47 #endif |
38 | 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 | |
662 | 59 void set_charge_state(uint8_t newState) |
60 { | |
61 #ifdef ENABLE_CHARGER_STATUS_V2 | |
62 if(newState < Charger_END) | |
63 { | |
64 batteryChargerState = newState; | |
65 } | |
66 #endif | |
67 } | |
68 | |
69 uint8_t get_charge_state(void) | |
70 { | |
71 return batteryChargerState; | |
72 } | |
73 | |
38 | 74 void init_battery_charger_status(void) |
75 { | |
76 #ifdef OSTC_ON_DISCOVERY_HARDWARE | |
77 return; | |
78 #endif | |
79 | |
80 CHARGE_IN_GPIO_ENABLE(); | |
81 CHARGE_OUT_GPIO_ENABLE(); | |
82 | |
83 ReInit_battery_charger_status_pins(); | |
84 } | |
85 | |
86 void ReInit_battery_charger_status_pins(void) | |
87 { | |
88 #ifdef OSTC_ON_DISCOVERY_HARDWARE | |
89 return; | |
90 #endif | |
91 | |
92 GPIO_InitTypeDef GPIO_InitStructure; | |
93 | |
94 GPIO_InitStructure.Pin = CHARGE_IN_PIN; | |
95 GPIO_InitStructure.Mode = GPIO_MODE_INPUT; | |
96 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
97 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
98 HAL_GPIO_Init(CHARGE_IN_GPIO_PORT, &GPIO_InitStructure); | |
99 | |
100 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
101 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
102 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
103 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
104 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
105 } | |
106 | |
107 | |
108 void DeInit_battery_charger_status_pins(void) | |
109 { | |
110 #ifdef OSTC_ON_DISCOVERY_HARDWARE | |
111 return; | |
112 #endif | |
113 GPIO_InitTypeDef GPIO_InitStructure; | |
114 | |
115 | |
116 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
117 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
118 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
119 | |
120 GPIO_InitStructure.Pin = CHARGE_IN_PIN; | |
121 HAL_GPIO_Init(CHARGE_IN_GPIO_PORT, &GPIO_InitStructure); | |
122 | |
123 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
124 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
125 } | |
126 | |
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 | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
140 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) |
38 | 141 { |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
142 #ifdef ENABLE_CHARGER_STATUS_V2 |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
143 static uint8_t notifyChargeComplete = 0; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
144 #endif |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
145 |
38 | 146 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
147 return; | |
148 #endif | |
149 | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
150 #ifdef ENABLE_CHARGER_STATUS_V2 |
662 | 151 |
152 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
153 { |
662 | 154 if(global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
155 { |
662 | 156 if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ |
157 { | |
158 battery_gas_gauge_set_charge_full(); | |
159 } | |
160 batteryChargerState = Charger_NotConnected; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
161 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
162 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
163 else |
662 | 164 { /* on disconnection or while disconnected */ |
165 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
166 { |
662 | 167 switch(batteryChargerState) |
168 { | |
169 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
170 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
171 batteryChargerState = Charger_LostConnection; | |
172 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | |
173 break; | |
668 | 174 case Charger_LostConnection: /* the charger stops charging when charge current is 1/10 */ |
175 /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ | |
176 if(((battery_gas_gauge_isChargeValueValid() == 0) || (global.lifeData.battery_charge < 90)) && (get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE)) | |
662 | 177 { |
178 batteryChargerState = Charger_Finished; | |
179 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
180 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
181 notifyChargeComplete = 1; | |
668 | 182 battery_charger_counter = 0; |
662 | 183 } |
184 /* no break */ | |
185 case Charger_WarmUp: | |
186 case Charger_Finished: if(battery_charger_counter >= cycleTimeBase) | |
187 { | |
188 battery_charger_counter -= cycleTimeBase; | |
189 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
190 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
191 batteryChargerState = Charger_LostConnection; | |
192 } | |
193 else | |
194 { | |
195 battery_charger_counter = 0; | |
196 battery_i_charge_status = 0; | |
197 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
198 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
199 |
662 | 200 if(notifyChargeComplete) |
201 { | |
202 battery_gas_gauge_set_charge_full(); | |
203 scheduleUpdateDeviceDataChargerFull(); | |
204 notifyChargeComplete = 0; | |
205 if(cycleTimeBase > 2) | |
206 { | |
207 HAL_Delay(50); /* I2C operations are pending in the background. Wait to avoid data loose in caused to potential change to sleep state */ | |
208 } | |
209 } | |
210 batteryChargerState = Charger_NotConnected; | |
211 } | |
212 break; | |
213 default: break; | |
214 } | |
215 } | |
216 else | |
217 { | |
218 /* connected */ | |
219 /* wait for disconnection to write and reset */ | |
220 switch(batteryChargerState) | |
221 { | |
222 case Charger_NotConnected: battery_i_charge_status = 1; | |
223 battery_charger_counter = 0; | |
224 batteryChargerState = Charger_WarmUp; | |
225 break; | |
226 case Charger_LostConnection: batteryChargerState = Charger_Active; | |
227 break; | |
228 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; | |
229 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) | |
230 { | |
231 battery_i_charge_status = 2; | |
232 scheduleUpdateDeviceDataChargerCharging(); | |
233 batteryChargerState = Charger_Active; | |
234 } | |
235 /* no break */ | |
236 case Charger_Finished: | |
237 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; | |
238 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
239 |
662 | 240 /* drive the output pin high to determine the state of the charger */ |
241 GPIO_InitTypeDef GPIO_InitStructure; | |
242 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
243 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; | |
244 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
245 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
246 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
247 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | |
248 HAL_Delay(1); | |
249 | |
250 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ | |
251 { | |
252 batteryChargerState = Charger_Finished; | |
253 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
254 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
255 battery_charger_counter = 30; | |
256 notifyChargeComplete = 1; | |
257 } | |
258 else | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
259 { |
668 | 260 if(global.lifeData.battery_charge > 100.0) /* still charging but indicator is set to full => decrease to 99% to keep count increasing */ |
261 { | |
262 battery_gas_gauge_set(99.0); | |
263 } | |
662 | 264 if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ |
265 { | |
266 batteryChargerState = Charger_Active; | |
267 notifyChargeComplete = 0; | |
268 } | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
269 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
270 |
662 | 271 /* restore high impedance to be able to detect disconnection */ |
272 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
273 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
274 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
275 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
276 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
277 HAL_Delay(1); | |
278 break; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
279 |
662 | 280 default: /* wait for disconnection */ |
281 break; | |
282 } | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
283 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
284 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
285 #else |
38 | 286 /* on disconnection or while disconnected */ |
287 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | |
288 { | |
289 if(battery_charger_counter) | |
290 { | |
291 battery_charger_counter--; | |
292 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
293 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
294 } | |
295 /* max count down to 127+5 or 127+20 */ | |
296 if((battery_i_charge_status == 255) && battery_charger_counter < 127) | |
297 { | |
298 // battery_gas_gauge_set_charge_full(); | |
299 // scheduleUpdateDeviceDataChargerFull(); | |
300 battery_charger_counter = 0; | |
301 } | |
302 | |
303 if(battery_charger_counter == 0) | |
304 { | |
305 battery_i_charge_status = 0; | |
306 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
307 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
308 | |
309 } | |
310 return; | |
311 } | |
312 | |
313 /* connected */ | |
314 | |
315 /* wait for disconnection to write and reset */ | |
316 if(battery_i_charge_status == 255) | |
317 { | |
318 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
319 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
320 | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
321 if(((cycleTimeBase > 1) && (battery_charger_counter < 127+5)) || (battery_charger_counter < 127+20)) |
38 | 322 battery_charger_counter++; |
323 return; | |
324 } | |
325 | |
326 if(battery_charger_counter == 0) | |
327 battery_i_charge_status = 1; | |
328 | |
329 /* charger is connected and didn't signal full yet */ | |
330 global.dataSendToMaster.chargeStatus = CHARGER_running; | |
331 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
332 | |
333 GPIO_InitTypeDef GPIO_InitStructure; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
334 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
335 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
336 GPIO_InitStructure.Pull = GPIO_NOPULL; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
337 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
338 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
38 | 339 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); |
340 HAL_Delay(1); | |
341 | |
342 | |
343 if(battery_charger_counter < 120) | |
344 { | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
345 if(cycleTimeBase == 1) |
38 | 346 battery_charger_counter++; |
347 else | |
348 { | |
349 battery_charger_counter += 30; | |
350 if(battery_charger_counter >= 127) | |
351 battery_charger_counter = 126; | |
352 } | |
353 } | |
354 else | |
355 if(battery_charger_counter < 127) | |
356 { | |
357 battery_charger_counter = 127; | |
358 if(battery_i_charge_status < 2) | |
359 { | |
360 battery_i_charge_status = 2; | |
361 scheduleUpdateDeviceDataChargerCharging(); | |
362 } | |
363 } | |
364 | |
365 if(battery_charger_counter >= 127) | |
366 { | |
367 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN) || (get_voltage() >= 4.1f)) | |
368 { | |
369 battery_charger_counter++; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
370 if(((cycleTimeBase > 1) && (battery_charger_counter > 127+5)) || (battery_charger_counter > 127+20)) |
38 | 371 { |
372 battery_charger_counter = 127; | |
373 if(get_voltage() >= 4.1f) | |
374 { | |
375 battery_i_charge_status = 255; | |
376 battery_gas_gauge_set_charge_full(); | |
377 scheduleUpdateDeviceDataChargerFull(); | |
378 } | |
379 } | |
380 } | |
381 else | |
382 battery_charger_counter = 127; | |
383 } | |
384 | |
385 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
386 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
387 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
388 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
389 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
390 #endif |
38 | 391 } |
392 | |
393 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ |