Refactoring: move FSMs to separate functions
This commit is contained in:
parent
c504fb944c
commit
ed6ac04686
|
@ -67,83 +67,9 @@ static void control_solar_switch(fxp_t u_bat, fxp_t corridor_high, fxp_t corrido
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charge_control_init(void)
|
static void solar_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
{
|
{
|
||||||
charge_state = CHARGE_WAIT_CHARGEPUMP;
|
|
||||||
discharge_state = DISCHARGE_WAIT_CHARGEPUMP;
|
|
||||||
|
|
||||||
charge_state_entered = true;
|
|
||||||
discharge_state_entered = true;
|
|
||||||
|
|
||||||
/* calculate thresholds */
|
|
||||||
u_bat_regulation_corridor = fxp_div(FXP_FROM_INT(U_BAT_REGULATION_CORRIDOR),
|
|
||||||
FXP_FROM_INT(1000));
|
|
||||||
|
|
||||||
u_bat_initial_full = fxp_div(FXP_FROM_INT(U_BAT_INITAL_FULL), FXP_FROM_INT(1000));
|
|
||||||
u_bat_initial_low = fxp_sub(u_bat_initial_full, u_bat_regulation_corridor);
|
|
||||||
|
|
||||||
u_bat_float_full = fxp_div(FXP_FROM_INT(U_BAT_FLOAT_FULL), FXP_FROM_INT(1000));
|
|
||||||
u_bat_float_low = fxp_sub(u_bat_float_full, u_bat_regulation_corridor);
|
|
||||||
|
|
||||||
min_charge_pump_excess_voltage = fxp_div(FXP_FROM_INT(MIN_CHARGE_PUMP_EXCESS_VOLTAGE),
|
|
||||||
FXP_FROM_INT(1000));
|
|
||||||
|
|
||||||
u_bat_load_on = fxp_div(FXP_FROM_INT(U_BAT_LOAD_ON), FXP_FROM_INT(1000));
|
|
||||||
u_bat_load_off = fxp_div(FXP_FROM_INT(U_BAT_LOAD_OFF), FXP_FROM_INT(1000));
|
|
||||||
|
|
||||||
load_current_limit = fxp_div(FXP_FROM_INT(LOAD_CURRENT_LIMIT_MA), FXP_FROM_INT(1000));
|
|
||||||
|
|
||||||
internal_temperature_limit = fxp_div(FXP_FROM_INT(INTERNAL_TEMPERATURE_LIMIT), FXP_FROM_INT(10));
|
|
||||||
internal_temperature_recovery = fxp_div(FXP_FROM_INT(INTERNAL_TEMPERATURE_RECOVERY), FXP_FROM_INT(10));
|
|
||||||
|
|
||||||
sleep_solar_current = fxp_div(FXP_FROM_INT(SLEEP_SOLAR_CURRENT), FXP_FROM_INT(1000));
|
|
||||||
sleep_solar_excess_voltage = fxp_div(FXP_FROM_INT(SLEEP_SOLAR_EXCESS_VOLTAGE), FXP_FROM_INT(1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void charge_control_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
|
||||||
{
|
|
||||||
/* state change tracking for efficient transistions. */
|
|
||||||
enum ChargeState last_charge_state = charge_state;
|
|
||||||
enum DischargeState last_discharge_state = discharge_state;
|
|
||||||
|
|
||||||
if(charge_state_entered) {
|
|
||||||
rs485_enqueue("STATE:CHARGE:");
|
|
||||||
rs485_enqueue(CHARGE_STATE_TEXT[charge_state]);
|
|
||||||
rs485_enqueue("\n");
|
|
||||||
charge_state_entered_timestamp = uptime_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(discharge_state_entered) {
|
|
||||||
rs485_enqueue("STATE:DISCHG:");
|
|
||||||
rs485_enqueue(DISCHARGE_STATE_TEXT[discharge_state]);
|
|
||||||
rs485_enqueue("\n");
|
|
||||||
discharge_state_entered_timestamp = uptime_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t charge_time_in_state = uptime_ms - charge_state_entered_timestamp;
|
uint64_t charge_time_in_state = uptime_ms - charge_state_entered_timestamp;
|
||||||
uint64_t discharge_time_in_state = uptime_ms - discharge_state_entered_timestamp;
|
|
||||||
|
|
||||||
/* calculate charge pump excess voltage above battery voltage. */
|
|
||||||
fxp_t charge_pump_voltage_delta = fxp_sub(meas->u_sw, meas->u_bat);
|
|
||||||
|
|
||||||
/* generalized charge pump control */
|
|
||||||
if(charge_state_entered || discharge_state_entered) {
|
|
||||||
if(charge_state == CHARGE_WAIT_CHARGEPUMP
|
|
||||||
|| discharge_state == DISCHARGE_WAIT_CHARGEPUMP) {
|
|
||||||
// either charge or discharge control is waiting for the charge
|
|
||||||
// pump, so power it up!
|
|
||||||
charge_pump_start();
|
|
||||||
} else if((charge_state == CHARGE_SLEEP)
|
|
||||||
&& (discharge_state == DISCHARGE_VOLTAGE_LOW)) {
|
|
||||||
// no power from the solar panel and the battery voltage is too
|
|
||||||
// low, so both switches are off and we can safely stop the charge
|
|
||||||
// pump
|
|
||||||
charge_pump_stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Charging FSM */
|
|
||||||
|
|
||||||
switch(charge_state) {
|
switch(charge_state) {
|
||||||
case CHARGE_WAIT_CHARGEPUMP:
|
case CHARGE_WAIT_CHARGEPUMP:
|
||||||
|
@ -152,7 +78,9 @@ void charge_control_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
power_switch_solar_off();
|
power_switch_solar_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(charge_pump_voltage_delta > min_charge_pump_excess_voltage) {
|
// calculate charge pump output excess voltage over battery voltage
|
||||||
|
// and compare to the threshold
|
||||||
|
if(fxp_sub(meas->u_sw, meas->u_bat) > min_charge_pump_excess_voltage) {
|
||||||
charge_state = CHARGE_INITIAL;
|
charge_state = CHARGE_INITIAL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -240,8 +168,12 @@ void charge_control_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
// unknown state
|
// unknown state
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Load control FSM */
|
|
||||||
|
static void load_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
|
{
|
||||||
|
uint64_t discharge_time_in_state = uptime_ms - discharge_state_entered_timestamp;
|
||||||
|
|
||||||
switch(discharge_state) {
|
switch(discharge_state) {
|
||||||
case DISCHARGE_WAIT_CHARGEPUMP:
|
case DISCHARGE_WAIT_CHARGEPUMP:
|
||||||
|
@ -250,7 +182,9 @@ void charge_control_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
power_switch_load_off();
|
power_switch_load_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(charge_pump_voltage_delta > min_charge_pump_excess_voltage) {
|
// calculate charge pump output excess voltage over battery voltage
|
||||||
|
// and compare to the threshold
|
||||||
|
if(fxp_sub(meas->u_sw, meas->u_bat) > min_charge_pump_excess_voltage) {
|
||||||
discharge_state = DISCHARGE_VOLTAGE_LOW;
|
discharge_state = DISCHARGE_VOLTAGE_LOW;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -298,6 +232,84 @@ void charge_control_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
// unknown state
|
// unknown state
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void charge_control_init(void)
|
||||||
|
{
|
||||||
|
charge_state = CHARGE_WAIT_CHARGEPUMP;
|
||||||
|
discharge_state = DISCHARGE_WAIT_CHARGEPUMP;
|
||||||
|
|
||||||
|
charge_state_entered = true;
|
||||||
|
discharge_state_entered = true;
|
||||||
|
|
||||||
|
/* calculate thresholds */
|
||||||
|
u_bat_regulation_corridor = fxp_div(FXP_FROM_INT(U_BAT_REGULATION_CORRIDOR),
|
||||||
|
FXP_FROM_INT(1000));
|
||||||
|
|
||||||
|
u_bat_initial_full = fxp_div(FXP_FROM_INT(U_BAT_INITAL_FULL), FXP_FROM_INT(1000));
|
||||||
|
u_bat_initial_low = fxp_sub(u_bat_initial_full, u_bat_regulation_corridor);
|
||||||
|
|
||||||
|
u_bat_float_full = fxp_div(FXP_FROM_INT(U_BAT_FLOAT_FULL), FXP_FROM_INT(1000));
|
||||||
|
u_bat_float_low = fxp_sub(u_bat_float_full, u_bat_regulation_corridor);
|
||||||
|
|
||||||
|
min_charge_pump_excess_voltage = fxp_div(FXP_FROM_INT(MIN_CHARGE_PUMP_EXCESS_VOLTAGE),
|
||||||
|
FXP_FROM_INT(1000));
|
||||||
|
|
||||||
|
u_bat_load_on = fxp_div(FXP_FROM_INT(U_BAT_LOAD_ON), FXP_FROM_INT(1000));
|
||||||
|
u_bat_load_off = fxp_div(FXP_FROM_INT(U_BAT_LOAD_OFF), FXP_FROM_INT(1000));
|
||||||
|
|
||||||
|
load_current_limit = fxp_div(FXP_FROM_INT(LOAD_CURRENT_LIMIT_MA), FXP_FROM_INT(1000));
|
||||||
|
|
||||||
|
internal_temperature_limit = fxp_div(FXP_FROM_INT(INTERNAL_TEMPERATURE_LIMIT), FXP_FROM_INT(10));
|
||||||
|
internal_temperature_recovery = fxp_div(FXP_FROM_INT(INTERNAL_TEMPERATURE_RECOVERY), FXP_FROM_INT(10));
|
||||||
|
|
||||||
|
sleep_solar_current = fxp_div(FXP_FROM_INT(SLEEP_SOLAR_CURRENT), FXP_FROM_INT(1000));
|
||||||
|
sleep_solar_excess_voltage = fxp_div(FXP_FROM_INT(SLEEP_SOLAR_EXCESS_VOLTAGE), FXP_FROM_INT(1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void charge_control_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
|
{
|
||||||
|
/* state change tracking for efficient transistions. */
|
||||||
|
enum ChargeState last_charge_state = charge_state;
|
||||||
|
enum DischargeState last_discharge_state = discharge_state;
|
||||||
|
|
||||||
|
if(charge_state_entered) {
|
||||||
|
rs485_enqueue("STATE:CHARGE:");
|
||||||
|
rs485_enqueue(CHARGE_STATE_TEXT[charge_state]);
|
||||||
|
rs485_enqueue("\n");
|
||||||
|
charge_state_entered_timestamp = uptime_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(discharge_state_entered) {
|
||||||
|
rs485_enqueue("STATE:DISCHG:");
|
||||||
|
rs485_enqueue(DISCHARGE_STATE_TEXT[discharge_state]);
|
||||||
|
rs485_enqueue("\n");
|
||||||
|
discharge_state_entered_timestamp = uptime_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate charge pump excess voltage above battery voltage. */
|
||||||
|
fxp_t charge_pump_voltage_delta = fxp_sub(meas->u_sw, meas->u_bat);
|
||||||
|
|
||||||
|
/* generalized charge pump control */
|
||||||
|
if(charge_state_entered || discharge_state_entered) {
|
||||||
|
if(charge_state == CHARGE_WAIT_CHARGEPUMP
|
||||||
|
|| discharge_state == DISCHARGE_WAIT_CHARGEPUMP) {
|
||||||
|
// either charge or discharge control is waiting for the charge
|
||||||
|
// pump, so power it up!
|
||||||
|
charge_pump_start();
|
||||||
|
} else if((charge_state == CHARGE_SLEEP)
|
||||||
|
&& (discharge_state == DISCHARGE_VOLTAGE_LOW)) {
|
||||||
|
// no power from the solar panel and the battery voltage is too
|
||||||
|
// low, so both switches are off and we can safely stop the charge
|
||||||
|
// pump
|
||||||
|
charge_pump_stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
solar_fsm_update(uptime_ms, meas);
|
||||||
|
load_fsm_update(uptime_ms, meas);
|
||||||
|
|
||||||
charge_state_entered = charge_state != last_charge_state;
|
charge_state_entered = charge_state != last_charge_state;
|
||||||
discharge_state_entered = discharge_state != last_discharge_state;
|
discharge_state_entered = discharge_state != last_discharge_state;
|
||||||
|
|
Loading…
Reference in a new issue