| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- #include "can.h"
- void CAN_Filter_StructInit(CAN_FilterConfigTypeDef *init)
- {
- init->FilterMode = CAN_FILTER_SINGLE;
- for (int i = 0; i < 4; ++i) {
- init->FilterMask[i] = CAN_FILTER_DONT_CARE; // Accept message with any identifier
- init->FilterCode[i] = 0x00;
- }
- }
- // Single filter for standard frame format. Can match ID, RTR, and data bytes 1 and 2
- void CAN_SetStandardSingleFilter(CAN_FilterConfigTypeDef *init, uint16_t id_mask, uint16_t id_code,
- uint16_t data_mask, uint16_t data_code, uint8_t rtr_mask, uint8_t rtr_code)
- {
- init->FilterMode = CAN_FILTER_SINGLE;
- init->FilterMask[0] = id_mask >> 3;
- init->FilterCode[0] = id_code >> 3;
- init->FilterMask[1] = (id_mask << 5) | (rtr_mask ? (1 << 4) : 0);
- init->FilterCode[1] = (id_code << 5) | (rtr_code ? (1 << 4) : 0);
- init->FilterMask[2] = data_mask >> 8; // Data byte 1
- init->FilterCode[2] = data_code >> 8; // Data byte 1
- init->FilterMask[3] = data_mask; // Data byte 2
- init->FilterCode[3] = data_code; // Data byte 2
- }
- // Dual filter for standard frame format. Filter 0 can match ID, RTR, and data byte 1. Filter 2 can match ID and RTR
- void CAN_SetStandardDualFilter(CAN_FilterConfigTypeDef *init, uint16_t id_mask0, uint16_t id_code0,
- uint8_t data_mask0, uint8_t data_code0, uint8_t rtr_mask0, uint8_t rtr_code0,
- uint16_t id_mask1, uint16_t id_code1, uint8_t rtr_mask1, uint8_t rtr_code1)
- {
- init->FilterMode = CAN_FILTER_DUAL;
- init->FilterMask[0] = id_mask0 >> 3;
- init->FilterCode[0] = id_code0 >> 3;
- init->FilterMask[1] = (id_mask0 << 5) | (rtr_mask0 ? (1 << 4) : 0) | (data_mask0 >> 4);
- init->FilterCode[1] = (id_code0 << 5) | (rtr_code0 ? (1 << 4) : 0) | (data_code0 >> 4);
- init->FilterMask[2] = id_mask1 >> 3;
- init->FilterCode[2] = id_code1 >> 3;
- init->FilterMask[3] = (id_mask1 << 5) | (rtr_mask1 ? (1 << 4) : 0) | (data_mask0 & 0xf);
- init->FilterCode[3] = (id_code1 << 5) | (rtr_code1 ? (1 << 4) : 0) | (data_code0 & 0xf);
- }
- // Single filter for extended frame format. Can match ID and RTR
- void CAN_SetExtendedSingleFilter(CAN_FilterConfigTypeDef *init, uint32_t id_mask, uint32_t id_code,
- uint8_t rtr_mask, uint8_t rtr_code)
- {
- init->FilterMode = CAN_FILTER_SINGLE;
- init->FilterMask[0] = id_mask >> 21;
- init->FilterCode[0] = id_code >> 21;
- init->FilterMask[1] = id_mask >> 13;
- init->FilterCode[1] = id_code >> 13;
- init->FilterMask[2] = id_mask >> 5;
- init->FilterCode[2] = id_code >> 5;
- init->FilterMask[3] = (id_mask << 3) | (rtr_mask ? (1 << 2) : 0);
- init->FilterCode[3] = (id_code << 3) | (rtr_code ? (1 << 2) : 0);
- }
- // Dual filter for extended frame format. Each filter can match the upper 16 bits of the 29-bit ID
- void CAN_SetExtendedDualFilter(CAN_FilterConfigTypeDef *init, uint32_t id_mask0, uint32_t id_code0,
- uint32_t id_mask1, uint32_t id_code1)
- {
- init->FilterMode = CAN_FILTER_DUAL;
- init->FilterMask[0] = id_mask0 >> 21;
- init->FilterCode[0] = id_code0 >> 21;
- init->FilterMask[1] = id_mask0 >> 13;
- init->FilterCode[1] = id_code0 >> 13;
- init->FilterMask[2] = id_mask1 >> 21;
- init->FilterCode[2] = id_code1 >> 21;
- init->FilterMask[3] = id_mask1 >> 13;
- init->FilterCode[3] = id_code1 >> 13;
- }
- void CAN_StructInit(CAN_InitTypeDef *init)
- {
- init->Prescaler = 0;
- init->SJW = CAN_SJW_1TQ;
- init->TSeg1 = CAN_TSEG1_1TQ;
- init->TSeg2 = CAN_TSEG2_1TQ;
- init->Sampling = CAN_SAMPLING_1;
- CAN_Filter_StructInit(&init->FilterConfig);
- }
- void CAN_Init(CAN_TypeDef *can, CAN_InitTypeDef *init)
- {
- can->MOD = CAN_MOD_RESET;
- can->BTR0 = init->Prescaler | init->SJW;
- can->BTR1 = init->TSeg1 | init->TSeg2 | init->Sampling;
- for (int i = 0; i < 4; ++i) {
- can->AMR[i] = init->FilterConfig.FilterMask[i];
- can->ACR[i] = init->FilterConfig.FilterCode[i];
- }
- can->OCR = CAN_OUTPUT_MODE_NORMAL;
- can->RXERR = 0;
- can->TXERR = 0;
- can->MOD = init->FilterConfig.FilterMode; // Will also clear the reset bit
- }
- void CAN_PrepareTx(CAN_TypeDef *can, CAN_TxMessageTypeDef *tx_msg)
- {
- CAN_WaitForTx(can);
- can->TXFRAME = tx_msg->FF | tx_msg->RTR | tx_msg->DLC;
- int data_idx;
- if (tx_msg->FF == CAN_STANDARD_FRAME_FORMAT) {
- can->TXDATA[0] = (tx_msg->ID >> 3);
- can->TXDATA[1] = (tx_msg->ID << 5) | (tx_msg->RTR >> 2);
- data_idx = 2;
- } else { // CAN_EXTENDTED_FRAME_FORMAT
- can->TXDATA[0] = (tx_msg->ID >> 21);
- can->TXDATA[1] = (tx_msg->ID >> 13);
- can->TXDATA[2] = (tx_msg->ID >> 5);
- can->TXDATA[3] = (tx_msg->ID << 3) | (tx_msg->RTR >> 4);
- data_idx = 4;
- }
- for (unsigned int i = 0; i < tx_msg->DLC; ++i) {
- can->TXDATA[data_idx + i] = tx_msg->Data[i];
- }
- }
- void CAN_Transmit(CAN_TypeDef *can, CAN_TxMessageTypeDef *tx_msg)
- {
- CAN_PrepareTx(can, tx_msg);
- CAN_StartTx(can);
- }
- void CAN_Receive(CAN_TypeDef *can, CAN_RxMessageTypeDef *rx_msg)
- {
- CAN_WaitForRx(can);
- uint32_t rx_frame = can->RXFRAME;
- rx_msg->FF = rx_frame & CAN_FRAME_FF;
- rx_msg->RTR = rx_frame & CAN_FRAME_RTR;
- rx_msg->DLC = rx_frame & CAN_FRAME_DLC;
- if (rx_msg->RTR == CAN_REMOTE_FRAME) {
- rx_msg->DLC = 0;
- }
- int data_idx;
- if (rx_msg->FF == CAN_STANDARD_FRAME_FORMAT) {
- rx_msg->ID = (can->RXDATA[0] << 3 ) | (can->RXDATA[1] >> 5);
- data_idx = 2;
- } else { // CAN_EXTENDTED_FRAME_FORMAT
- rx_msg->ID = (can->RXDATA[0] << 21) | (can->RXDATA[1] << 13) | (can->RXDATA[2] << 5) | (can->RXDATA[3] >> 3);
- data_idx = 4;
- }
- for (unsigned int i = 0; i < rx_msg->DLC; ++i) {
- rx_msg->Data[i] = can->RXDATA[data_idx + i];
- }
- CAN_ReleaseRxBuffer(can);
- }
|