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))