diff --git a/Core/Inc/state_machine.h b/Core/Inc/state_machine.h new file mode 100644 index 0000000..478c6a6 --- /dev/null +++ b/Core/Inc/state_machine.h @@ -0,0 +1,71 @@ +//int errorcode[2] = {0,0}; 1 Bit per error +#include +#include + +// Minimum vehicle side voltage to exit precharge +#define MIN_VEHICLE_SIDE_VOLTAGE 150000 // mV +// Time to wait after reaching 95% of battery voltage before exiting precharge +// Set this to 1000 in scruti to demonstrate the voltage on the multimeter +#define PRECHARGE_95_DURATION 0 // ms +// Time to wait for discharge +#define DISCHARGE_DURATION 5000 // ms +// Time to wait after there is no more error condition before exiting TS_ERROR +#define NO_ERROR_TIME 1000 // ms +// Time to wait for charger voltage before going to TS_ERROR +#define MAX_CHARGING_CHECK_DURATION 2000 // ms +// Time to wait between closing relays +#define RELAY_CLOSE_WAIT 10 // ms + +typedef enum { // valid transitions: (all could transition to error) + INACTIVE, // INACTIVE -> PRECHARGE, CHARGING, ERROR + PRECHARGE, // PRECHARGE -> INACTIVE, READY, DISCHARGE, ERROR + READY, // READY -> ACTIVE, DISCHARGE, ERROR + ACTIVE, // ACTIVE -> READY, DISCHARGE, ERROR + DISCHARGE, // DISCHARGE -> INACTIVE, PRECHARGE, ERROR + CHARGING, // CHARGING -> INACTIVE, DISCHARGE, ERROR + ERROR, // ERROR -> INACTIVE, DISCHARGE, ERROR +} State; + +typedef enum { + ERRORKIND_NONE = 0x0, + ERRORKIND_BMS_TIMEOUT = 0x1, + ERRORKIND_OVERTEMPTURE = 0x2, + ERRORKIND_OVERCURRENT = 0x3, + ERRORKIND_OVERVOLTAGE = 0x4, + ERRORKIND_MISSING_CURRENT_READING = 0x5, + ERRORKIND_MISSING_VOLTAGE_READING = 0x6, + ERRORKIND_MISSING_TEMP_READING = 0x7, + ERRORKIND_PRECHARGE_FAIL = 0x8, + ERRORKIND_POWERGROUND_FAIL = 0x9 +} ErrorKind; + +//typedef enum {} WarningKind; + +typedef struct { + State current_state; + State target_state; + uint16_t error_source; // TSErrorSource (bitmask) + uint16_t error_type; // TSErrorKind +} StateHandle; + +extern StateHandle state; + +void sm_init(); +void sm_update(); + +State sm_update_inactive(); +State sm_update_active(); +State sm_update_precharge(); +State sm_update_discharge(); +State sm_update_error(); +State sm_update_charging_check(); +State sm_update_charging(); + +typedef enum { RELAY_POS, RELAY_PRECHARGE } Relay; +void sm_set_relay_positions(State state); +void sm_set_relay_position(Relay relay, int closed); +void sm_check_close_wait(int *is_closed, int should_close); + +void sm_handle_ams_in(const uint8_t *data); + +void sm_set_error(ErrorKind error_kind, bool is_errored); \ No newline at end of file diff --git a/Core/Src/main.c b/Core/Src/main.c index 4cd65ab..523bd73 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -121,9 +121,6 @@ int main(void) AMS_Init(&hspi1); ams_can_init(&hcan); - bool relay_actual = false; - bool relay_target = true; - uint32_t target_time = HAL_GetTick() + 10000; /* USER CODE END 2 */ @@ -142,13 +139,6 @@ int main(void) ams_can_send_error(); } ams_can_send_log(); - - if (HAL_GetTick() >= target_time) { - HAL_GPIO_WritePin(RELAY_EN_GPIO_Port, RELAY_EN_Pin, relay_target ? GPIO_PIN_SET : GPIO_PIN_RESET); - HAL_GPIO_WritePin(STATUS_LED_R_GPIO_Port, STATUS_LED_R_Pin, relay_target ? GPIO_PIN_RESET : GPIO_PIN_SET); - target_time = HAL_GetTick() + 10000; - relay_target = !relay_target; - } } /* USER CODE END 3 */ } diff --git a/Core/Src/state_machine.c b/Core/Src/state_machine.c new file mode 100644 index 0000000..3aa8808 --- /dev/null +++ b/Core/Src/state_machine.c @@ -0,0 +1,146 @@ +#include "state_machine.h" + +StateHandle state; + +void sm_init(){ + state.current_state = INACTIVE; + state.target_state = INACTIVE; + state.error_source = 0; +} + +void sm_update(){ + + if (state.error_source) { + state.current_state = ERROR; + } + + switch (state.current_state) { + case INACTIVE: + //state.current_state = sm_update_inactive(); moniter only + break; + case PRECHARGE: + //state.current_state = sm_update_precharge(); set PRECHARGE and turn on cooling at 50% or such + break; + case READY: + //state.current_state = ; keep cooling at 50%, get ready to turn on powerground + break; + case ACTIVE: + //state.current_state = sm_update_precharge(); set PRECHARGE and turn on cooling at 50% or such + break; + case DISCHARGE: + //state.current_state = sm_update_discharge(); // open the main relay, keep PRECHARGE closed + break; + case CHARGING: + //state.current_state = sm_update_charging(); // turn on cooling if needed, + break; + case ERROR: + //state.current_state = sm_update_error(); // enter the correct ERROR state + break; + case WARNING: + //state.current_state = sm_update_error(); // send warnings through CAN + break; + } + + sm_set_relay_positions(state.current_state); + status_led_state(state.current_state, (ErrorKind) state.error_type); +} + +State sm_update_inactive(){ + switch (state.target_state) { + case PRECHARGE: + if () + break; + case CHARGING: + break; + } + return INACTIVE; +} + +State sm_update_precharge(){ + switch (state.target_state) { + case INACTIVE: + break; + case READY: + break; + case DISCHARGE: + break; + } + return PRECHARGE; +} + +State sm_update_ready(){ + switch (state.target_state) { + case ACTIVE: + break; + case DISCHARGE: + break; + } + return READY; +} + +State sm_update_active(){ + switch (state.target_state) { + case READY: + break; + case DISCHARGE: + break; + } + return ACTIVE; +} + +State sm_update_discharge(){ + switch (state.target_state) { + case INACTIVE: + break; + case PRECHARGE: + break; + } + return DISCHARGE; +} + +State sm_update_charging(){ + switch (state.target_state) { + case INACTIVE: + break; + case DISCHARGE: + break; + } + return CHARGING; +} + +State sm_update_error(){ + switch (state.target_state) { + case INACTIVE: + break; + case DISCHARGE: + break; + } + return ERROR; +} + +void sm_set_relay_positions(State state){ + return; +} + +void sm_set_relay(Relay relay, int closed){ + static int closed = 0; + static int precharge_closed = 0; + + GPIO_PinState state = closed ? GPIO_PIN_SET : GPIO_PIN_RESET; + switch (relay) { + case RELAY_POS: + ts_sm_check_close_wait(&closed, closed); + HAL_GPIO_WritePin(RELAY_EN_GPIO_Port, RELAY_EN_Pin, state); + break; + case RELAY_PRECHARGE: + ts_sm_check_close_wait(&precharge_closed, closed); + HAL_GPIO_WritePin(PRECHARGE_EN_GPIO_Port, PRECHARGE_EN_Pin, state); + break; + } +} + +//void sm_check_close_wait(int *is_closed, int should_close); + +//void sm_handle_ams_in(const uint8_t *data); + +//void sm_set_error(ErrorKind error_kind, bool is_errored); \ No newline at end of file