diff --git a/Core/Inc/AMS_CAN.h b/Core/Inc/AMS_CAN.h index 31c42a4..5bc3e50 100644 --- a/Core/Inc/AMS_CAN.h +++ b/Core/Inc/AMS_CAN.h @@ -14,6 +14,8 @@ #include "stm32f4xx_hal_can.h" #include "stm32f4xx_hal_def.h" +#include + #define CAN_ID_SLAVE_ERROR 0x001 #define CAN_ID_AMS_SLAVE_HEARTBEAT_BASE 0x600 #define CAN_HEARTBEAT_TX_TIMEOUT 5 /* ms */ @@ -24,9 +26,18 @@ void ams_can_handle_ams_msg(CAN_RxHeaderTypeDef* header, uint8_t* data); void ams_can_handle_car_msg(CAN_RxHeaderTypeDef* header, uint8_t* data); void ams_can_send_heartbeat(); -void ams_can_send_error(AMS_ErrorCode error_code); +/** + * @brief Send an AMS Error via CAN. + * + * @param error_code The kind of error + * @param transmission_timeout How long to wait for the transmission to complete + * after starting it (in ms). Set to 0 for no wait. + */ +void ams_can_send_error(AMS_ErrorCode error_code, + uint32_t transmission_timeout); -HAL_StatusTypeDef ams_can_wait_for_free_mailbox(CAN_HandleTypeDef* handle, - uint32_t timeout); +HAL_StatusTypeDef ams_can_wait_for_free_mailboxes(CAN_HandleTypeDef* handle, + int num_mailboxes, + uint32_t timeout); #endif /* INC_AMS_CAN_H_ */ diff --git a/Core/Inc/BQ_Abstraction_Layer.h b/Core/Inc/BQ_Abstraction_Layer.h index 366c2dc..e286246 100644 --- a/Core/Inc/BQ_Abstraction_Layer.h +++ b/Core/Inc/BQ_Abstraction_Layer.h @@ -20,6 +20,7 @@ #define CELL_UV_THRESHOLD 34100 // 2.6V extern uint16_t cell_voltages[N_CELLS]; +extern uint16_t max_voltage, min_voltage; typedef enum { BQ_OFF, BQ_RDY, BQ_STDBY, BQ_INIT_PHASE, BQ_ERROR } BQ_Status; extern BQ_Status bq_status; diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 0760271..88b5bfb 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -40,7 +40,9 @@ typedef enum { AMS_ERROR_UV, AMS_ERROR_OV, AMS_ERROR_UT, - AMS_ERROR_OT + AMS_ERROR_OT, + AMS_ERROR_BQ, + AMS_ERROR_TMP144 } AMS_ErrorCode; /* USER CODE END ET */ @@ -51,7 +53,12 @@ extern uint8_t slave_id; /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ -#define MAIN_LOOP_PERIOD 100 /* ms */ +#define MAIN_LOOP_PERIOD 100 /* ms */ +#define AMS_ERROR_TX_TIMEOUT 2 /* ms */ +#define THRESH_UV 32768 /* 2.5V */ +#define THRESH_OV 55050 /* 4.2V */ +#define THRESH_UT 0 /* 0C */ +#define THRESH_OT 880 /* 55C */ /* USER CODE END EM */ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim); @@ -61,6 +68,7 @@ void Error_Handler(void); /* USER CODE BEGIN EFP */ void update_status_leds(); +void check_error_conditions(); void delay_period(); /* USER CODE END EFP */ diff --git a/Core/Src/AMS_CAN.c b/Core/Src/AMS_CAN.c index 28f9a77..8a8ce16 100644 --- a/Core/Src/AMS_CAN.c +++ b/Core/Src/AMS_CAN.c @@ -16,6 +16,8 @@ #include "stm32f4xx_hal.h" #include "stm32f4xx_hal_can.h" +#include + static CAN_HandleTypeDef* handle_ams; static CAN_HandleTypeDef* handle_car; @@ -127,7 +129,8 @@ void ams_can_send_heartbeat() { } } -void ams_can_send_error(AMS_ErrorCode error_code) { +void ams_can_send_error(AMS_ErrorCode error_code, + uint32_t transmission_timeout) { static CAN_TxHeaderTypeDef header; header.IDE = CAN_ID_STD; header.DLC = 8; @@ -143,13 +146,15 @@ void ams_can_send_error(AMS_ErrorCode error_code) { CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2); uint32_t mailbox; HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox); + ams_can_wait_for_free_mailboxes(handle_ams, 3, transmission_timeout); } -HAL_StatusTypeDef ams_can_wait_for_free_mailbox(CAN_HandleTypeDef* handle, - uint32_t timeout) { +HAL_StatusTypeDef ams_can_wait_for_free_mailboxes(CAN_HandleTypeDef* handle, + int num_mailboxes, + uint32_t timeout) { uint32_t end = HAL_GetTick() + timeout; while (HAL_GetTick() < end) { - if (HAL_CAN_GetTxMailboxesFreeLevel(handle) > 0) { + if (HAL_CAN_GetTxMailboxesFreeLevel(handle) >= num_mailboxes) { return HAL_OK; } } diff --git a/Core/Src/BQ_Abstraction_Layer.c b/Core/Src/BQ_Abstraction_Layer.c index 1c686aa..5ee6ade 100644 --- a/Core/Src/BQ_Abstraction_Layer.c +++ b/Core/Src/BQ_Abstraction_Layer.c @@ -16,6 +16,7 @@ #include uint16_t cell_voltages[N_CELLS]; +uint16_t max_voltage, min_voltage; BQ_Status bq_status; BQ_Error_Description bq_error; @@ -82,11 +83,20 @@ void afe_measure() { lastmeasurementtime = HAL_GetTick(); if (retval == BQ_COMM_OK) { + uint16_t max = 0; + uint16_t min = 0xFFFF; for (int n = 0; n < N_CELLS; n++) { - cell_voltages[N_CELLS - 1 - n] = - (uint16_t)(cellvoltagebuffer[2 * n] << 8) + - (uint16_t)cellvoltagebuffer[2 * n + 1]; + uint16_t v = cellvoltagebuffer[2 * n] << 8 | cellvoltagebuffer[2 * n + 1]; + cell_voltages[N_CELLS - 1 - n] = v; + if (v > max) { + max = v; + } + if (v < min) { + min = v; + } } + max_voltage = max; + min_voltage = min; } else if (retval == BQ_COMM_ERR_HAL) { bq_set_error_with_loc(BQ_COMM_ERR_HAL, BQ_ERROR_LOC_MEASURE); } else if (retval == BQ_COMM_ERR_CRC) { diff --git a/Core/Src/main.c b/Core/Src/main.c index 3c8d85d..a572064 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -21,10 +21,12 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include "AMS_CAN.h" #include "BQ_Abstraction_Layer.h" #include "EEPROM.h" #include "FanControl.h" #include "TMP144.h" +#include "common_defs.h" #include "stm32f4xx_hal.h" #include "stm32f4xx_hal_gpio.h" @@ -94,6 +96,29 @@ void update_status_leds() { } } +void check_error_conditions() { + if (bq_status != BQ_RDY) { + ams_can_send_error(AMS_ERROR_BQ, AMS_ERROR_TX_TIMEOUT); + } + tmp144_check_timeouts(); + if (tmp144_bus_busbar.state == TMP144_ERROR || + tmp144_bus_other.state == TMP144_ERROR) { + ams_can_send_error(AMS_ERROR_TMP144, AMS_ERROR_TX_TIMEOUT); + } + if (min_voltage < THRESH_UV) { + ams_can_send_error(AMS_ERROR_UV, AMS_ERROR_TX_TIMEOUT); + } + if (max_voltage > THRESH_OV) { + ams_can_send_error(AMS_ERROR_OV, AMS_ERROR_TX_TIMEOUT); + } + if (min_temperature < THRESH_UT) { + ams_can_send_error(AMS_ERROR_UT, AMS_ERROR_TX_TIMEOUT); + } + if (max_temperature > THRESH_OT) { + ams_can_send_error(AMS_ERROR_OT, AMS_ERROR_TX_TIMEOUT); + } +} + void delay_period() { static uint32_t last_it = 0; uint32_t now = HAL_GetTick(); @@ -161,8 +186,9 @@ int main(void) { /* USER CODE BEGIN 3 */ update_status_leds(); afe_measure(); + tmp144_read_temps(); + check_error_conditions(); delay_period(); - fan_ctrl_set_power((HAL_GetTick() / 100) % 100); } /* USER CODE END 3 */ }