FreeCalypso > hg > fc-magnetite
diff src/cs/drivers/drv_app/fchg/fchg_process.c @ 362:4c3d05866531
FCHG: beginning of the new version
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 Dec 2017 07:06:06 +0000 |
parents | ce6d71349af0 |
children | cce24b9de6db |
line wrap: on
line diff
--- a/src/cs/drivers/drv_app/fchg/fchg_process.c Fri Dec 29 05:51:08 2017 +0000 +++ b/src/cs/drivers/drv_app/fchg/fchg_process.c Fri Dec 29 07:06:06 2017 +0000 @@ -13,6 +13,7 @@ #include <stdio.h> extern UINT16 madc_vbat_2_physical(UINT16 adc_val); +extern UINT16 madc_vbat_inverse(UINT16 mv); void pwr_init_discharge(void) { @@ -45,16 +46,6 @@ RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); } -static void charge_progress_trace(char *mode, UINT16 ichg) -{ - char trace[64]; - - sprintf(trace, "%s charging: Vbat=%u Ichg=%u i2v=%u", mode, - pwr_ctrl->batt_mv, ichg, pwr_ctrl->i2v_offset); - rvf_send_trace(trace, strlen(trace), NULL_PARAM, - RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); -} - static void start_i2v_cal(void) { UINT16 bciconf; @@ -88,24 +79,32 @@ ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0003); } -static void start_cv_charging(UINT16 code) +static void start_cv_charging(void) { + UINT16 code; + rvf_send_trace("Start CV charging", 17, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); pwr_ctrl->state = FCHG_STATE_CV_CHARGING; /* Select constant voltage charging. The charger is disabled */ ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); /* figure out the DAC code */ - while (code && - madc_vbat_2_physical(code) >= pwr_ctrl->config.cv_init_set) - code--; - code++; + code = madc_vbat_inverse(pwr_ctrl->config.cv_init_set); rvf_send_trace("Voltage (DAC code) ", 19, code, RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); /* Program the DAC with the constant voltage value */ ABB_Write_Register_on_page(PAGE0, CHGREG, code); /* Enable the charger */ ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0001); + /* CV control loop state init */ + pwr_ctrl->cv_dac_init = code; + pwr_ctrl->cv_dac_curr = code; + pwr_ctrl->cv_high_vbat_count = 0; + pwr_ctrl->cv_low_vbat_count = 0; + /* Ichg averaging state init */ + pwr_ctrl->ichg_fill_level = 0; + pwr_ctrl->ichg_ring_ptr = 0; + pwr_ctrl->ichg_low_count = 0; } static void start_charge_condition_met(void) @@ -120,10 +119,70 @@ } } +static void ci_progress_trace(UINT16 ichg) +{ + char trace[64]; + + sprintf(trace, "CI charging: Vbat=%u Ichg=%u i2v=%u", + pwr_ctrl->batt_mv, ichg, pwr_ctrl->i2v_offset); + rvf_send_trace(trace, strlen(trace), NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); +} + +static int cv_ichg_process(UINT16 ichg_new) +{ + UINT16 ichg_clip, ichg_entry; + UINT32 ichg_accum; + UINT16 i; + char trace[64]; + + if (pwr_ctrl->ichg_fill_level < ICHG_AVG_WINDOW) + pwr_ctrl->ichg_avg_buf[pwr_ctrl->ichg_fill_level++] = ichg_new; + else { + ichg_clip = pwr_ctrl->ichg_average + + pwr_ctrl->config.ichg_max_spike; + if (ichg_new > ichg_clip) + ichg_entry = ichg_clip; + else + ichg_entry = ichg_new; + pwr_ctrl->ichg_avg_buf[pwr_ctrl->ichg_ring_ptr++] = ichg_entry; + if (pwr_ctrl->ichg_ring_ptr >= ICHG_AVG_WINDOW) + pwr_ctrl->ichg_ring_ptr = 0; + } + ichg_accum = 0; + for (i = 0; i < pwr_ctrl->ichg_fill_level; i++) + ichg_accum += pwr_ctrl->ichg_avg_buf[i]; + pwr_ctrl->ichg_average = ichg_accum / pwr_ctrl->ichg_fill_level; + sprintf(trace, "CV charging: Vbat=%u Ichg=%u Ichg_avg=%u i2v=%u", + pwr_ctrl->batt_mv, ichg_new, pwr_ctrl->ichg_average, + pwr_ctrl->i2v_offset); + rvf_send_trace(trace, strlen(trace), NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); + if (pwr_ctrl->ichg_average > + (pwr_ctrl->config.end_current + pwr_ctrl->i2v_offset)) { + pwr_ctrl->ichg_low_count = 0; + return 0; + } + pwr_ctrl->ichg_low_count++; + if (pwr_ctrl->ichg_low_count < pwr_ctrl->config.ichg_samples_needed) + return 0; + rvf_send_trace("Stopping charge by low current condition", 40, + NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); + ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); + pwr_init_discharge(); + pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; + return 1; +} + static int overvoltage_end_charge_check(void) { if (pwr_ctrl->batt_mv < pwr_ctrl->config.overvoltage) return 0; + if (pwr_ctrl->cv_dac_curr >= pwr_ctrl->cv_dac_init) + return 0; + if ((pwr_ctrl->cv_dac_init - pwr_ctrl->cv_dac_curr) < + pwr_ctrl->config.cv_dac_max_decr) + return 0; rvf_send_trace("Stopping charge by overvoltage condition", 40, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); @@ -185,35 +244,26 @@ start_ci_charging(); return; case FCHG_STATE_CI_CHARGING: - charge_progress_trace("CI", msg->data[2]); + ci_progress_trace(msg->data[2]); if (!(msg->data[9] & CHGPRES)) { ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; return; } - if (overvoltage_end_charge_check()) - return; if (pwr_ctrl->batt_mv >= pwr_ctrl->config.ci2cv_thresh) - start_cv_charging(msg->data[0]); + start_cv_charging(); return; case FCHG_STATE_CV_CHARGING: - charge_progress_trace("CV", msg->data[2]); if (!(msg->data[9] & CHGPRES)) { ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; return; } + if (cv_ichg_process(msg->data[2])) + return; if (overvoltage_end_charge_check()) return; - if (msg->data[2] >= - pwr_ctrl->config.end_current + pwr_ctrl->i2v_offset) - return; - rvf_send_trace("Stopping charge by low current condition", 40, - NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, - FCHG_USE_ID); - ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); - pwr_init_discharge(); - pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; + /* DAC control loop will go here */ return; default: rvf_send_trace("Invalid state in pwr_process_adc()", 32,