can.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "can.h"
  2. void CAN_Filter_StructInit(CAN_FilterConfigTypeDef *init)
  3. {
  4. init->FilterMode = CAN_FILTER_SINGLE;
  5. for (int i = 0; i < 4; ++i) {
  6. init->FilterMask[i] = CAN_FILTER_DONT_CARE; // Accept message with any identifier
  7. init->FilterCode[i] = 0x00;
  8. }
  9. }
  10. // Single filter for standard frame format. Can match ID, RTR, and data bytes 1 and 2
  11. void CAN_SetStandardSingleFilter(CAN_FilterConfigTypeDef *init, uint16_t id_mask, uint16_t id_code,
  12. uint16_t data_mask, uint16_t data_code, uint8_t rtr_mask, uint8_t rtr_code)
  13. {
  14. init->FilterMode = CAN_FILTER_SINGLE;
  15. init->FilterMask[0] = id_mask >> 3;
  16. init->FilterCode[0] = id_code >> 3;
  17. init->FilterMask[1] = (id_mask << 5) | (rtr_mask ? (1 << 4) : 0);
  18. init->FilterCode[1] = (id_code << 5) | (rtr_code ? (1 << 4) : 0);
  19. init->FilterMask[2] = data_mask >> 8; // Data byte 1
  20. init->FilterCode[2] = data_code >> 8; // Data byte 1
  21. init->FilterMask[3] = data_mask; // Data byte 2
  22. init->FilterCode[3] = data_code; // Data byte 2
  23. }
  24. // Dual filter for standard frame format. Filter 0 can match ID, RTR, and data byte 1. Filter 2 can match ID and RTR
  25. void CAN_SetStandardDualFilter(CAN_FilterConfigTypeDef *init, uint16_t id_mask0, uint16_t id_code0,
  26. uint8_t data_mask0, uint8_t data_code0, uint8_t rtr_mask0, uint8_t rtr_code0,
  27. uint16_t id_mask1, uint16_t id_code1, uint8_t rtr_mask1, uint8_t rtr_code1)
  28. {
  29. init->FilterMode = CAN_FILTER_DUAL;
  30. init->FilterMask[0] = id_mask0 >> 3;
  31. init->FilterCode[0] = id_code0 >> 3;
  32. init->FilterMask[1] = (id_mask0 << 5) | (rtr_mask0 ? (1 << 4) : 0) | (data_mask0 >> 4);
  33. init->FilterCode[1] = (id_code0 << 5) | (rtr_code0 ? (1 << 4) : 0) | (data_code0 >> 4);
  34. init->FilterMask[2] = id_mask1 >> 3;
  35. init->FilterCode[2] = id_code1 >> 3;
  36. init->FilterMask[3] = (id_mask1 << 5) | (rtr_mask1 ? (1 << 4) : 0) | (data_mask0 & 0xf);
  37. init->FilterCode[3] = (id_code1 << 5) | (rtr_code1 ? (1 << 4) : 0) | (data_code0 & 0xf);
  38. }
  39. // Single filter for extended frame format. Can match ID and RTR
  40. void CAN_SetExtendedSingleFilter(CAN_FilterConfigTypeDef *init, uint32_t id_mask, uint32_t id_code,
  41. uint8_t rtr_mask, uint8_t rtr_code)
  42. {
  43. init->FilterMode = CAN_FILTER_SINGLE;
  44. init->FilterMask[0] = id_mask >> 21;
  45. init->FilterCode[0] = id_code >> 21;
  46. init->FilterMask[1] = id_mask >> 13;
  47. init->FilterCode[1] = id_code >> 13;
  48. init->FilterMask[2] = id_mask >> 5;
  49. init->FilterCode[2] = id_code >> 5;
  50. init->FilterMask[3] = (id_mask << 3) | (rtr_mask ? (1 << 2) : 0);
  51. init->FilterCode[3] = (id_code << 3) | (rtr_code ? (1 << 2) : 0);
  52. }
  53. // Dual filter for extended frame format. Each filter can match the upper 16 bits of the 29-bit ID
  54. void CAN_SetExtendedDualFilter(CAN_FilterConfigTypeDef *init, uint32_t id_mask0, uint32_t id_code0,
  55. uint32_t id_mask1, uint32_t id_code1)
  56. {
  57. init->FilterMode = CAN_FILTER_DUAL;
  58. init->FilterMask[0] = id_mask0 >> 21;
  59. init->FilterCode[0] = id_code0 >> 21;
  60. init->FilterMask[1] = id_mask0 >> 13;
  61. init->FilterCode[1] = id_code0 >> 13;
  62. init->FilterMask[2] = id_mask1 >> 21;
  63. init->FilterCode[2] = id_code1 >> 21;
  64. init->FilterMask[3] = id_mask1 >> 13;
  65. init->FilterCode[3] = id_code1 >> 13;
  66. }
  67. void CAN_StructInit(CAN_InitTypeDef *init)
  68. {
  69. init->Prescaler = 0;
  70. init->SJW = CAN_SJW_1TQ;
  71. init->TSeg1 = CAN_TSEG1_1TQ;
  72. init->TSeg2 = CAN_TSEG2_1TQ;
  73. init->Sampling = CAN_SAMPLING_1;
  74. CAN_Filter_StructInit(&init->FilterConfig);
  75. }
  76. void CAN_Init(CAN_TypeDef *can, CAN_InitTypeDef *init)
  77. {
  78. can->MOD = CAN_MOD_RESET;
  79. can->BTR0 = init->Prescaler | init->SJW;
  80. can->BTR1 = init->TSeg1 | init->TSeg2 | init->Sampling;
  81. for (int i = 0; i < 4; ++i) {
  82. can->AMR[i] = init->FilterConfig.FilterMask[i];
  83. can->ACR[i] = init->FilterConfig.FilterCode[i];
  84. }
  85. can->OCR = CAN_OUTPUT_MODE_NORMAL;
  86. can->RXERR = 0;
  87. can->TXERR = 0;
  88. can->MOD = init->FilterConfig.FilterMode; // Will also clear the reset bit
  89. }
  90. void CAN_PrepareTx(CAN_TypeDef *can, CAN_TxMessageTypeDef *tx_msg)
  91. {
  92. CAN_WaitForTx(can);
  93. can->TXFRAME = tx_msg->FF | tx_msg->RTR | tx_msg->DLC;
  94. int data_idx;
  95. if (tx_msg->FF == CAN_STANDARD_FRAME_FORMAT) {
  96. can->TXDATA[0] = (tx_msg->ID >> 3);
  97. can->TXDATA[1] = (tx_msg->ID << 5) | (tx_msg->RTR >> 2);
  98. data_idx = 2;
  99. } else { // CAN_EXTENDTED_FRAME_FORMAT
  100. can->TXDATA[0] = (tx_msg->ID >> 21);
  101. can->TXDATA[1] = (tx_msg->ID >> 13);
  102. can->TXDATA[2] = (tx_msg->ID >> 5);
  103. can->TXDATA[3] = (tx_msg->ID << 3) | (tx_msg->RTR >> 4);
  104. data_idx = 4;
  105. }
  106. for (unsigned int i = 0; i < tx_msg->DLC; ++i) {
  107. can->TXDATA[data_idx + i] = tx_msg->Data[i];
  108. }
  109. }
  110. void CAN_Transmit(CAN_TypeDef *can, CAN_TxMessageTypeDef *tx_msg)
  111. {
  112. CAN_PrepareTx(can, tx_msg);
  113. CAN_StartTx(can);
  114. }
  115. void CAN_Receive(CAN_TypeDef *can, CAN_RxMessageTypeDef *rx_msg)
  116. {
  117. CAN_WaitForRx(can);
  118. uint32_t rx_frame = can->RXFRAME;
  119. rx_msg->FF = rx_frame & CAN_FRAME_FF;
  120. rx_msg->RTR = rx_frame & CAN_FRAME_RTR;
  121. rx_msg->DLC = rx_frame & CAN_FRAME_DLC;
  122. if (rx_msg->RTR == CAN_REMOTE_FRAME) {
  123. rx_msg->DLC = 0;
  124. }
  125. int data_idx;
  126. if (rx_msg->FF == CAN_STANDARD_FRAME_FORMAT) {
  127. rx_msg->ID = (can->RXDATA[0] << 3 ) | (can->RXDATA[1] >> 5);
  128. data_idx = 2;
  129. } else { // CAN_EXTENDTED_FRAME_FORMAT
  130. rx_msg->ID = (can->RXDATA[0] << 21) | (can->RXDATA[1] << 13) | (can->RXDATA[2] << 5) | (can->RXDATA[3] >> 3);
  131. data_idx = 4;
  132. }
  133. for (unsigned int i = 0; i < rx_msg->DLC; ++i) {
  134. rx_msg->Data[i] = can->RXDATA[data_idx + i];
  135. }
  136. CAN_ReleaseRxBuffer(can);
  137. }