Mercurial > public > ostc4
comparison Small_CPU/Src/batteryCharger.c @ 981:c6c781a2e85b default
Merge into default
| author | heinrichsweikamp |
|---|---|
| date | Tue, 11 Feb 2025 18:12:00 +0100 |
| parents | d32901746950 |
| children |
comparison
equal
deleted
inserted
replaced
| 871:f7318457df4d | 981:c6c781a2e85b |
|---|---|
| 32 #include "batteryGasGauge.h" | 32 #include "batteryGasGauge.h" |
| 33 #include "stm32f4xx_hal.h" | 33 #include "stm32f4xx_hal.h" |
| 34 #include "scheduler.h" | 34 #include "scheduler.h" |
| 35 | 35 |
| 36 | 36 |
| 37 /* Use This compile switch to select the new charger status control implementation */ | |
| 38 #define ENABLE_CHARGER_STATUS_V2 | |
| 39 | |
| 40 #define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ | 37 #define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ |
| 41 | 38 |
| 42 static uint8_t battery_i_charge_status = 0; | |
| 43 static uint16_t battery_charger_counter = 0; | 39 static uint16_t battery_charger_counter = 0; |
| 44 | |
| 45 #ifdef ENABLE_CHARGER_STATUS_V2 | |
| 46 static chargerState_t batteryChargerState = Charger_NotConnected; | 40 static chargerState_t batteryChargerState = Charger_NotConnected; |
| 47 #endif | |
| 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 | 41 |
| 59 void set_charge_state(uint8_t newState) | 42 void set_charge_state(uint8_t newState) |
| 60 { | 43 { |
| 61 #ifdef ENABLE_CHARGER_STATUS_V2 | |
| 62 if(newState < Charger_END) | 44 if(newState < Charger_END) |
| 63 { | 45 { |
| 64 batteryChargerState = newState; | 46 batteryChargerState = newState; |
| 65 } | 47 } |
| 66 #endif | |
| 67 } | 48 } |
| 68 | 49 |
| 69 uint8_t get_charge_state(void) | 50 uint8_t get_charge_state(void) |
| 70 { | 51 { |
| 71 return batteryChargerState; | 52 return batteryChargerState; |
| 122 | 103 |
| 123 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | 104 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; |
| 124 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | 105 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
| 125 } | 106 } |
| 126 | 107 |
| 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 | |
| 140 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) | 108 void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase) |
| 141 { | 109 { |
| 142 #ifdef ENABLE_CHARGER_STATUS_V2 | |
| 143 static uint8_t notifyChargeComplete = 0; | 110 static uint8_t notifyChargeComplete = 0; |
| 144 #endif | |
| 145 | 111 |
| 146 #ifdef OSTC_ON_DISCOVERY_HARDWARE | 112 #ifdef OSTC_ON_DISCOVERY_HARDWARE |
| 147 return; | 113 return; |
| 148 #endif | 114 #endif |
| 149 | 115 |
| 150 #ifdef ENABLE_CHARGER_STATUS_V2 | |
| 151 | |
| 152 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ | 116 if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ |
| 153 { | 117 { |
| 154 if((global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) && (global.lifeData.battery_voltage < BATTERY_CHARGER_CONNECTED_VOLTAGE)) | 118 if(global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) /* wait for first valid voltage value */ |
| 155 { | 119 { |
| 156 if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ | 120 if((global.lifeData.battery_voltage < BATTERY_CHARGER_CONNECTED_VOLTAGE) |
| 121 && (global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE)) /* Voltage close to full state => maybe new battery inserted */ | |
| 157 { | 122 { |
| 158 battery_gas_gauge_set_charge_full(); | 123 battery_gas_gauge_set_charge_full(); |
| 159 } | 124 } |
| 160 batteryChargerState = Charger_NotConnected; | 125 batteryChargerState = Charger_NotConnected; |
| 161 } | 126 } |
| 177 else | 142 else |
| 178 { | 143 { |
| 179 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; | 144 battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; |
| 180 } | 145 } |
| 181 break; | 146 break; |
| 182 case Charger_Finished: battery_charger_counter = 0; | 147 case Charger_Finished: if((get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) && (get_voltage() < BATTERY_CHARGER_CONNECTED_VOLTAGE)) /* stopping does not necessarily mean battery is full */ |
| 148 { | |
| 149 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
| 150 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
| 151 notifyChargeComplete = 1; | |
| 152 } | |
| 153 battery_charger_counter = 10; | |
| 183 batteryChargerState = Charger_LostConnection; | 154 batteryChargerState = Charger_LostConnection; |
| 184 /* no break */ | 155 /* no break */ |
| 185 case Charger_LostConnection: /* the charger stops charging when charge current is 1/10 */ | 156 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 */ | 157 /* 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)) | 158 if(((battery_gas_gauge_isChargeValueValid() == 0) || (global.lifeData.battery_charge < 90)) && (get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) && (get_voltage() < BATTERY_CHARGER_CONNECTED_VOLTAGE)) |
| 188 { | 159 { |
| 189 notifyChargeComplete = 1; | 160 notifyChargeComplete = 1; |
| 190 } | 161 } |
| 162 if(battery_charger_counter >= cycleTimeBase) | |
| 163 { | |
| 164 battery_charger_counter -= cycleTimeBase; | |
| 165 } | |
| 191 else | 166 else |
| 192 { | 167 { |
| 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; | 168 battery_charger_counter = 0; |
| 202 battery_i_charge_status = 0; | 169 |
| 203 global.dataSendToMaster.chargeStatus = CHARGER_off; | 170 global.dataSendToMaster.chargeStatus = CHARGER_off; |
| 204 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | 171 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; |
| 205 | 172 |
| 206 if(notifyChargeComplete) | 173 if(notifyChargeComplete) |
| 207 { | 174 { |
| 208 battery_gas_gauge_set_charge_full(); | 175 battery_gas_gauge_set_charge_full(); |
| 209 scheduleUpdateDeviceDataChargerFull(); | 176 scheduleUpdateDeviceDataChargerFull(); |
| 210 notifyChargeComplete = 0; | |
| 211 } | 177 } |
| 178 notifyChargeComplete = 0; | |
| 212 batteryChargerState = Charger_NotConnected; | 179 batteryChargerState = Charger_NotConnected; |
| 213 } | 180 } |
| 214 break; | 181 break; |
| 215 default: break; | 182 default: batteryChargerState = Charger_NotConnected; /* unexpected state => reinitialize state machine */ |
| 183 break; | |
| 216 } | 184 } |
| 217 } | 185 } |
| 218 else | 186 else |
| 219 { | 187 { |
| 220 /* connected */ | 188 /* connected */ |
| 221 /* wait for disconnection to write and reset */ | 189 /* wait for disconnection to write and reset */ |
| 222 switch(batteryChargerState) | 190 switch(batteryChargerState) |
| 223 { | 191 { |
| 224 case Charger_NotConnected: battery_i_charge_status = 1; | 192 case Charger_NotConnected: battery_charger_counter = 0; |
| 225 battery_charger_counter = 0; | |
| 226 batteryChargerState = Charger_WarmUp; | 193 batteryChargerState = Charger_WarmUp; |
| 227 break; | 194 break; |
| 228 case Charger_LostConnection: batteryChargerState = Charger_Active; | 195 case Charger_LostConnection: batteryChargerState = Charger_Active; |
| 229 break; | 196 break; |
| 230 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; | 197 case Charger_WarmUp: battery_charger_counter += cycleTimeBase; |
| 231 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) | 198 if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) |
| 232 { | 199 { |
| 233 battery_i_charge_status = 2; | |
| 234 scheduleUpdateDeviceDataChargerCharging(); | 200 scheduleUpdateDeviceDataChargerCharging(); |
| 235 batteryChargerState = Charger_Active; | 201 batteryChargerState = Charger_Active; |
| 236 } | 202 } |
| 237 /* no break */ | 203 /* no break */ |
| 238 case Charger_Finished: | 204 case Charger_Finished: |
| 249 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | 215 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); |
| 250 HAL_Delay(1); | 216 HAL_Delay(1); |
| 251 | 217 |
| 252 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ | 218 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ |
| 253 { | 219 { |
| 220 battery_charger_counter = 30; | |
| 254 batteryChargerState = Charger_Finished; | 221 batteryChargerState = Charger_Finished; |
| 255 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
| 256 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
| 257 battery_charger_counter = 30; | |
| 258 notifyChargeComplete = 1; | |
| 259 } | 222 } |
| 260 else | 223 else |
| 261 { | 224 { |
| 262 if(global.lifeData.battery_charge > 100.0) /* still charging but indicator is set to full => decrease to 99% to keep count increasing */ | 225 if(global.lifeData.battery_charge > 100.0) /* still charging but indicator is set to full => decrease to 99% to keep count increasing */ |
| 263 { | 226 { |
| 277 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | 240 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; |
| 278 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | 241 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); |
| 279 HAL_Delay(1); | 242 HAL_Delay(1); |
| 280 break; | 243 break; |
| 281 | 244 |
| 282 default: /* wait for disconnection */ | 245 default: batteryChargerState = Charger_NotConnected; /* unexpected state => reinitialize state machine */ |
| 283 break; | 246 break; |
| 284 } | 247 } |
| 285 } | 248 } |
| 286 } | 249 } |
| 287 #else | |
| 288 /* on disconnection or while disconnected */ | |
| 289 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) | |
| 290 { | |
| 291 if(battery_charger_counter) | |
| 292 { | |
| 293 battery_charger_counter--; | |
| 294 global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
| 295 global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; | |
| 296 } | |
| 297 /* max count down to 127+5 or 127+20 */ | |
| 298 if((battery_i_charge_status == 255) && battery_charger_counter < 127) | |
| 299 { | |
| 300 // battery_gas_gauge_set_charge_full(); | |
| 301 // scheduleUpdateDeviceDataChargerFull(); | |
| 302 battery_charger_counter = 0; | |
| 303 } | |
| 304 | |
| 305 if(battery_charger_counter == 0) | |
| 306 { | |
| 307 battery_i_charge_status = 0; | |
| 308 global.dataSendToMaster.chargeStatus = CHARGER_off; | |
| 309 global.deviceDataSendToMaster.chargeStatus = CHARGER_off; | |
| 310 | |
| 311 } | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 /* connected */ | |
| 316 | |
| 317 /* wait for disconnection to write and reset */ | |
| 318 if(battery_i_charge_status == 255) | |
| 319 { | |
| 320 global.dataSendToMaster.chargeStatus = CHARGER_complete; | |
| 321 global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; | |
| 322 | |
| 323 if(((cycleTimeBase > 1) && (battery_charger_counter < 127+5)) || (battery_charger_counter < 127+20)) | |
| 324 battery_charger_counter++; | |
| 325 return; | |
| 326 } | |
| 327 | |
| 328 if(battery_charger_counter == 0) | |
| 329 battery_i_charge_status = 1; | |
| 330 | |
| 331 /* charger is connected and didn't signal full yet */ | |
| 332 global.dataSendToMaster.chargeStatus = CHARGER_running; | |
| 333 global.deviceDataSendToMaster.chargeStatus = CHARGER_running; | |
| 334 | |
| 335 GPIO_InitTypeDef GPIO_InitStructure; | |
| 336 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
| 337 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; | |
| 338 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
| 339 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
| 340 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
| 341 HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); | |
| 342 HAL_Delay(1); | |
| 343 | |
| 344 | |
| 345 if(battery_charger_counter < 120) | |
| 346 { | |
| 347 if(cycleTimeBase == 1) | |
| 348 battery_charger_counter++; | |
| 349 else | |
| 350 { | |
| 351 battery_charger_counter += 30; | |
| 352 if(battery_charger_counter >= 127) | |
| 353 battery_charger_counter = 126; | |
| 354 } | |
| 355 } | |
| 356 else | |
| 357 if(battery_charger_counter < 127) | |
| 358 { | |
| 359 battery_charger_counter = 127; | |
| 360 if(battery_i_charge_status < 2) | |
| 361 { | |
| 362 battery_i_charge_status = 2; | |
| 363 scheduleUpdateDeviceDataChargerCharging(); | |
| 364 } | |
| 365 } | |
| 366 | |
| 367 if(battery_charger_counter >= 127) | |
| 368 { | |
| 369 if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN) || (get_voltage() >= 4.1f)) | |
| 370 { | |
| 371 battery_charger_counter++; | |
| 372 if(((cycleTimeBase > 1) && (battery_charger_counter > 127+5)) || (battery_charger_counter > 127+20)) | |
| 373 { | |
| 374 battery_charger_counter = 127; | |
| 375 if(get_voltage() >= 4.1f) | |
| 376 { | |
| 377 battery_i_charge_status = 255; | |
| 378 battery_gas_gauge_set_charge_full(); | |
| 379 scheduleUpdateDeviceDataChargerFull(); | |
| 380 } | |
| 381 } | |
| 382 } | |
| 383 else | |
| 384 battery_charger_counter = 127; | |
| 385 } | |
| 386 | |
| 387 GPIO_InitStructure.Pin = CHARGE_OUT_PIN; | |
| 388 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; | |
| 389 GPIO_InitStructure.Pull = GPIO_NOPULL; | |
| 390 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; | |
| 391 HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); | |
| 392 #endif | |
| 393 } | 250 } |
| 394 | 251 |
| 395 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ | 252 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ |
