.. _program_listing_file_mainboard_Src_bal_fsm.c: Program Listing for File bal_fsm.c ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``mainboard/Src/bal_fsm.c``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "bal_fsm.h" #include "cli_bms.h" #include "config.h" #include "fenice_config.h" #include "pack/pack.h" #include "spi.h" #define CONF_VER 0x01 #define CONF_ADDR 0x01 typedef struct { voltage_t threshold; } bal_params; bal_params bal_params_default = {BAL_MAX_VOLTAGE_THRESHOLD}; bal_fsm bal; config_t config; void off_entry(fsm FSM); void off_handler(fsm FSM, uint8_t event); void compute_entry(fsm FSM); void discharge_entry(fsm FSM); void discharge_handler(fsm FSM, uint8_t event); void cooldown_handler(fsm FSM, uint8_t event); voltage_t bal_get_threshold() { return ((bal_params *)config_get(config))->threshold; } void bal_set_threshold(uint16_t thresh) { bal_params params = *(bal_params *)config_get(config); params.threshold = thresh; config_set(config, ¶ms); config_write(config); } void bal_fsm_init() { bal.cycle_length = BAL_CYCLE_LENGTH; bal.fsm = fsm_init(BAL_NUM_STATES, BAL_EV_NUM, NULL, NULL); fsm_state state; state.run = NULL; state.handler = off_handler; state.entry = off_entry; state.exit = NULL; fsm_set_state(bal.fsm, BAL_OFF, &state); state.handler = NULL; state.entry = compute_entry; state.exit = NULL; fsm_set_state(bal.fsm, BAL_COMPUTE, &state); state.handler = discharge_handler; state.entry = discharge_entry; state.exit = NULL; fsm_set_state(bal.fsm, BAL_DISCHARGE, &state); state.handler = cooldown_handler; state.entry = NULL; state.exit = NULL; fsm_set_state(bal.fsm, BAL_COOLDOWN, &state); config_init(&config, CONF_ADDR, CONF_VER, &bal_params_default, sizeof(bal_params)); } void off_entry(fsm FSM) { } void off_handler(fsm FSM, uint8_t event) { switch (event) { case EV_BAL_START: fsm_transition(FSM, BAL_COMPUTE); break; } } void compute_entry(fsm FSM) { if (bal_get_cells_to_discharge(voltage_get_cells(), PACK_CELL_COUNT, bal_get_threshold(), bal.cells) != 0) { fsm_transition(FSM, BAL_DISCHARGE); return; } cli_bms_debug("Non si può fare meglio di così.", 34); fsm_transition(FSM, BAL_OFF); } void discharge_entry(fsm FSM) { bal.discharge_time = HAL_GetTick(); cli_bms_debug("Discharging cells", 18); } void discharge_handler(fsm FSM, uint8_t event) { switch (event) { case EV_BAL_STOP: fsm_transition(FSM, BAL_OFF); break; case EV_BAL_CHECK_TIMER: if (bal.discharge_time - HAL_GetTick() >= bal.cycle_length) { fsm_transition(FSM, BAL_COOLDOWN); } else { fsm_trigger_event(FSM, EV_BAL_CHECK_TIMER); } break; } } void cooldown_handler(fsm FSM, uint8_t event) { switch (event) { case EV_BAL_STOP: fsm_transition(FSM, BAL_OFF); case EV_BAL_CHECK_TIMER: if (bal.discharge_time - HAL_GetTick() >= bal.cycle_length + BAL_COOLDOWN_DELAY) { fsm_transition(FSM, BAL_COMPUTE); } else { fsm_trigger_event(FSM, EV_BAL_CHECK_TIMER); } break; } }