FreeCalypso > hg > ffs-editor
comparison src/cs/drivers/drv_app/fchg/fchg_process.c @ 0:92470e5d0b9e
src: partial import from FC Selenite
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 15 May 2020 01:28:16 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:92470e5d0b9e |
|---|---|
| 1 /* | |
| 2 * In this module we are going to implement the main process functions | |
| 3 * for FCHG. | |
| 4 */ | |
| 5 | |
| 6 #include "fchg/fchg_env.h" | |
| 7 #include "fchg/fchg_func_i.h" | |
| 8 #include "rv/rv_general.h" | |
| 9 #include "rvf/rvf_api.h" | |
| 10 #include "rvm/rvm_use_id_list.h" | |
| 11 #include "abb/abb.h" | |
| 12 #include "fc-target.h" | |
| 13 #include <string.h> | |
| 14 #include <stdio.h> | |
| 15 | |
| 16 extern UINT16 madc_vbat_2_physical(UINT16 adc_val); | |
| 17 extern UINT16 madc_vbat_inverse(UINT16 mv); | |
| 18 | |
| 19 #if defined(CONFIG_TARGET_C155) || defined(CONFIG_TARGET_J100) | |
| 20 #define LEDC 0x20 | |
| 21 #else | |
| 22 #define LEDC 0 | |
| 23 #endif | |
| 24 | |
| 25 void pwr_init_discharge(void) | |
| 26 { | |
| 27 pwr_ctrl->curr_disch_thresh = 0; | |
| 28 } | |
| 29 | |
| 30 static void handle_discharge(void) | |
| 31 { | |
| 32 UINT16 i; | |
| 33 char trace[64]; | |
| 34 | |
| 35 /* first we need to find the current threshold we are at */ | |
| 36 i = pwr_ctrl->curr_disch_thresh; | |
| 37 /* is there one below? */ | |
| 38 if (++i == pwr_ctrl->nb_thresholds) | |
| 39 return; | |
| 40 /* are we crossing it? */ | |
| 41 if (pwr_ctrl->batt_mv >= pwr_ctrl->batt_thresholds[i].bat_voltage) | |
| 42 return; | |
| 43 /* yes, we crossed it - see if we fell even further down */ | |
| 44 while (i < pwr_ctrl->nb_thresholds && | |
| 45 pwr_ctrl->batt_mv < pwr_ctrl->batt_thresholds[i].bat_voltage) | |
| 46 i++; | |
| 47 /* the last one was it */ | |
| 48 i--; | |
| 49 pwr_ctrl->curr_disch_thresh = i; | |
| 50 sprintf(trace, "Battery fell through %u%% mark", | |
| 51 pwr_ctrl->batt_thresholds[i].remain_capa); | |
| 52 rvf_send_trace(trace, strlen(trace), NULL_PARAM, | |
| 53 RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); | |
| 54 } | |
| 55 | |
| 56 static void start_i2v_cal(void) | |
| 57 { | |
| 58 UINT16 bciconf; | |
| 59 | |
| 60 rvf_send_trace("Calibrating i2v offset", 22, NULL_PARAM, | |
| 61 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 62 pwr_ctrl->state = FCHG_STATE_I2V_CAL_2; | |
| 63 bciconf = ABB_Read_Register_on_page(PAGE1, BCICONF); | |
| 64 bciconf &= 0x3E0; | |
| 65 bciconf |= pwr_ctrl->config.bciconf; | |
| 66 ABB_Write_Register_on_page(PAGE1, BCICONF, bciconf); | |
| 67 /* | |
| 68 * Set the CHDISPA bit and start the zero calibration routine | |
| 69 * of the I to V converter | |
| 70 */ | |
| 71 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0010); | |
| 72 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0019 | LEDC); | |
| 73 } | |
| 74 | |
| 75 static void start_ci_charging(void) | |
| 76 { | |
| 77 rvf_send_trace("Start CI charging", 17, NULL_PARAM, | |
| 78 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 79 pwr_ctrl->state = FCHG_STATE_CI_CHARGING; | |
| 80 /* Select constant current charging. The charger is disabled */ | |
| 81 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0002); | |
| 82 /* Program the DAC with the constant current value */ | |
| 83 ABB_Write_Register_on_page(PAGE0, CHGREG, | |
| 84 pwr_ctrl->config.ci_current + pwr_ctrl->i2v_offset); | |
| 85 /* Enable the charger */ | |
| 86 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0003 | LEDC); | |
| 87 /* The total charging time starts now */ | |
| 88 pwr_ctrl->start_time = rvf_get_tick_count(); | |
| 89 } | |
| 90 | |
| 91 static void start_cv_charging(void) | |
| 92 { | |
| 93 UINT16 code; | |
| 94 | |
| 95 rvf_send_trace("Start CV charging", 17, NULL_PARAM, | |
| 96 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 97 pwr_ctrl->state = FCHG_STATE_CV_CHARGING; | |
| 98 /* Select constant voltage charging. The charger is disabled */ | |
| 99 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 100 /* figure out the DAC code */ | |
| 101 code = madc_vbat_inverse(pwr_ctrl->config.cv_init_set); | |
| 102 rvf_send_trace("Voltage (DAC code) ", 19, code, | |
| 103 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
| 104 /* Program the DAC with the constant voltage value */ | |
| 105 ABB_Write_Register_on_page(PAGE0, CHGREG, code); | |
| 106 /* Enable the charger */ | |
| 107 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0001 | LEDC); | |
| 108 /* CV control loop state init */ | |
| 109 pwr_ctrl->cv_dac_init = code; | |
| 110 pwr_ctrl->cv_dac_curr = code; | |
| 111 pwr_ctrl->cv_high_vbat_count = 0; | |
| 112 pwr_ctrl->cv_low_vbat_count = 0; | |
| 113 /* Ichg averaging state init */ | |
| 114 pwr_ctrl->ichg_fill_level = 0; | |
| 115 pwr_ctrl->ichg_ring_ptr = 0; | |
| 116 pwr_ctrl->ichg_low_count = 0; | |
| 117 } | |
| 118 | |
| 119 static void start_charge_condition_met(void) | |
| 120 { | |
| 121 rvf_send_trace("Charge start condition met", 26, NULL_PARAM, | |
| 122 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 123 if (pwr_ctrl->config.bciconf) | |
| 124 start_i2v_cal(); | |
| 125 else { | |
| 126 pwr_ctrl->i2v_offset = 0; | |
| 127 start_ci_charging(); | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 static void ci_progress_trace(UINT16 ichg) | |
| 132 { | |
| 133 char trace[64]; | |
| 134 | |
| 135 sprintf(trace, "CI charging: Vbat=%u Ichg=%u i2v=%u", | |
| 136 pwr_ctrl->batt_mv, ichg, pwr_ctrl->i2v_offset); | |
| 137 rvf_send_trace(trace, strlen(trace), NULL_PARAM, | |
| 138 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
| 139 } | |
| 140 | |
| 141 static int cv_ichg_process(UINT16 ichg_new) | |
| 142 { | |
| 143 UINT16 ichg_clip, ichg_entry; | |
| 144 UINT32 ichg_accum; | |
| 145 UINT16 i; | |
| 146 char trace[64]; | |
| 147 | |
| 148 if (pwr_ctrl->ichg_fill_level < ICHG_AVG_WINDOW) | |
| 149 pwr_ctrl->ichg_avg_buf[pwr_ctrl->ichg_fill_level++] = ichg_new; | |
| 150 else { | |
| 151 ichg_clip = pwr_ctrl->ichg_average + | |
| 152 pwr_ctrl->config.ichg_max_spike; | |
| 153 if (ichg_new > ichg_clip) | |
| 154 ichg_entry = ichg_clip; | |
| 155 else | |
| 156 ichg_entry = ichg_new; | |
| 157 pwr_ctrl->ichg_avg_buf[pwr_ctrl->ichg_ring_ptr++] = ichg_entry; | |
| 158 if (pwr_ctrl->ichg_ring_ptr >= ICHG_AVG_WINDOW) | |
| 159 pwr_ctrl->ichg_ring_ptr = 0; | |
| 160 } | |
| 161 ichg_accum = 0; | |
| 162 for (i = 0; i < pwr_ctrl->ichg_fill_level; i++) | |
| 163 ichg_accum += pwr_ctrl->ichg_avg_buf[i]; | |
| 164 pwr_ctrl->ichg_average = ichg_accum / pwr_ctrl->ichg_fill_level; | |
| 165 sprintf(trace, "CV charging: Vbat=%u Ichg=%u Ichg_avg=%u i2v=%u", | |
| 166 pwr_ctrl->batt_mv, ichg_new, pwr_ctrl->ichg_average, | |
| 167 pwr_ctrl->i2v_offset); | |
| 168 rvf_send_trace(trace, strlen(trace), NULL_PARAM, | |
| 169 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
| 170 if (pwr_ctrl->ichg_average > | |
| 171 (pwr_ctrl->config.end_current + pwr_ctrl->i2v_offset)) { | |
| 172 pwr_ctrl->ichg_low_count = 0; | |
| 173 return 0; | |
| 174 } | |
| 175 pwr_ctrl->ichg_low_count++; | |
| 176 if (pwr_ctrl->ichg_low_count < pwr_ctrl->config.ichg_samples_needed) | |
| 177 return 0; | |
| 178 rvf_send_trace("Stopping charge by low current condition", 40, | |
| 179 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 180 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 181 pwr_init_discharge(); | |
| 182 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; | |
| 183 return 1; | |
| 184 } | |
| 185 | |
| 186 static int overvoltage_end_charge_check(void) | |
| 187 { | |
| 188 if (pwr_ctrl->batt_mv < pwr_ctrl->config.overvoltage) | |
| 189 return 0; | |
| 190 if (pwr_ctrl->cv_dac_curr != | |
| 191 (pwr_ctrl->cv_dac_init - pwr_ctrl->config.cv_dac_max_decr)) | |
| 192 return 0; | |
| 193 rvf_send_trace("Stopping charge by overvoltage condition", 40, | |
| 194 NULL_PARAM, RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); | |
| 195 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 196 pwr_init_discharge(); | |
| 197 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; | |
| 198 return 1; | |
| 199 } | |
| 200 | |
| 201 static void cv_ctrl_loop_high_check(void) | |
| 202 { | |
| 203 if (pwr_ctrl->batt_mv < pwr_ctrl->config.cv_ctrl_loop_high) { | |
| 204 pwr_ctrl->cv_high_vbat_count = 0; | |
| 205 return; | |
| 206 } | |
| 207 pwr_ctrl->cv_high_vbat_count++; | |
| 208 if (pwr_ctrl->cv_high_vbat_count < pwr_ctrl->config.cv_samples_needed) | |
| 209 return; | |
| 210 if (pwr_ctrl->cv_dac_curr == | |
| 211 (pwr_ctrl->cv_dac_init - pwr_ctrl->config.cv_dac_max_decr)) | |
| 212 return; | |
| 213 pwr_ctrl->cv_dac_curr--; | |
| 214 ABB_Write_Register_on_page(PAGE0, CHGREG, pwr_ctrl->cv_dac_curr); | |
| 215 rvf_send_trace("Sub CV DAC", 10, pwr_ctrl->cv_dac_curr, | |
| 216 RV_TRACE_LEVEL_DEBUG_MEDIUM, FCHG_USE_ID); | |
| 217 pwr_ctrl->cv_high_vbat_count = 0; | |
| 218 } | |
| 219 | |
| 220 static void cv_ctrl_loop_low_check(void) | |
| 221 { | |
| 222 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.cv_ctrl_loop_low) { | |
| 223 pwr_ctrl->cv_low_vbat_count = 0; | |
| 224 return; | |
| 225 } | |
| 226 pwr_ctrl->cv_low_vbat_count++; | |
| 227 if (pwr_ctrl->cv_low_vbat_count < pwr_ctrl->config.cv_samples_needed) | |
| 228 return; | |
| 229 if (pwr_ctrl->cv_dac_curr == | |
| 230 (pwr_ctrl->cv_dac_init + pwr_ctrl->config.cv_dac_max_incr)) | |
| 231 return; | |
| 232 pwr_ctrl->cv_dac_curr++; | |
| 233 ABB_Write_Register_on_page(PAGE0, CHGREG, pwr_ctrl->cv_dac_curr); | |
| 234 rvf_send_trace("Add CV DAC", 10, pwr_ctrl->cv_dac_curr, | |
| 235 RV_TRACE_LEVEL_DEBUG_MEDIUM, FCHG_USE_ID); | |
| 236 pwr_ctrl->cv_low_vbat_count = 0; | |
| 237 } | |
| 238 | |
| 239 static int charging_time_limit_check(void) | |
| 240 { | |
| 241 if ((rvf_get_tick_count() - pwr_ctrl->start_time) < | |
| 242 RVF_SECS_TO_TICKS(pwr_ctrl->config.charge_time_limit)) | |
| 243 return 0; | |
| 244 rvf_send_trace("Stopping charge by time exceeded condition", 42, | |
| 245 NULL_PARAM, RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); | |
| 246 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 247 pwr_init_discharge(); | |
| 248 pwr_ctrl->state = FCHG_STATE_RECHARGE_TIMER; | |
| 249 pwr_ctrl->start_time = rvf_get_tick_count(); | |
| 250 return 1; | |
| 251 } | |
| 252 | |
| 253 void pwr_process_adc(struct pwr_adc_ind_s *msg) | |
| 254 { | |
| 255 pwr_ctrl->batt_mv = madc_vbat_2_physical(msg->data[0]); | |
| 256 | |
| 257 switch (pwr_ctrl->state) { | |
| 258 case FCHG_STATE_NO_EXT_PWR: | |
| 259 case FCHG_STATE_PWR_PLUG_TIMER: | |
| 260 case FCHG_STATE_NO_CHARGING: | |
| 261 handle_discharge(); | |
| 262 return; | |
| 263 case FCHG_STATE_READY_TO_CHARGE: | |
| 264 handle_discharge(); | |
| 265 if (!(msg->data[9] & CHGPRES)) { | |
| 266 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 267 return; | |
| 268 } | |
| 269 if (pwr_ctrl->batt_mv < pwr_ctrl->config.start_thresh) | |
| 270 start_charge_condition_met(); | |
| 271 return; | |
| 272 case FCHG_STATE_READY_TO_RECHARGE: | |
| 273 handle_discharge(); | |
| 274 if (!(msg->data[9] & CHGPRES)) { | |
| 275 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 276 return; | |
| 277 } | |
| 278 if (pwr_ctrl->batt_mv < pwr_ctrl->config.restart_thresh) | |
| 279 start_charge_condition_met(); | |
| 280 return; | |
| 281 case FCHG_STATE_I2V_CAL_1: | |
| 282 if (!(msg->data[9] & CHGPRES)) { | |
| 283 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 284 return; | |
| 285 } | |
| 286 if (pwr_ctrl->config.bciconf) | |
| 287 start_i2v_cal(); | |
| 288 else { | |
| 289 pwr_ctrl->i2v_offset = 0; | |
| 290 start_ci_charging(); | |
| 291 } | |
| 292 return; | |
| 293 case FCHG_STATE_I2V_CAL_2: | |
| 294 pwr_ctrl->i2v_offset = msg->data[2]; | |
| 295 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 296 rvf_send_trace("i2v offset (MADC code) ", 23, | |
| 297 pwr_ctrl->i2v_offset, | |
| 298 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
| 299 if (!(msg->data[9] & CHGPRES)) { | |
| 300 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 301 pwr_init_discharge(); | |
| 302 return; | |
| 303 } | |
| 304 start_ci_charging(); | |
| 305 return; | |
| 306 case FCHG_STATE_CI_CHARGING: | |
| 307 ci_progress_trace(msg->data[2]); | |
| 308 if (!(msg->data[9] & CHGPRES)) { | |
| 309 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 310 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 311 pwr_init_discharge(); | |
| 312 return; | |
| 313 } | |
| 314 if (charging_time_limit_check()) | |
| 315 return; | |
| 316 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.ci2cv_thresh) | |
| 317 start_cv_charging(); | |
| 318 return; | |
| 319 case FCHG_STATE_CV_CHARGING: | |
| 320 if (!(msg->data[9] & CHGPRES)) { | |
| 321 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 322 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 323 pwr_init_discharge(); | |
| 324 return; | |
| 325 } | |
| 326 if (cv_ichg_process(msg->data[2])) | |
| 327 return; | |
| 328 if (overvoltage_end_charge_check()) | |
| 329 return; | |
| 330 if (charging_time_limit_check()) | |
| 331 return; | |
| 332 cv_ctrl_loop_high_check(); | |
| 333 cv_ctrl_loop_low_check(); | |
| 334 return; | |
| 335 case FCHG_STATE_RECHARGE_TIMER: | |
| 336 handle_discharge(); | |
| 337 if ((rvf_get_tick_count() - pwr_ctrl->start_time) < | |
| 338 RVF_SECS_TO_TICKS(pwr_ctrl->config.recharge_delay)) | |
| 339 return; | |
| 340 rvf_send_trace("Restart time met, allowing new charging", 39, | |
| 341 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, | |
| 342 FCHG_USE_ID); | |
| 343 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; | |
| 344 return; | |
| 345 default: | |
| 346 rvf_send_trace("Invalid state in pwr_process_adc()", 32, | |
| 347 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, | |
| 348 FCHG_USE_ID); | |
| 349 } | |
| 350 } | |
| 351 | |
| 352 void pwr_handle_timer(void) | |
| 353 { | |
| 354 if (pwr_ctrl->state != FCHG_STATE_PWR_PLUG_TIMER) | |
| 355 return; | |
| 356 rvf_send_trace("Timer expired, ready to charge", 30, NULL_PARAM, | |
| 357 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
| 358 pwr_ctrl->state = FCHG_STATE_READY_TO_CHARGE; | |
| 359 } | |
| 360 | |
| 361 void pwr_charger_plug(void) | |
| 362 { | |
| 363 if (pwr_ctrl->state != FCHG_STATE_NO_EXT_PWR) { | |
| 364 rvf_send_trace("Charger plug event in unexpected state", 38, | |
| 365 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, | |
| 366 FCHG_USE_ID); | |
| 367 return; | |
| 368 } | |
| 369 if (!pwr_ctrl->config_present) { | |
| 370 rvf_send_trace( | |
| 371 "Charger plugged in, but no config: won't charge", 47, | |
| 372 NULL_PARAM, RV_TRACE_LEVEL_ERROR, FCHG_USE_ID); | |
| 373 pwr_ctrl->state = FCHG_STATE_NO_CHARGING; | |
| 374 return; | |
| 375 } | |
| 376 if (pwr_ctrl->config.start_delay) { | |
| 377 rvf_send_trace("Charger plug, starting timer", 28, NULL_PARAM, | |
| 378 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 379 rvf_start_timer(FCHG_TIMER, | |
| 380 RVF_MS_TO_TICKS(pwr_ctrl->config.start_delay), | |
| 381 FALSE); | |
| 382 pwr_ctrl->state = FCHG_STATE_PWR_PLUG_TIMER; | |
| 383 } else { | |
| 384 rvf_send_trace("Charger plug, ready to charge", 29, NULL_PARAM, | |
| 385 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
| 386 pwr_ctrl->state = FCHG_STATE_READY_TO_CHARGE; | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 void pwr_charger_unplug(void) | |
| 391 { | |
| 392 switch (pwr_ctrl->state) { | |
| 393 case FCHG_STATE_NO_EXT_PWR: | |
| 394 rvf_send_trace("Charger unplug, already handled", 31, | |
| 395 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, | |
| 396 FCHG_USE_ID); | |
| 397 /* nothing to do */ | |
| 398 return; | |
| 399 case FCHG_STATE_PWR_PLUG_TIMER: | |
| 400 case FCHG_STATE_READY_TO_CHARGE: | |
| 401 case FCHG_STATE_READY_TO_RECHARGE: | |
| 402 case FCHG_STATE_I2V_CAL_1: | |
| 403 case FCHG_STATE_RECHARGE_TIMER: | |
| 404 case FCHG_STATE_NO_CHARGING: | |
| 405 rvf_send_trace("Charger unplug", 14, NULL_PARAM, | |
| 406 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
| 407 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 408 return; | |
| 409 case FCHG_STATE_I2V_CAL_2: | |
| 410 case FCHG_STATE_CI_CHARGING: | |
| 411 case FCHG_STATE_CV_CHARGING: | |
| 412 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 413 rvf_send_trace("Charger unplug, charging stopped", 32, | |
| 414 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, | |
| 415 FCHG_USE_ID); | |
| 416 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
| 417 pwr_init_discharge(); | |
| 418 return; | |
| 419 default: | |
| 420 rvf_send_trace("Invalid state in pwr_charger_unplug()", 35, | |
| 421 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, | |
| 422 FCHG_USE_ID); | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 void pwr_charge_start_req(void) | |
| 427 { | |
| 428 switch (pwr_ctrl->state) { | |
| 429 case FCHG_STATE_NO_EXT_PWR: | |
| 430 rvf_send_trace("Cannot charge without a power source", 36, | |
| 431 NULL_PARAM, RV_TRACE_LEVEL_ERROR, FCHG_USE_ID); | |
| 432 return; | |
| 433 case FCHG_STATE_NO_CHARGING: | |
| 434 if (!pwr_ctrl->config_present) { | |
| 435 rvf_send_trace("No config set, cannot charge", 28, | |
| 436 NULL_PARAM, RV_TRACE_LEVEL_ERROR, | |
| 437 FCHG_USE_ID); | |
| 438 return; | |
| 439 } | |
| 440 /* FALL THRU */ | |
| 441 case FCHG_STATE_PWR_PLUG_TIMER: | |
| 442 case FCHG_STATE_READY_TO_CHARGE: | |
| 443 case FCHG_STATE_READY_TO_RECHARGE: | |
| 444 case FCHG_STATE_RECHARGE_TIMER: | |
| 445 rvf_send_trace("Starting charge on user request", 31, | |
| 446 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, | |
| 447 FCHG_USE_ID); | |
| 448 pwr_ctrl->state = FCHG_STATE_I2V_CAL_1; | |
| 449 return; | |
| 450 case FCHG_STATE_I2V_CAL_1: | |
| 451 case FCHG_STATE_I2V_CAL_2: | |
| 452 case FCHG_STATE_CI_CHARGING: | |
| 453 case FCHG_STATE_CV_CHARGING: | |
| 454 rvf_send_trace( | |
| 455 "Charging already in progress, start request ignored", | |
| 456 51, NULL_PARAM, RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); | |
| 457 return; | |
| 458 default: | |
| 459 rvf_send_trace("Invalid state in pwr_charge_start_req()", 37, | |
| 460 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, | |
| 461 FCHG_USE_ID); | |
| 462 } | |
| 463 } | |
| 464 | |
| 465 void pwr_charge_stop_req(void) | |
| 466 { | |
| 467 switch (pwr_ctrl->state) { | |
| 468 case FCHG_STATE_NO_EXT_PWR: | |
| 469 case FCHG_STATE_NO_CHARGING: | |
| 470 /* nothing to do */ | |
| 471 return; | |
| 472 case FCHG_STATE_PWR_PLUG_TIMER: | |
| 473 case FCHG_STATE_READY_TO_CHARGE: | |
| 474 case FCHG_STATE_READY_TO_RECHARGE: | |
| 475 case FCHG_STATE_I2V_CAL_1: | |
| 476 case FCHG_STATE_RECHARGE_TIMER: | |
| 477 rvf_send_trace("Charging disabled by user request", 33, | |
| 478 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, | |
| 479 FCHG_USE_ID); | |
| 480 pwr_ctrl->state = FCHG_STATE_NO_CHARGING; | |
| 481 return; | |
| 482 case FCHG_STATE_I2V_CAL_2: | |
| 483 case FCHG_STATE_CI_CHARGING: | |
| 484 case FCHG_STATE_CV_CHARGING: | |
| 485 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
| 486 rvf_send_trace("Charging stopped by user request", 32, | |
| 487 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, | |
| 488 FCHG_USE_ID); | |
| 489 pwr_ctrl->state = FCHG_STATE_NO_CHARGING; | |
| 490 pwr_init_discharge(); | |
| 491 return; | |
| 492 default: | |
| 493 rvf_send_trace("Invalid state in pwr_charge_stop_req()", 36, | |
| 494 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, | |
| 495 FCHG_USE_ID); | |
| 496 } | |
| 497 } |
