diff --git a/Core/Inc/can.h b/Core/Inc/can.h index 7f6fcae..8b6651f 100644 --- a/Core/Inc/can.h +++ b/Core/Inc/can.h @@ -4,7 +4,6 @@ #include "stm32f3xx_hal.h" #include #include "main.h" -#include "AMS_HighLevel.h" #include "state_machine.h" #include "can-halal.h" @@ -17,4 +16,6 @@ void can_handle_send_status(); void can_handle_recieve_command(const uint8_t *data); +void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data); + #endif /* "INC_CAN_H" */ \ No newline at end of file diff --git a/Core/Inc/state_machine.h b/Core/Inc/state_machine.h index 64f657d..9442090 100644 --- a/Core/Inc/state_machine.h +++ b/Core/Inc/state_machine.h @@ -3,14 +3,8 @@ #include #include - #include "ADBMS_LL_Driver.h" #include "AMS_HighLevel.h" -#include "PWM_control.h" -#include "stm32f3xx_hal.h" -#include "ADBMS_Abstraction.h" -#include "main.h" -#include "can.h" // Minimum vehicle side voltage to exit precharge #define MIN_VEHICLE_SIDE_VOLTAGE 150000 // mV @@ -65,6 +59,11 @@ typedef struct { } StateHandle; extern StateHandle state; +static bool relay_closed = 0; +static bool precharge_closed = 0; +static int16_t RELAY_BAT_SIDE_VOLTAGE = 0; +static int16_t RELAY_ESC_SIDE_VOLTAGE = 0; +static int16_t CURRENT_MEASUREMENT = 0; void sm_init(); void sm_update(); @@ -81,9 +80,10 @@ State sm_update_error(); typedef enum { RELAY_MAIN, RELAY_PRECHARGE } Relay; void sm_set_relay_positions(State state); void sm_set_relay(Relay relay, bool closed); -void sm_charging_check(); +void sm_check_charging(); +void sm_check_cell_temps(int8_t* id, int16_t* temp); -void sm_handle_ams_in(); +void sm_handle_ams_in(const uint8 *data); void sm_check_errors(); void sm_set_error(ErrorKind error_kind, bool is_errored); diff --git a/Core/Src/can.c b/Core/Src/can.c index ab1eadb..9b71da5 100644 --- a/Core/Src/can.c +++ b/Core/Src/can.c @@ -5,6 +5,8 @@ */ #include "can.h" +#include "ADBMS_Abstraction.h" +#include "state_machine.h" //#define CAN_ID_IN 0x501 //#define CAN_ID_OUT 0x502 @@ -15,14 +17,54 @@ This function sends the status of the mvbms, the battery and of powerground. once every 1s in states: INACTIVE, PRECHARGE, DISCHARGE, CHARGING, ERROR. once every 0.5s in states: READY, ACTIVE. with format of: +CAN Messages: +- MVBMS Status (1B), Powerground Status 0-100% (1 bit) +- Battery: SoC (1B), Pack Voltage (2B), Current (1B), + Min/Max. Cell Temp (ID, Min Temp, ID, Max Temp)(4B), + Min/Max Cell Voltage (ID, Min Voltage, ID, Max Voltage)(4B) +bit 0-2: status +bit 0-7: +bit 8-15: State of Charge from 0-100% +bit 16-31: Battery voltage +bit 32-47: Current measurement +bit 48-50: id of cell with highest temperature +bit 51-62: temperature of the cell with highest temperature (12 bits moved 4 bit to the left) */ + void can_handle_send_status() { - static uint8_t data[8] = {}; - data[0] = (state.current_state << 5); //save 5 bit since codes are from 0-6 + uint8_t data[8] = {}; + data[0] = (state.current_state << 5); // save 5 bit since codes are from 0-7 61 bits left + //data[1] = // in 8 bits from 0-100% + data[2] = mV_from_ADBMS6830(RELAY_BAT_SIDE_VOLTAGE); // Battery voltage 16 bit 45 bit + data[4] = CURRENT_MEASUREMENT; // 16 bit measurement + + int8_t id = -1; + int16_t temp = INT16_MIN; + sm_check_cell_temps(&id, &temp); + data[6] = (id << 5) | (temp >> 4); // there are only 7 TMP1075 ftcan_transmit(CAN_ID_OUT, data, sizeof(data)); } +/* +can_handle_recieve_command() should only check if the message is valid and then hand it +to the sm_handle_ams_in() which handles the state machine transition. +*/ void can_handle_recieve_command(const uint8_t *data){ - ftcan_msg_received_cb(0x501, 16, data); + if (data[0] == 0x00 && data[1] == 0x00){ + sm_handle_ams_in(data); + } else if (data[0] == 0b1000000 && data[1] == 0x00){ + sm_handle_ams_in(data); + } else if (data[0] == 0b1100000 && data[1] <= 100) { + sm_handle_ams_in(data); + } +} +/* +implements the _weak method ftcan_msg_recieved_cb() which throws an interrupt when a CAN message is recieved. +it only checks if the id is and datalen is correct thans hands data over to can_handle_recieve_command(). +*/ +void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data){ + if (id == 0x501 && datalen == 16){ + can_handle_recieve_command(data); + } } diff --git a/Core/Src/state_machine.c b/Core/Src/state_machine.c index 2a2322a..8f232df 100644 --- a/Core/Src/state_machine.c +++ b/Core/Src/state_machine.c @@ -1,24 +1,23 @@ #include "state_machine.h" +#include "ADBMS_LL_Driver.h" +#include "TMP1075.h" +#include "common_defs.h" +#include StateHandle state; -static bool relay_closed = 0; -static bool precharge_closed = 0; -static int16_t RELAY_BAT_SIDE_VOLTAGE = 0; -static int16_t RELAY_ESC_SIDE_VOLTAGE = 0; -static int16_t CURRENT_MEASUREMENT_VOLTAGE = 0; static int16_t timestamp; void sm_init(){ state.current_state = STATE_INACTIVE; state.target_state = STATE_INACTIVE; state.error_source = 0; - RELAY_BAT_SIDE_VOLTAGE = module.auxVoltages[0]; - RELAY_ESC_SIDE_VOLTAGE = module.auxVoltages[1]; - CURRENT_MEASUREMENT_VOLTAGE = module.auxVoltages[2]; } void sm_update(){ - sm_handle_ams_in(); + RELAY_BAT_SIDE_VOLTAGE = module.auxVoltages[0]; + RELAY_ESC_SIDE_VOLTAGE = module.auxVoltages[1]; + CURRENT_MEASUREMENT_VOLTAGE = module.auxVoltages[2]; + switch (state.current_state) { case STATE_INACTIVE: state.current_state = sm_update_inactive(); // monitor only @@ -65,7 +64,7 @@ State sm_update_precharge(){ case STATE_INACTIVE: // if CAN Signal 0000 0000 then immidiete shutdown return STATE_DISCHARGE; case STATE_READY: - if (RELAY_BAT_SIDE_VOLTAGE == RELAY_ESC_SIDE_VOLTAGE) + if (roundf(RELAY_BAT_SIDE_VOLTAGE) == roundf(RELAY_ESC_SIDE_VOLTAGE)) return STATE_READY; default: return STATE_PRECHARGE; @@ -97,7 +96,7 @@ State sm_update_active(){ State sm_update_discharge(){ switch (state.target_state) { case STATE_INACTIVE: - if (RELAY_ESC_SIDE_VOLTAGE == 0) + if (RELAY_ESC_SIDE_VOLTAGE < 12) return STATE_INACTIVE; case STATE_PRECHARGE: // if CAN Signal 1000 0000 then get ready return STATE_PRECHARGE; @@ -182,9 +181,23 @@ void sm_set_relay(Relay relay, bool closed){ } } -void sm_handle_ams_in(){ - uint8_t data[2] = {}; - can_handle_recieve_command(&data); + +void sm_check_charging(){ + if (RELAY_BAT_SIDE_VOLTAGE < RELAY_ESC_SIDE_VOLTAGE && timestamp == 0) + timestamp = HAL_GetTick() + 5000; + if (timestamp < HAL_GetTick()) + state.target_state = STATE_CHARGING_PRECHARGE; +} + +void sm_check_cell_temps(int8_t *id, int16_t *temp){ + for (int i = 0; i < N_TEMP_SENSORS; i++) { + if (tmp1075_temps[i] > *temp){ + *id = i; + } + } +} + +void sm_handle_ams_in(const uint8_t *data){ switch (data[0]) { case 0b00000000: if (state.current_state != STATE_INACTIVE){ @@ -210,6 +223,7 @@ void sm_handle_ams_in(){ void sm_set_error(ErrorKind error_kind, bool is_errored){} +#warning TODO: add error checking for everything here void sm_check_errors(){ if (module.status.THSD == 1) { state.error_type.bms_overtemp = 1; @@ -218,10 +232,3 @@ void sm_check_errors(){ state.error_source = (1 << 10); } } - -void sm_charging_check(){ - if (RELAY_BAT_SIDE_VOLTAGE < RELAY_ESC_SIDE_VOLTAGE && timestamp == 0) - timestamp = HAL_GetTick() + 5000; - if (timestamp < HAL_GetTick()) - state.target_state = STATE_CHARGING_PRECHARGE; -} \ No newline at end of file