#include "canhalal.h" #define FTCAN_NUM_FILTERS 2 HAL_StatusTypeDef ftcan_init(CAN_HandleTypeDef *handle) { HAL_StatusTypeDef status = HAL_CAN_ActivateNotification(handle, CAN_IT_RX_FIFO0_MSG_PENDING); if (status != HAL_OK) { return status; } return HAL_CAN_Start(handle); } HAL_StatusTypeDef ftcan_transmit(CAN_HandleTypeDef *handle, uint16_t id, const uint8_t *data, size_t datalen) { static CAN_TxHeaderTypeDef header; header.StdId = id; header.IDE = CAN_ID_STD; header.RTR = CAN_RTR_DATA; header.DLC = datalen; uint32_t mailbox; return HAL_CAN_AddTxMessage(handle, &header, data, &mailbox); } HAL_StatusTypeDef ftcan_add_filter(CAN_HandleTypeDef *handle, uint16_t id, uint16_t mask) { static uint32_t next_filter_no = 0; static CAN_FilterTypeDef filter; if (next_filter_no % 2 == 0) { filter.FilterIdHigh = id << 5; filter.FilterMaskIdHigh = mask << 5; filter.FilterIdLow = id << 5; filter.FilterMaskIdLow = mask << 5; } else { // Leave high filter untouched from the last configuration filter.FilterIdLow = id << 5; filter.FilterMaskIdLow = mask << 5; } filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.FilterBank = next_filter_no / 2; if (filter.FilterBank > FTCAN_NUM_FILTERS + 1) { return HAL_ERROR; } filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterScale = CAN_FILTERSCALE_16BIT; filter.FilterActivation = CAN_FILTER_ENABLE; // Disable slave filters // TODO: Some STM32 have multiple CAN peripherals, and one uses the slave // filter bank filter.SlaveStartFilterBank = FTCAN_NUM_FILTERS; HAL_StatusTypeDef status = HAL_CAN_ConfigFilter(handle, &filter); if (status == HAL_OK) { next_filter_no++; } return status; }