Mercurial > public > ostc4
annotate Small_CPU/Src/batteryCharger.c @ 664:667093daa937 Betatest
Stability improvment bluetooth startup:
The previous implementation expected a default setup of the Bluetooth module. Deviations from the default expectation caused the init function to stop. The new implementation is able to fix wrong baud rate setting (reset baudrate to default 115200).
In addition the function evaluating the answers of the module is not able to derive the status out of a data stream.
author | Ideenmodellierer |
---|---|
date | Tue, 21 Dec 2021 19:36:41 +0100 |
parents | 1b995079c045 |
children | 079bb5b22c06 |
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 |
42 uint8_t battery_i_charge_status = 0; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
43 uint16_t battery_charger_counter = 0; |
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; |
662 | 144 static float chargeValueAtStart = 0; |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
145 #endif |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
146 |
38 | 147 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
148 return; | |
149 #endif | |
150 | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
151 #ifdef ENABLE_CHARGER_STATUS_V2 |
662 | 152 |
153 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
154 { |
662 | 155 if(global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
156 { |
662 | 157 if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ |
158 { | |
159 battery_gas_gauge_set_charge_full(); | |
160 } | |
161 else /* unknown state => reset to 0% */ | |
162 { | |
163 battery_gas_gauge_set(0); | |
164 } | |
165 batteryChargerState = Charger_NotConnected; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
166 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
167 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
168 else |
662 | 169 { /* on disconnection or while disconnected */ |
170 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
171 { |
662 | 172 switch(batteryChargerState) |
173 { | |
174 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
175 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
176 batteryChargerState = Charger_LostConnection; | |
177 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | |
178 break; | |
179 case Charger_LostConnection: if(get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) /* the charger stops charging when charge current is 1/10 */ | |
180 /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ | |
181 { | |
182 batteryChargerState = Charger_Finished; | |
183 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
184 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
185 notifyChargeComplete = 1; | |
186 } | |
187 /* no break */ | |
188 case Charger_WarmUp: | |
189 case Charger_Finished: if(battery_charger_counter >= cycleTimeBase) | |
190 { | |
191 battery_charger_counter -= cycleTimeBase; | |
192 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
193 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
194 batteryChargerState = Charger_LostConnection; | |
195 } | |
196 else | |
197 { | |
198 battery_charger_counter = 0; | |
199 battery_i_charge_status = 0; | |
200 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
201 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
202 |
662 | 203 if(notifyChargeComplete) |
204 { | |
205 battery_gas_gauge_set_charge_full(); | |
206 scheduleUpdateDeviceDataChargerFull(); | |
207 notifyChargeComplete = 0; | |
208 if(cycleTimeBase > 2) | |
209 { | |
210 HAL_Delay(50); /* I2C operations are pending in the background. Wait to avoid data loose in caused to potential change to sleep state */ | |
211 } | |
212 } | |
213 else | |
214 { | |
215 if(chargeValueAtStart < 1.0) /* charging started with unknown value => reset charge state reported by charger */ | |
216 { | |
217 battery_gas_gauge_set(0); | |
218 } | |
219 } | |
220 batteryChargerState = Charger_NotConnected; | |
221 } | |
222 break; | |
223 default: break; | |
224 } | |
225 } | |
226 else | |
227 { | |
228 /* connected */ | |
229 /* wait for disconnection to write and reset */ | |
230 switch(batteryChargerState) | |
231 { | |
232 case Charger_NotConnected: battery_i_charge_status = 1; | |
233 battery_charger_counter = 0; | |
234 batteryChargerState = Charger_WarmUp; | |
235 chargeValueAtStart = global.lifeData.battery_charge; | |
236 break; | |
237 case Charger_LostConnection: batteryChargerState = Charger_Active; | |
238 break; | |
239 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; | |
240 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) | |
241 { | |
242 battery_i_charge_status = 2; | |
243 scheduleUpdateDeviceDataChargerCharging(); | |
244 batteryChargerState = Charger_Active; | |
245 } | |
246 /* no break */ | |
247 case Charger_Finished: | |
248 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; | |
249 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
250 |
662 | 251 /* drive the output pin high to determine the state of the charger */ |
252 GPIO_InitTypeDef GPIO_InitStructure; | |
253 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
254 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; | |
255 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
256 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
257 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
258 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | |
259 HAL_Delay(1); | |
260 | |
261 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ | |
262 { | |
263 batteryChargerState = Charger_Finished; | |
264 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
265 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
266 battery_charger_counter = 30; | |
267 notifyChargeComplete = 1; | |
268 } | |
269 else | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
270 { |
662 | 271 if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ |
272 { | |
273 batteryChargerState = Charger_Active; | |
274 notifyChargeComplete = 0; | |
275 } | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
276 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
277 |
662 | 278 /* restore high impedance to be able to detect disconnection */ |
279 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
280 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
281 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
282 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
283 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
284 HAL_Delay(1); | |
285 break; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
286 |
662 | 287 default: /* wait for disconnection */ |
288 break; | |
289 } | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
290 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
291 } |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
292 #else |
38 | 293 /* on disconnection or while disconnected */ |
294 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | |
295 { | |
296 if(battery_charger_counter) | |
297 { | |
298 battery_charger_counter--; | |
299 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
300 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
301 } | |
302 /* max count down to 127+5 or 127+20 */ | |
303 if((battery_i_charge_status == 255) && battery_charger_counter < 127) | |
304 { | |
305 // battery_gas_gauge_set_charge_full(); | |
306 // scheduleUpdateDeviceDataChargerFull(); | |
307 battery_charger_counter = 0; | |
308 } | |
309 | |
310 if(battery_charger_counter == 0) | |
311 { | |
312 battery_i_charge_status = 0; | |
313 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
314 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
315 | |
316 } | |
317 return; | |
318 } | |
319 | |
320 /* connected */ | |
321 | |
322 /* wait for disconnection to write and reset */ | |
323 if(battery_i_charge_status == 255) | |
324 { | |
325 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
326 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
327 | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
328 if(((cycleTimeBase > 1) && (battery_charger_counter < 127+5)) || (battery_charger_counter < 127+20)) |
38 | 329 battery_charger_counter++; |
330 return; | |
331 } | |
332 | |
333 if(battery_charger_counter == 0) | |
334 battery_i_charge_status = 1; | |
335 | |
336 /* charger is connected and didn't signal full yet */ | |
337 global.dataSendToMaster.chargeStatus = CHARGER_running; | |
338 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
339 | |
340 GPIO_InitTypeDef GPIO_InitStructure; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
341 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
342 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
343 GPIO_InitStructure.Pull = GPIO_NOPULL; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
344 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; |
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
345 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
38 | 346 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); |
347 HAL_Delay(1); | |
348 | |
349 | |
350 if(battery_charger_counter < 120) | |
351 { | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
352 if(cycleTimeBase == 1) |
38 | 353 battery_charger_counter++; |
354 else | |
355 { | |
356 battery_charger_counter += 30; | |
357 if(battery_charger_counter >= 127) | |
358 battery_charger_counter = 126; | |
359 } | |
360 } | |
361 else | |
362 if(battery_charger_counter < 127) | |
363 { | |
364 battery_charger_counter = 127; | |
365 if(battery_i_charge_status < 2) | |
366 { | |
367 battery_i_charge_status = 2; | |
368 scheduleUpdateDeviceDataChargerCharging(); | |
369 } | |
370 } | |
371 | |
372 if(battery_charger_counter >= 127) | |
373 { | |
374 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN) || (get_voltage() >= 4.1f)) | |
375 { | |
376 battery_charger_counter++; | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
377 if(((cycleTimeBase > 1) && (battery_charger_counter > 127+5)) || (battery_charger_counter > 127+20)) |
38 | 378 { |
379 battery_charger_counter = 127; | |
380 if(get_voltage() >= 4.1f) | |
381 { | |
382 battery_i_charge_status = 255; | |
383 battery_gas_gauge_set_charge_full(); | |
384 scheduleUpdateDeviceDataChargerFull(); | |
385 } | |
386 } | |
387 } | |
388 else | |
389 battery_charger_counter = 127; | |
390 } | |
391 | |
392 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
393 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
394 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
395 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
396 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
643
5149cd644fbc
Reimplemented charger status generation (deactivated):
Ideenmodellierer
parents:
38
diff
changeset
|
397 #endif |
38 | 398 } |
399 | |
400 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ |