From fbfa309c161aa4c50f4b3cfcbcf6ca34eb93c767 Mon Sep 17 00:00:00 2001 From: Nicholas DePatie <80368116+nwdepatie@users.noreply.github.com> Date: Thu, 14 Dec 2023 19:26:55 -0500 Subject: [PATCH] New CAN API Implementation (#108) * Updating Embedded-Base Submodule * Adapting to new CAN driver --- Core/Inc/cerberus_conf.h | 25 +++++++++++ Core/Inc/fault.h | 2 + Core/Src/can_handler.c | 89 +++++++++++++++++++++++++--------------- Core/Src/fault.c | 2 +- Core/Src/monitor.c | 14 +++---- Drivers/Embedded-Base | 2 +- 6 files changed, 90 insertions(+), 44 deletions(-) diff --git a/Core/Inc/cerberus_conf.h b/Core/Inc/cerberus_conf.h index 2fc01775..a18ce02f 100644 --- a/Core/Inc/cerberus_conf.h +++ b/Core/Inc/cerberus_conf.h @@ -1,5 +1,30 @@ #define YELLOW_LED_BLINK_DELAY 500 /* ms */ +#define FAULT_MCU_Pin GPIO_PIN_3 +#define FAULT_MCU_GPIO_Port GPIOC +#define BSE_1_Pin GPIO_PIN_0 +#define BSE_1_GPIO_Port GPIOA +#define BSE_2_Pin GPIO_PIN_1 +#define BSE_2_GPIO_Port GPIOA +#define APPS_1_Pin GPIO_PIN_2 +#define APPS_1_GPIO_Port GPIOA +#define APPS_2_Pin GPIO_PIN_3 +#define APPS_2_GPIO_Port GPIOA +#define GPIO_1_Pin GPIO_PIN_4 +#define GPIO_1_GPIO_Port GPIOC +#define GPIO_2_Pin GPIO_PIN_5 +#define GPIO_2_GPIO_Port GPIOC +#define GPIO_3_Pin GPIO_PIN_0 +#define GPIO_3_GPIO_Port GPIOB +#define GPIO_4_Pin GPIO_PIN_1 +#define GPIO_4_GPIO_Port GPIOB +#define WATCHDOG_Pin GPIO_PIN_15 +#define WATCHDOG_GPIO_Port GPIOB +#define LED_1_Pin GPIO_PIN_8 +#define LED_1_GPIO_Port GPIOC +#define LED_2_Pin GPIO_PIN_9 +#define LED_2_GPIO_Port GPIOC + #define CANID_TEMP_SENSOR 0xBEEF #define CANID_PEDAL_SENSOR 0xDEAD //TODO: GET CORRECT CAN ID diff --git a/Core/Inc/fault.h b/Core/Inc/fault.h index 89cd16ec..7e48871e 100644 --- a/Core/Inc/fault.h +++ b/Core/Inc/fault.h @@ -17,6 +17,8 @@ typedef enum { ONBOARD_TEMP_FAULT = 0x1, ONBOARD_PEDAL_FAULT = 0x2, IMU_FAULT = 0x4, + CAN_DISPATCH_FAULT = 0x8, + CAN_ROUTING_FAULT = 0x10, } fault_code_t; typedef struct { diff --git a/Core/Src/can_handler.c b/Core/Src/can_handler.c index 75542f5c..47d3ddbb 100644 --- a/Core/Src/can_handler.c +++ b/Core/Src/can_handler.c @@ -11,36 +11,35 @@ #include "can_handler.h" #include "can.h" -#include "can_config.h" #include #include "fault.h" #include #include "cerberus_conf.h" #define CAN_MSG_QUEUE_SIZE 25 /* messages */ -#define NUM_CALLBACKS 5 // Update when adding new callbacks +#define NUM_INBOUND_CAN_IDS 1 /* Update when adding new callbacks */ +/* Queue for Inbound CAN Messages */ static osMessageQueueId_t can_inbound_queue; -osThreadId_t route_can_incoming_handle; -const osThreadAttr_t route_can_incoming_attributes = { - .name = "RouteCanIncoming", - .stack_size = 128 * 8, - .priority = (osPriority_t)osPriorityAboveNormal4 -}; -static CAN_HandleTypeDef* hcan1; +/* Relevant Info for Initializing CAN 1 */ +static can_t *can1; +static const uint16_t id_list[NUM_INBOUND_CAN_IDS] = { + //CANID_X, + NULL +}; + +/* Relevant Info for Cerberus CAN LUT */ typedef void (*callback_t)(can_msg_t); -/* Struct to couple function with message IDs */ typedef struct { uint8_t id; callback_t function; } function_info_t; -// TODO: Evaluate memory usage here -static function_info_t can_callbacks[] = { +static function_info_t can_callbacks[NUM_INBOUND_CAN_IDS] = { // TODO: Implement MC_Update and other callbacks //{ .id = 0x2010, .function = (*MC_update)(can_msg_t) }, //{ .id = 0x2110, .function = (*MC_update)(can_msg_t) }, @@ -51,52 +50,76 @@ static function_info_t can_callbacks[] = { static callback_t getFunction(uint8_t id) { - int i; - - for (i = 0; i < NUM_CALLBACKS; i++) { + //TODO: optimization of create algo to more efficiently find handler + for (uint8_t i = 0; i < NUM_INBOUND_CAN_IDS; i++) { if (can_callbacks[i].id == id) return can_callbacks[i].function; } return NULL; } -void can1_isr() +/* Callback to be called when we get a CAN message */ +void can1_callback(CAN_HandleTypeDef *hcan) { - // TODO: Wrap this HAL function into a "get_message" function in the CAN driver + fault_data_t fault_data = { + .id = CAN_ROUTING_FAULT, + .severity = DEFCON2, + }; + CAN_RxHeaderTypeDef rx_header; + can_msg_t new_msg; - new_msg.line = CAN_LINE_1; - HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO1, &rx_header, new_msg.data); + + /* Read in CAN message */ + if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, new_msg.data) != HAL_OK) { + fault_data.diag = "Failed to read CAN Msg"; + queue_fault(&fault_data); + } new_msg.len = rx_header.DLC; new_msg.id = rx_header.StdId; - /* Publish to Onboard Temp Queue */ + /* Publish to CAN processing queue */ osMessageQueuePut(can_inbound_queue, &new_msg, 0U, 0U); } +/* Inbound Task-specific Info */ +osThreadId_t route_can_incoming_handle; +const osThreadAttr_t route_can_incoming_attributes = { + .name = "RouteCanIncoming", + .stack_size = 128 * 8, + .priority = (osPriority_t)osPriorityAboveNormal4 +}; + void vRouteCanIncoming(void* pv_params) { can_msg_t* message; osStatus_t status; callback_t callback; + fault_data_t fault_data = { .id = CAN_ROUTING_FAULT, .severity = DEFCON2 }; + can1->callback = can1_callback; + can1->id_list = id_list; + can1->id_list_len = NUM_INBOUND_CAN_IDS; - hcan1 = (CAN_HandleTypeDef*)pv_params; + can1->hcan = (CAN_HandleTypeDef *)pv_params; - // TODO: Initialize CAN here? Or at least initialize it somewhere + if (can_init(can1)) { + fault_data.diag = "Failed to init CAN handler"; + queue_fault(&fault_data); + } can_inbound_queue = osMessageQueueNew(CAN_MSG_QUEUE_SIZE, sizeof(can_msg_t), NULL); - // TODO: Link CAN1_ISR via hcan1, future ticket needs to enable CAN driver to pass in devoloper ISR - for (;;) { /* Wait until new CAN message comes into queue */ status = osMessageQueueGet(can_inbound_queue, &message, NULL, 0U); if (status != osOK) { - // TODO: Trigger fault ? + fault_data.diag = "Init Failed"; + queue_fault(&fault_data); } else { callback = getFunction(message->id); if (callback == NULL) { - // TODO: Trigger low priority error + fault_data.diag = "No callback found"; + queue_fault(&fault_data); } else { callback(*message); } @@ -116,20 +139,18 @@ void vCanDispatch(void* pv_params) { const uint16_t can_dispatch_delay = 100; //ms fault_data_t fault_data = { - .id = 1, /* this is arbitrary */ - .severity = DEFCON2 + .id = CAN_DISPATCH_FAULT, + .severity = DEFCON1 }; can_outbound_queue = osMessageQueueNew(CAN_MSG_QUEUE_SIZE, sizeof(can_msg_t), NULL); can_msg_t msg_from_queue; - // Wait until a message is in the queue, send messages when they are in the queue for(;;) { - // "borrowed" from temp sensor CAN code (PR 58) - /* Send CAN message */ //queue id buffer to put data timeout + /* Send CAN message */ if (osOK == osMessageQueueGet(can_outbound_queue, &msg_from_queue, NULL, 50)) { - if (can_send_message(msg_from_queue)) { + if (can_send_msg(can1, &msg_from_queue)) { fault_data.diag = "Failed to send CAN message"; queue_fault(&fault_data); } @@ -143,7 +164,7 @@ void vCanDispatch(void* pv_params) { int queue_can_msg(can_msg_t msg) { if(!can_outbound_queue) - return 1; + return -1; osMessageQueuePut(can_outbound_queue, &msg, 0U, 0U); -} \ No newline at end of file +} diff --git a/Core/Src/fault.c b/Core/Src/fault.c index e0d37b85..3400af18 100644 --- a/Core/Src/fault.c +++ b/Core/Src/fault.c @@ -16,7 +16,7 @@ const osThreadAttr_t fault_handle_attributes = { int queue_fault(fault_data_t *fault_data) { if(!fault_handle_queue) - return 1; + return -1; osMessageQueuePut(fault_handle_queue, fault_data, 0U, 0U); } diff --git a/Core/Src/monitor.c b/Core/Src/monitor.c index 166bc409..487152fd 100644 --- a/Core/Src/monitor.c +++ b/Core/Src/monitor.c @@ -28,7 +28,7 @@ void vTempMonitor(void* pv_params) sht30_t temp_sensor; I2C_HandleTypeDef* hi2c1; can_msg_t temp_msg - = { .id = CANID_TEMP_SENSOR, .len = can_msg_len, .line = CAN_LINE_1, .data = { 0 } }; + = { .id = CANID_TEMP_SENSOR, .len = can_msg_len, .data = { 0 } }; hi2c1 = (I2C_HandleTypeDef*)pv_params; temp_sensor.i2c_handle = hi2c1; @@ -55,7 +55,7 @@ void vTempMonitor(void* pv_params) /* Send CAN message */ //memcpy(temp_msg.data, &sensor_data, can_msg_len); - //if (can_send_message(temp_msg)) { + //if (queue_can_msg(temp_msg)) { // fault_data.diag = "Failed to send CAN message"; // queue_fault(&fault_data); //} @@ -109,7 +109,7 @@ void vPedalsMonitor(void* pv_params) fault_data_t fault_data = { .id = ONBOARD_PEDAL_FAULT, .severity = DEFCON1 }; can_msg_t pedal_msg - = { .id = CANID_PEDAL_SENSOR, .len = can_msg_len, .line = CAN_LINE_1, .data = { 0 } }; + = { .id = CANID_PEDAL_SENSOR, .len = can_msg_len, .data = { 0 } }; /* Handle ADC Data for two input accelerator value and two input brake value*/ pedal_params_t* params = (pedal_params_t*)pv_params; @@ -171,7 +171,7 @@ void vPedalsMonitor(void* pv_params) /* Send CAN message */ //memcpy(pedal_msg.data, &sensor_data, can_msg_len); - //if (can_send_message(pedal_msg)) { + //if (queue_can_msg(pedal_msg)) { // fault_data.diag = "Failed to send CAN message"; // queue_fault(&fault_data); //} @@ -203,13 +203,11 @@ void vIMUMonitor(void *pv_params) can_msg_t imu_accel_msg = { .id = CANID_IMU, .len = accel_msg_len, - .line = CAN_LINE_1, .data = {0} }; can_msg_t imu_gyro_msg = { .id = CANID_IMU, .len = gyro_msg_len, - .line = CAN_LINE_1, .data = {0} }; @@ -254,13 +252,13 @@ void vIMUMonitor(void *pv_params) /* Send CAN message */ //memcpy(imu_accel_msg.data, &sensor_data, accel_msg_len); - //if (can_send_message(imu_accel_msg)) { + //if (queue_can_msg(imu_accel_msg)) { // fault_data.diag = "Failed to send CAN message"; // queue_fault(&fault_data); //} //memcpy(imu_gyro_msg.data, &sensor_data, gyro_msg_len); - //if (can_send_message(imu_gyro_msg)) { + //if (queue_can_msg(imu_gyro_msg)) { // fault_data.diag = "Failed to send CAN message"; // queue_fault(&fault_data); //} diff --git a/Drivers/Embedded-Base b/Drivers/Embedded-Base index c2ea04a5..8a5c28a9 160000 --- a/Drivers/Embedded-Base +++ b/Drivers/Embedded-Base @@ -1 +1 @@ -Subproject commit c2ea04a5b042dd3102c9d8f3b7bfdcf9a27182b4 +Subproject commit 8a5c28a97067ddf995ce5fcff649398681c80fbd