Skip to content

Commit

Permalink
some error handling and added can filter
Browse files Browse the repository at this point in the history
  • Loading branch information
tiandahuang committed Nov 25, 2023
1 parent cc171be commit 18f4493
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 135 deletions.
8 changes: 6 additions & 2 deletions Apps/Src/CAN_Queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,16 @@ ErrorStatus CAN_ReceiveQueue_Post(CANMSG_t message) {

/**
* @brief: (NON Blocking) grabs a CANMSG from the receive queue
* @param: pointer to CANMSG
* @param message: pointer to CANMSG
* @return: error status
* @note: SemPend (Micrium) will have err = OS_ERR_PEND_WOULD_BLOCK, which is okay
*/
ErrorStatus CAN_ReceiveQueue_Pend(CANMSG_t *message) {
RTOS_BPS_SemPend(&canFifo_Receive_Sem4, OS_OPT_PEND_NON_BLOCKING);
BPS_OS_SEM_CTR cnt = RTOS_BPS_SemPend(&canFifo_Receive_Sem4, OS_OPT_PEND_NON_BLOCKING);
if (cnt == BPS_OS_SEM_WOULD_BLOCK) {
return ERROR;
}

RTOS_BPS_MutexPend(&canFifo_Receive_Mutex, OS_OPT_PEND_BLOCKING);
bool result = CAN_fifo_RECEIVE_get(&canFifo_RECEIVE, message);
RTOS_BPS_MutexPost(&canFifo_Receive_Mutex, OS_OPT_POST_NONE);
Expand Down
12 changes: 4 additions & 8 deletions Apps/Src/FaultState.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ void EnterFaultState() {

EEPROM_Init();

// if (BSP_WDTimer_DidSystemReset()) {
// Fault_BitMap = Fault_WDOG;
// }
if (BSP_WDTimer_DidSystemReset()) {
Fault_BitMap = Fault_WDOG;
}

// TODO: fix this so it works if there are multiple faults
#ifdef SIMULATION
Expand All @@ -94,14 +94,10 @@ void EnterFaultState() {

EEPROM_LogError(Fault_BitMap);

// TODO: create an interrupt-independent CAN interface, so we can use CAN from within a fault state
// avoid infinite recursive faults, since our CAN Driver relies on the OS to work
// also don't call CAN if the watchdog tripped, since CAN won't be initialized

//Deinitialize CAN registers
CANbus_DeInit();
//Reinit CAN in fault state
CANbus_Init(BPS_CAN_LOOPBACK, true);
CANbus_Init(BPS_CAN_LOOPBACK, true, NULL, 0);

#ifdef DEBUGMODE
char command[COMMAND_SIZE];
Expand Down
18 changes: 12 additions & 6 deletions BSP/Inc/BSP_CAN.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@

/**
* @brief Initializes the CAN module that communicates with the rest of the electrical system.
* @param rxEvent : the function to execute when recieving a message. NULL for no action.
* @param txEnd : the function to execute after transmitting a message. NULL for no action.
* @param faultState : if we should initialize CAN interrupts
* @param loopback : if we should use loopback mode (for testing)
* @param rxEvent : the function to execute when recieving a message. NULL for no action.
* @param txEnd : the function to execute after transmitting a message. NULL for no action.
* @param faultState : if we should initialize CAN interrupts
* @param loopback : if we should use loopback mode (for testing)
* @param txIDFilter : array of IDs to accept messages from. Pass NULL for no filtering.
* @param txIDFilterLen : length of txIDFilter array. Max 28 * 4 (28 filter banks * 4 IDs per bank)
* @return None
*/
void BSP_CAN_Init(callback_t rxEvent, callback_t txEnd, bool faultState, bool loopback);

void BSP_CAN_Init(callback_t rxEvent,
callback_t txEnd,
bool faultState,
bool loopback,
uint16_t *txIDFilter,
uint8_t txIDFilterLen);

/**
* @brief Calls stm-level CAN_DeInit
Expand Down
74 changes: 58 additions & 16 deletions BSP/STM32F413/Src/BSP_CAN.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ typedef struct _msg {
#define FIFO_NAME msg_queue
#include "fifo.h"

#define BSP_CAN_IDS_PER_FILTER 4
#define BSP_CAN_NUM_FILTERS 28

static msg_queue_t gRxQueue;

// Required for receiving CAN messages
Expand All @@ -31,13 +34,20 @@ static void (*gTxEnd)(void);

/**
* @brief Initializes the CAN module that communicates with the rest of the electrical system.
* @param rxEvent : the function to execute when recieving a message. NULL for no action.
* @param txEnd : the function to execute after transmitting a message. NULL for no action.
* @param faultState : if we should initialize CAN interrupts
* @param loopback : if we should use loopback mode (for testing)
* @param rxEvent : the function to execute when recieving a message. NULL for no action.
* @param txEnd : the function to execute after transmitting a message. NULL for no action.
* @param faultState : if we should initialize CAN interrupts
* @param loopback : if we should use loopback mode (for testing)
* @param txIDFilter : array of IDs to accept messages from. Pass NULL for no filtering.
* @param txIDFilterLen : length of txIDFilter array. Max 28 * 4 (28 filter banks * 4 IDs per bank)
* @return None
*/
void BSP_CAN_Init(callback_t rxEvent, callback_t txEnd, bool faultState, bool loopback) {
void BSP_CAN_Init(callback_t rxEvent,
callback_t txEnd,
bool faultState,
bool loopback,
uint16_t *txIDFilter,
uint8_t txIDFilterLen) {
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
Expand Down Expand Up @@ -92,17 +102,49 @@ void BSP_CAN_Init(callback_t rxEvent, callback_t txEnd, bool faultState, bool lo
CAN_InitStructure.CAN_Prescaler = 20;
CAN_Init(CAN1, &CAN_InitStructure);

/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0;//ARRAY_CONTACTOR_STATE_CHANGE << 5;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;//0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;//0xFFFF;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(CAN1, &CAN_FilterInitStructure);
/* CAN filter init
* Do nothing if we want to filter too many IDs
*/
if (txIDFilter && (txIDFilterLen <= BSP_CAN_IDS_PER_FILTER * BSP_CAN_NUM_FILTERS)) {
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

uint16_t *filter_fields[BSP_CAN_IDS_PER_FILTER] = {
&CAN_FilterInitStructure.CAN_FilterIdHigh,
&CAN_FilterInitStructure.CAN_FilterIdLow,
&CAN_FilterInitStructure.CAN_FilterMaskIdHigh,
&CAN_FilterInitStructure.CAN_FilterMaskIdLow
};

uint8_t num_ids_rounded = ((txIDFilterLen + BSP_CAN_IDS_PER_FILTER - 1)
/ BSP_CAN_IDS_PER_FILTER)
* BSP_CAN_IDS_PER_FILTER; // round up
for (uint8_t i = 0; i < num_ids_rounded; i++) {
// loop through a rounded-up number of IDs, that way we can fill in the empty
// filter banks with 0s.
*filter_fields[i / BSP_CAN_IDS_PER_FILTER] = (i < txIDFilterLen) ? (txIDFilter[i] << 5) : 0x0000;
if (i % BSP_CAN_IDS_PER_FILTER == 3) {
CAN_FilterInit(CAN1, &CAN_FilterInitStructure);
CAN_FilterInitStructure.CAN_FilterNumber++;
}
}
}
else {
// no filter
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(CAN1, &CAN_FilterInitStructure);
}

/* Transmit Structure preparation */
gTxMessage.ExtId = 0x1;
Expand Down
9 changes: 8 additions & 1 deletion Drivers/Inc/CANbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@
* @brief Initializes the CAN system
* @param loopback : if we should use loopback mode (for testing)
* @param faultState : fault state being true disables Tx and Rx interrupts
* @param txIDFilter : array of IDs to accept messages from. Pass NULL for no filtering.
* @param txIDFilterLen : length of txIDFilter array. Max 28 * 4 (28 filter banks * 4 IDs per bank)
* @return None
*/
void CANbus_Init(bool loopback, bool faultState);
void CANbus_Init(bool loopback, bool faultState, uint16_t *txIDFilter, uint8_t txIDFilterLen);

/**
* @brief name says it all
*/
bool CANbus_IsInitialized();

/**
* @brief Deitializes the CAN system
Expand Down
Loading

0 comments on commit 18f4493

Please sign in to comment.