Skip to content

Commit

Permalink
New CAN API Implementation (#108)
Browse files Browse the repository at this point in the history
* Updating Embedded-Base Submodule

* Adapting to new CAN driver
  • Loading branch information
nwdepatie committed Feb 4, 2024
1 parent 0e024b1 commit fbfa309
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 44 deletions.
25 changes: 25 additions & 0 deletions Core/Inc/cerberus_conf.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions Core/Inc/fault.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
89 changes: 55 additions & 34 deletions Core/Src/can_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,35 @@

#include "can_handler.h"
#include "can.h"
#include "can_config.h"
#include <stdlib.h>
#include "fault.h"
#include <string.h>
#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) },
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
}
2 changes: 1 addition & 1 deletion Core/Src/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
14 changes: 6 additions & 8 deletions Core/Src/monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
//}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
//}
Expand Down Expand Up @@ -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}
};

Expand Down Expand Up @@ -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);
//}
Expand Down

0 comments on commit fbfa309

Please sign in to comment.