79 lines
2.1 KiB
C
79 lines
2.1 KiB
C
|
#include "FT_CAN_AL.h"
|
||
|
|
||
|
#ifdef FTCAN_IS_BXCAN
|
||
|
static CAN_HandleTypeDef *hcan;
|
||
|
|
||
|
HAL_StatusTypeDef ftcan_init(CAN_HandleTypeDef *handle) {
|
||
|
hcan = handle;
|
||
|
|
||
|
HAL_StatusTypeDef status =
|
||
|
HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||
|
if (status != HAL_OK) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
return HAL_CAN_Start(hcan);
|
||
|
}
|
||
|
|
||
|
HAL_StatusTypeDef ftcan_transmit(uint8_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(hcan, &header, data, &mailbox);
|
||
|
}
|
||
|
|
||
|
HAL_StatusTypeDef ftcan_add_filter(uint8_t id, uint8_t mask) {
|
||
|
static uint32_t next_filter_no = 0;
|
||
|
static CAN_FilterTypeDef filter;
|
||
|
if (next_filter_no % 2 == 0) {
|
||
|
filter.FilterIdHigh = id;
|
||
|
filter.FilterMaskIdHigh = mask;
|
||
|
filter.FilterIdLow = 0;
|
||
|
filter.FilterMaskIdLow = 0xFFFF;
|
||
|
} else {
|
||
|
// Leave high filter untouched from the last configuration
|
||
|
filter.FilterIdLow = id;
|
||
|
filter.FilterMaskIdLow = mask;
|
||
|
}
|
||
|
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
|
||
|
filter.FilterBank = next_filter_no / 2;
|
||
|
if (filter.FilterBank > FTCAN_MAX_FILTER_NO) {
|
||
|
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_MAX_FILTER_NO + 1;
|
||
|
|
||
|
return HAL_CAN_ConfigFilter(hcan, &filter);
|
||
|
}
|
||
|
|
||
|
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *handle) {
|
||
|
if (handle != hcan) {
|
||
|
return;
|
||
|
}
|
||
|
CAN_RxHeaderTypeDef header;
|
||
|
uint8_t data[8];
|
||
|
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &header, data) != HAL_OK) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (header.IDE != CAN_ID_STD) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ftcan_msg_received_cb(header.StdId, header.DLC, data);
|
||
|
}
|
||
|
#endif // CAN_IS_BXCAN
|
||
|
|
||
|
__weak void ftcan_msg_received_cb(uint8_t id, size_t datalen,
|
||
|
const uint8_t *data) {}
|