diff --git a/Core/Inc/AMS_CAN.h b/Core/Inc/AMS_CAN.h index 7f5911b..31c42a4 100644 --- a/Core/Inc/AMS_CAN.h +++ b/Core/Inc/AMS_CAN.h @@ -8,9 +8,15 @@ #ifndef INC_AMS_CAN_H_ #define INC_AMS_CAN_H_ -#include "stm32f4xx_hal.h" +#include "main.h" -#define CAN_ID_AMS_SLAVE_HEARTBEAT_BASE 0x100 +#include "stm32f4xx_hal.h" +#include "stm32f4xx_hal_can.h" +#include "stm32f4xx_hal_def.h" + +#define CAN_ID_SLAVE_ERROR 0x001 +#define CAN_ID_AMS_SLAVE_HEARTBEAT_BASE 0x600 +#define CAN_HEARTBEAT_TX_TIMEOUT 5 /* ms */ void ams_can_init(CAN_HandleTypeDef* ams, CAN_HandleTypeDef* car); @@ -18,5 +24,9 @@ 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); + +HAL_StatusTypeDef ams_can_wait_for_free_mailbox(CAN_HandleTypeDef* handle, + uint32_t timeout); #endif /* INC_AMS_CAN_H_ */ diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 4d993bd..0760271 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -36,11 +36,17 @@ extern "C" { /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ - +typedef enum { + AMS_ERROR_UV, + AMS_ERROR_OV, + AMS_ERROR_UT, + AMS_ERROR_OT +} AMS_ErrorCode; /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ +extern uint8_t slave_id; /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ diff --git a/Core/Src/AMS_CAN.c b/Core/Src/AMS_CAN.c index 0c0bec2..28f9a77 100644 --- a/Core/Src/AMS_CAN.c +++ b/Core/Src/AMS_CAN.c @@ -9,6 +9,12 @@ #include "BQ_Abstraction_Layer.h" #include "TMP144.h" +#include "common_defs.h" +#include "main.h" + +#include "stm32f4xx.h" +#include "stm32f4xx_hal.h" +#include "stm32f4xx_hal_can.h" static CAN_HandleTypeDef* handle_ams; static CAN_HandleTypeDef* handle_car; @@ -81,34 +87,71 @@ void ams_can_handle_car_msg(CAN_RxHeaderTypeDef* header, uint8_t* data) {} void ams_can_send_heartbeat() { static CAN_TxHeaderTypeDef header; static uint8_t data[8]; - static uint8_t SLAVE_ID = 0; header.IDE = CAN_ID_STD; header.DLC = 8; header.RTR = CAN_RTR_DATA; header.TransmitGlobalTime = DISABLE; - for (int i = 0; i < N_CELLS / 2; i++) { - header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (SLAVE_ID) << 4 | i; - uint16_t v1 = cell_voltages[i * 2]; - uint16_t v2 = cell_voltages[i * 2 + 1]; - data[0] = v1 >> 8; - data[1] = v1 & 0xFF; - data[2] = v2 >> 8; - data[3] = v2 & 0xFF; - uint16_t t1 = temperatures[i * 2]; - uint16_t t2 = temperatures[i * 2 + 1]; - data[4] = t1 >> 8; - data[5] = t1 & 0xFF; - data[6] = t2 >> 8; - data[7] = t2 & 0xFF; - uint32_t mailbox; - HAL_StatusTypeDef status; - if ((status = HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox)) != + // Send voltages + for (int msg_id = 0; msg_id < 3; msg_id++) { + header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (slave_id << 4) | msg_id; + for (int i = 0; i < 4; i++) { + int cell = msg_id * 4 + i; + uint16_t v = (cell < N_CELLS) ? cell_voltages[cell] : 0; + data[2 * i + 0] = v & 0xFF; + data[2 * i + 1] = v >> 8; + } + if (ams_can_wait_for_free_mailbox(handle_ams, CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) { - Error_Handler(); - } else { - HAL_Delay(100); + uint32_t mailbox; + HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox); + } + } + + // Send temperatures + for (int temp_msg_id = 0; temp_msg_id < 8; temp_msg_id++) { + int msg_id = temp_msg_id + 3; + header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (slave_id << 4) | msg_id; + for (int i = 0; i < 4; i++) { + int sensor = temp_msg_id * 4 + i; + uint16_t temp = temperatures[sensor]; + data[2 * i + 0] = temp & 0xFF; + data[2 * i + 1] = temp >> 8; + } + if (ams_can_wait_for_free_mailbox(handle_ams, CAN_HEARTBEAT_TX_TIMEOUT) == + HAL_OK) { + uint32_t mailbox; + HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox); } } } + +void ams_can_send_error(AMS_ErrorCode error_code) { + static CAN_TxHeaderTypeDef header; + header.IDE = CAN_ID_STD; + header.DLC = 8; + header.RTR = CAN_RTR_DATA; + header.TransmitGlobalTime = DISABLE; + header.StdId = CAN_ID_SLAVE_ERROR; + + static uint8_t data[8]; + data[0] = slave_id; + data[1] = error_code; + + HAL_CAN_AbortTxRequest(handle_ams, + CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2); + uint32_t mailbox; + HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox); +} + +HAL_StatusTypeDef ams_can_wait_for_free_mailbox(CAN_HandleTypeDef* handle, + uint32_t timeout) { + uint32_t end = HAL_GetTick() + timeout; + while (HAL_GetTick() < end) { + if (HAL_CAN_GetTxMailboxesFreeLevel(handle) > 0) { + return HAL_OK; + } + } + return HAL_TIMEOUT; +} diff --git a/Core/Src/main.c b/Core/Src/main.c index 16cdcbe..3c8d85d 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -60,7 +60,7 @@ UART_HandleTypeDef huart3; UART_HandleTypeDef huart6; /* USER CODE BEGIN PV */ - +uint8_t slave_id; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -149,10 +149,7 @@ int main(void) { HAL_Delay(100); afe_init(&huart2); eeprom_init(&hi2c1); - uint8_t id; - if (eeprom_read_random(EEPROM_ADDR_SLAVE_ID, &id) == HAL_OK) { - HAL_GPIO_WritePin(STAT_LED4_GPIO_Port, STAT_LED4_Pin, GPIO_PIN_SET); - } + eeprom_read_random(EEPROM_ADDR_SLAVE_ID, &slave_id); fan_ctrl_init(&htim3, TIM_CHANNEL_4); /* USER CODE END 2 */