Mercurial > public > ostc4
comparison Small_CPU/Src/batteryCharger.c @ 696:cc542448fb28
Merge
author | heinrichsweikamp |
---|---|
date | Fri, 19 Aug 2022 11:30:24 +0200 |
parents | b1e24513b83e |
children | d32901746950 |
comparison
equal
deleted
inserted
replaced
661:87bee7cc77b3 | 696:cc542448fb28 |
---|---|
35 | 35 |
36 | 36 |
37 /* Use This compile switch to select the new charger status control implementation */ | 37 /* Use This compile switch to select the new charger status control implementation */ |
38 #define ENABLE_CHARGER_STATUS_V2 | 38 #define ENABLE_CHARGER_STATUS_V2 |
39 | 39 |
40 #define CHARGE_IN_PIN GPIO_PIN_2 | 40 #define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ |
41 #define CHARGE_IN_GPIO_PORT GPIOC | 41 |
42 #define CHARGE_IN_GPIO_ENABLE() __GPIOC_CLK_ENABLE() | 42 static uint8_t battery_i_charge_status = 0; |
43 | 43 static uint16_t battery_charger_counter = 0; |
44 #define CHARGE_OUT_PIN GPIO_PIN_1 | |
45 #define CHARGE_OUT_GPIO_PORT GPIOC | |
46 #define CHARGE_OUT_GPIO_ENABLE() __GPIOC_CLK_ENABLE() | |
47 | |
48 #define CHARGER_DEBOUNCE_SECONDS (5u) /* 5 seconds used to avoid problems with charger interrupts / disconnections */ | |
49 | |
50 uint8_t battery_i_charge_status = 0; | |
51 uint16_t battery_charger_counter = 0; | |
52 | 44 |
53 #ifdef ENABLE_CHARGER_STATUS_V2 | 45 #ifdef ENABLE_CHARGER_STATUS_V2 |
54 typedef enum | |
55 { | |
56 Charger_NotConnected = 0, /* This is identified reading CHARGE_IN_PIN == HIGH */ | |
57 Charger_WarmUp, /* Charging started but counter did not yet reach a certain limit (used to debounce connect / disconnect events to avoid multiple increases of statistic charging cycle counter) */ | |
58 Charger_Active, /* Charging identified by CHARGE_IN_PIN == LOW for a certain time */ | |
59 Charger_Finished, | |
60 Charger_LostConnection /* Intermediate state to debounce disconnecting events (including charging error state like over temperature) */ | |
61 } chargerState_t; | |
62 | |
63 static chargerState_t batteryChargerState = Charger_NotConnected; | 46 static chargerState_t batteryChargerState = Charger_NotConnected; |
64 #endif | 47 #endif |
65 | 48 |
66 /* can be 0, 1 or 255 | 49 /* can be 0, 1 or 255 |
67 * 0 is disconnected | 50 * 0 is disconnected |
71 uint8_t get_charge_status(void) | 54 uint8_t get_charge_status(void) |
72 { | 55 { |
73 return battery_i_charge_status; | 56 return battery_i_charge_status; |
74 } | 57 } |
75 | 58 |
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 | |
76 void init_battery_charger_status(void) | 74 void init_battery_charger_status(void) |
77 { | 75 { |
78 #ifdef OSTC_ON_DISCOVERY_HARDWARE | 76 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
79 return; | 77 return; |
80 #endif | 78 #endif |
148 #ifdef OSTC_ON_DISCOVERY_HARDWARE | 146 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
149 return; | 147 return; |
150 #endif | 148 #endif |
151 | 149 |
152 #ifdef ENABLE_CHARGER_STATUS_V2 | 150 #ifdef ENABLE_CHARGER_STATUS_V2 |
153 /* on disconnection or while disconnected */ | 151 |
154 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | 152 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ |
155 { | 153 { |
156 switch(batteryChargerState) | 154 if((global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) && (global.lifeData.battery_voltage < BATTERY_CHARGER_CONNECTED_VOLTAGE)) |
157 { | 155 { |
158 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | 156 if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ |
159 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | 157 { |
160 batteryChargerState = Charger_LostConnection; | 158 battery_gas_gauge_set_charge_full(); |
161 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | 159 } |
162 | 160 batteryChargerState = Charger_NotConnected; |
163 if(get_voltage() >= 4.1f) /* the charger stops charging when charge current is 1/10. */ | 161 } |
164 { /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ | 162 } |
165 batteryChargerState = Charger_Finished; | 163 else |
166 global.dataSendToMaster.chargeStatus = CHARGER_complete; | 164 { /* on disconnection or while disconnected */ |
167 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | 165 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) |
168 battery_charger_counter = 15; | 166 { |
169 notifyChargeComplete = 1; | 167 switch(batteryChargerState) |
170 } | 168 { |
171 break; | 169 case Charger_WarmUp: |
172 case Charger_WarmUp: | 170 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; |
173 case Charger_Finished: | |
174 case Charger_LostConnection: if(battery_charger_counter >= cycleTimeBase) | |
175 { | |
176 battery_charger_counter -= cycleTimeBase; | |
177 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
178 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | 171 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; |
179 batteryChargerState = Charger_LostConnection; | 172 batteryChargerState = Charger_LostConnection; |
180 } | 173 if(cycleTimeBase > CHARGER_DEBOUNCE_SECONDS) /* adapt connection lost detection to sleep mode */ |
181 else | 174 { |
182 { | 175 battery_charger_counter = cycleTimeBase + 1; |
176 } | |
177 else | |
178 { | |
179 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | |
180 } | |
181 break; | |
182 case Charger_Finished: battery_charger_counter = 0; | |
183 batteryChargerState = Charger_LostConnection; | |
184 /* no break */ | |
185 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 */ | |
187 if(((battery_gas_gauge_isChargeValueValid() == 0) || (global.lifeData.battery_charge < 90)) && (get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) && (get_voltage() < BATTERY_CHARGER_CONNECTED_VOLTAGE)) | |
188 { | |
189 notifyChargeComplete = 1; | |
190 } | |
191 else | |
192 { | |
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; | |
202 battery_i_charge_status = 0; | |
203 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
204 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
205 | |
206 if(notifyChargeComplete) | |
207 { | |
208 battery_gas_gauge_set_charge_full(); | |
209 scheduleUpdateDeviceDataChargerFull(); | |
210 notifyChargeComplete = 0; | |
211 } | |
212 batteryChargerState = Charger_NotConnected; | |
213 } | |
214 break; | |
215 default: break; | |
216 } | |
217 } | |
218 else | |
219 { | |
220 /* connected */ | |
221 /* wait for disconnection to write and reset */ | |
222 switch(batteryChargerState) | |
223 { | |
224 case Charger_NotConnected: battery_i_charge_status = 1; | |
183 battery_charger_counter = 0; | 225 battery_charger_counter = 0; |
184 battery_i_charge_status = 0; | 226 batteryChargerState = Charger_WarmUp; |
185 global.dataSendToMaster.chargeStatus = CHARGER_off; | 227 break; |
186 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | 228 case Charger_LostConnection: batteryChargerState = Charger_Active; |
187 | 229 break; |
188 if(notifyChargeComplete) | 230 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; |
189 { | 231 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) |
190 battery_gas_gauge_set_charge_full(); | 232 { |
191 scheduleUpdateDeviceDataChargerFull(); | 233 battery_i_charge_status = 2; |
192 notifyChargeComplete = 0; | 234 scheduleUpdateDeviceDataChargerCharging(); |
193 } | |
194 batteryChargerState = Charger_NotConnected; | |
195 } | |
196 break; | |
197 default: break; | |
198 } | |
199 } | |
200 else | |
201 { | |
202 /* connected */ | |
203 /* wait for disconnection to write and reset */ | |
204 switch(batteryChargerState) | |
205 { | |
206 case Charger_NotConnected: battery_i_charge_status = 1; | |
207 battery_charger_counter = 0; | |
208 batteryChargerState = Charger_WarmUp; | |
209 break; | |
210 case Charger_LostConnection: batteryChargerState = Charger_Active; | |
211 break; | |
212 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; | |
213 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) | |
214 { | |
215 battery_i_charge_status = 2; | |
216 scheduleUpdateDeviceDataChargerCharging(); | |
217 batteryChargerState = Charger_Active; | |
218 } | |
219 /* no break */ | |
220 case Charger_Finished: | |
221 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; | |
222 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
223 | |
224 /* drive the output pin high to determine the state of the charger */ | |
225 GPIO_InitTypeDef GPIO_InitStructure; | |
226 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
227 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; | |
228 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
229 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
230 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
231 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | |
232 HAL_Delay(1); | |
233 | |
234 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ | |
235 { | |
236 batteryChargerState = Charger_Finished; | |
237 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
238 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
239 battery_charger_counter = 30; | |
240 notifyChargeComplete = 1; | |
241 } | |
242 else | |
243 { | |
244 if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ | |
245 { | |
246 batteryChargerState = Charger_Active; | 235 batteryChargerState = Charger_Active; |
247 notifyChargeComplete = 0; | 236 } |
248 } | 237 /* no break */ |
249 } | 238 case Charger_Finished: |
250 | 239 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; |
251 /* restore high impedance to be able to detect disconnection */ | 240 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; |
252 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | 241 |
253 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | 242 /* drive the output pin high to determine the state of the charger */ |
254 GPIO_InitStructure.Pull = GPIO_NOPULL; | 243 GPIO_InitTypeDef GPIO_InitStructure; |
255 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | 244 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; |
256 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | 245 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; |
257 HAL_Delay(1); | 246 GPIO_InitStructure.Pull = GPIO_NOPULL; |
258 break; | 247 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; |
259 | 248 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
260 default: /* wait for disconnection */ | 249 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); |
261 break; | 250 HAL_Delay(1); |
251 | |
252 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ | |
253 { | |
254 batteryChargerState = Charger_Finished; | |
255 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
256 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
257 battery_charger_counter = 30; | |
258 notifyChargeComplete = 1; | |
259 } | |
260 else | |
261 { | |
262 if(global.lifeData.battery_charge > 100.0) /* still charging but indicator is set to full => decrease to 99% to keep count increasing */ | |
263 { | |
264 battery_gas_gauge_set(99.0); | |
265 } | |
266 if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ | |
267 { | |
268 batteryChargerState = Charger_Active; | |
269 notifyChargeComplete = 0; | |
270 } | |
271 } | |
272 | |
273 /* restore high impedance to be able to detect disconnection */ | |
274 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
275 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
276 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
277 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
278 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
279 HAL_Delay(1); | |
280 break; | |
281 | |
282 default: /* wait for disconnection */ | |
283 break; | |
284 } | |
262 } | 285 } |
263 } | 286 } |
264 #else | 287 #else |
265 /* on disconnection or while disconnected */ | 288 /* on disconnection or while disconnected */ |
266 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | 289 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) |