Mercurial > public > ostc4
comparison Small_CPU/Src/batteryCharger.c @ 662:1b995079c045 Betatest
PSCR Mode
author | heinrichs weikamp |
---|---|
date | Tue, 14 Dec 2021 15:36:10 +0100 |
parents | e58f81cb25a7 |
children | 079bb5b22c06 |
comparison
equal
deleted
inserted
replaced
661:87bee7cc77b3 | 662:1b995079c045 |
---|---|
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 | |
42 #define CHARGE_IN_GPIO_ENABLE() __GPIOC_CLK_ENABLE() | |
43 | |
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 | 41 |
50 uint8_t battery_i_charge_status = 0; | 42 uint8_t battery_i_charge_status = 0; |
51 uint16_t battery_charger_counter = 0; | 43 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 |
141 | 139 |
142 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) | 140 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) |
143 { | 141 { |
144 #ifdef ENABLE_CHARGER_STATUS_V2 | 142 #ifdef ENABLE_CHARGER_STATUS_V2 |
145 static uint8_t notifyChargeComplete = 0; | 143 static uint8_t notifyChargeComplete = 0; |
144 static float chargeValueAtStart = 0; | |
146 #endif | 145 #endif |
147 | 146 |
148 #ifdef OSTC_ON_DISCOVERY_HARDWARE | 147 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
149 return; | 148 return; |
150 #endif | 149 #endif |
151 | 150 |
152 #ifdef ENABLE_CHARGER_STATUS_V2 | 151 #ifdef ENABLE_CHARGER_STATUS_V2 |
153 /* on disconnection or while disconnected */ | 152 |
154 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | 153 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ |
155 { | 154 { |
156 switch(batteryChargerState) | 155 if(global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) |
157 { | 156 { |
158 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | 157 if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ |
159 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | 158 { |
160 batteryChargerState = Charger_LostConnection; | 159 battery_gas_gauge_set_charge_full(); |
161 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | 160 } |
162 | 161 else /* unknown state => reset to 0% */ |
163 if(get_voltage() >= 4.1f) /* the charger stops charging when charge current is 1/10. */ | 162 { |
164 { /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ | 163 battery_gas_gauge_set(0); |
165 batteryChargerState = Charger_Finished; | 164 } |
166 global.dataSendToMaster.chargeStatus = CHARGER_complete; | 165 batteryChargerState = Charger_NotConnected; |
167 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | 166 } |
168 battery_charger_counter = 15; | 167 } |
169 notifyChargeComplete = 1; | 168 else |
170 } | 169 { /* on disconnection or while disconnected */ |
171 break; | 170 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) |
172 case Charger_WarmUp: | 171 { |
173 case Charger_Finished: | 172 switch(batteryChargerState) |
174 case Charger_LostConnection: if(battery_charger_counter >= cycleTimeBase) | 173 { |
175 { | 174 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; |
176 battery_charger_counter -= cycleTimeBase; | |
177 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
178 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | 175 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; |
179 batteryChargerState = Charger_LostConnection; | 176 batteryChargerState = Charger_LostConnection; |
180 } | 177 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; |
181 else | 178 break; |
182 { | 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; | |
202 | |
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; | |
183 battery_charger_counter = 0; | 233 battery_charger_counter = 0; |
184 battery_i_charge_status = 0; | 234 batteryChargerState = Charger_WarmUp; |
185 global.dataSendToMaster.chargeStatus = CHARGER_off; | 235 chargeValueAtStart = global.lifeData.battery_charge; |
186 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | 236 break; |
187 | 237 case Charger_LostConnection: batteryChargerState = Charger_Active; |
188 if(notifyChargeComplete) | 238 break; |
189 { | 239 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; |
190 battery_gas_gauge_set_charge_full(); | 240 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) |
191 scheduleUpdateDeviceDataChargerFull(); | 241 { |
192 notifyChargeComplete = 0; | 242 battery_i_charge_status = 2; |
193 } | 243 scheduleUpdateDeviceDataChargerCharging(); |
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; | 244 batteryChargerState = Charger_Active; |
247 notifyChargeComplete = 0; | 245 } |
248 } | 246 /* no break */ |
249 } | 247 case Charger_Finished: |
250 | 248 case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; |
251 /* restore high impedance to be able to detect disconnection */ | 249 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; |
252 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | 250 |
253 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | 251 /* drive the output pin high to determine the state of the charger */ |
254 GPIO_InitStructure.Pull = GPIO_NOPULL; | 252 GPIO_InitTypeDef GPIO_InitStructure; |
255 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | 253 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; |
256 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | 254 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; |
257 HAL_Delay(1); | 255 GPIO_InitStructure.Pull = GPIO_NOPULL; |
258 break; | 256 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; |
259 | 257 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
260 default: /* wait for disconnection */ | 258 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); |
261 break; | 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 | |
270 { | |
271 if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ | |
272 { | |
273 batteryChargerState = Charger_Active; | |
274 notifyChargeComplete = 0; | |
275 } | |
276 } | |
277 | |
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; | |
286 | |
287 default: /* wait for disconnection */ | |
288 break; | |
289 } | |
262 } | 290 } |
263 } | 291 } |
264 #else | 292 #else |
265 /* on disconnection or while disconnected */ | 293 /* on disconnection or while disconnected */ |
266 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | 294 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) |