soft_can.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "board.h"
  2. #include "soft_can.h"
  3. #include "hard_can.h"
  4. #include "params.h"
  5. #include "rkfifo.h"
  6. #include "soft_gs.h"
  7. #include "soft_time.h"
  8. #include "ver_config.h"
  9. #include "soft_can_yy.h"
  10. // 宏定义与hard can同步修改
  11. #define CAN2 HPM_CAN2
  12. #define CAN2_IRQ IRQn_CAN2
  13. #define CAN2_CLK_NAME clock_can2
  14. #define BAUD_1000k (1000000)
  15. #define BAUD_500k (500000)
  16. #define CAN_RX_FIFO_SIZE 16
  17. #define CAN_TX_FIFO_SIZE 16
  18. /* can 接收结构体 fifo */
  19. static can_receive_buf_t canRxMsgBuffer[CAN_RX_FIFO_SIZE] = {0};
  20. static rkfifo_t canRxFifo = {0};
  21. /* can 发送结构体 FIFO */
  22. static can_transmit_buf_t canTxMsgBuffer[CAN_TX_FIFO_SIZE] = {0};
  23. static rkfifo_t canTxFifo = {0};
  24. static void CAN_FilterConfig(void);
  25. /**
  26. * @brief can tx rx fifo 初始化
  27. *
  28. */
  29. static void canTxRxFifoInit(void)
  30. {
  31. rkfifo_init(&canRxFifo, &canRxMsgBuffer, sizeof(canRxMsgBuffer),
  32. sizeof(can_receive_buf_t));
  33. rkfifo_init(&canTxFifo, &canTxMsgBuffer, sizeof(canTxMsgBuffer),
  34. sizeof(can_transmit_buf_t));
  35. }
  36. /**
  37. * @brief CAN bus 总线初始化
  38. *
  39. */
  40. void CAN_BusInit(void)
  41. {
  42. canTxRxFifoInit();
  43. uint32_t baudrate = 1000 * 1000;
  44. CAN1_Mode_Init(baudrate);
  45. CAN_FilterConfig();
  46. }
  47. /**
  48. * @brief CAN 过滤器初始化
  49. *
  50. */
  51. void CAN_FilterConfig(void)
  52. {
  53. // 放在硬件CAN里去处理了
  54. }
  55. int canSendMsg(can_transmit_buf_t *pTxMsg)
  56. {
  57. int ret = 0;
  58. if (can_send_message_nonblocking(CAN2, pTxMsg) != status_success ) // 发送失败
  59. {
  60. if (rkfifo_in(&canTxFifo, pTxMsg, 1) != 1)
  61. {
  62. ret = -1;
  63. }
  64. }
  65. return ret;
  66. }
  67. int canSendVkMsg(unsigned char *data, unsigned char length, unsigned int extid,
  68. uint16_t time_out_ms)
  69. {
  70. // 计算总帧数
  71. unsigned char frame_num = (length - 1) / 8 + 1;
  72. uint32_t start_time = micros();
  73. uint8_t sequence = 0;
  74. int ret_val = 0;
  75. can_transmit_buf_t TxMessage;
  76. // 设置固定属性
  77. TxMessage.extend_id = 1; // 扩展帧
  78. TxMessage.remote_frame = 0; // 数据帧
  79. TxMessage.canfd_frame = 0; // 标准CAN,不是CANFD
  80. while (sequence < frame_num)
  81. {
  82. // 基于原始extid计算当前帧的ID
  83. uint32_t current_id = extid;
  84. // 添加帧标志
  85. if (sequence == 0)
  86. current_id |= CAN_MSG_STA; // 起始帧标志
  87. if (sequence == frame_num - 1)
  88. current_id |= CAN_MSG_END; // 结束帧标志
  89. // 添加序列号 (左移3位,保留3位空间给标志位)
  90. current_id = current_id | (sequence << 3);
  91. // 右移3位,去除标志位占用的低位
  92. current_id = current_id >> 3;
  93. // 确保是29位扩展ID (0x1FFFFFFF = 29位全1)
  94. TxMessage.id = current_id & 0x1FFFFFFF;
  95. // 扩展ID帧未使用标准ID
  96. // TxMessage.StdId = TxMessage.ExtId & 0x07FF0000;
  97. // 设置数据长度
  98. if (length - (sequence + 1) * 8 >= 0)
  99. TxMessage.dlc = 8;
  100. else
  101. TxMessage.dlc = length - sequence * 8;
  102. // 复制数据
  103. for (int i = 0; i < TxMessage.dlc; i++)
  104. {
  105. TxMessage.data[i] = *(data + sequence * 8 + i);
  106. }
  107. // 发送消息
  108. if (canSendMsg(&TxMessage) == 0)
  109. {
  110. sequence++;
  111. }
  112. // 超时检查
  113. if (micros() - start_time > time_out_ms * 1000)
  114. {
  115. ret_val = -1;
  116. break;
  117. }
  118. // 等待发送完成(如果需要)
  119. // while (!has_sent_out && (micros() - start_time <= time_out_ms * 1000));
  120. // has_sent_out = false;
  121. }
  122. return ret_val;
  123. }
  124. void CanTxRxServicePoll(void)
  125. {
  126. can_receive_buf_t msg;
  127. while (rkfifo_out(&canRxFifo, &msg, 1) == 1)
  128. {
  129. // YY_can_rx_decode(&msg);
  130. }
  131. YY_tx_loop();
  132. }
  133. static volatile bool has_sent_out;
  134. SDK_DECLARE_EXT_ISR_M(CAN2_IRQ, can2_isr)
  135. void can2_isr(void)
  136. {
  137. can_transmit_buf_t can_TxMessage;
  138. can_receive_buf_t can_RxMessage;
  139. uint8_t flags = can_get_tx_rx_flags(CAN2);
  140. /* 处理接收中断 */
  141. if ((flags & CAN_EVENT_RECEIVE) != 0) {
  142. /* 直接读取到应用层消息结构(现在就是HPM格式) */
  143. can_read_received_message(CAN2, &can_RxMessage);
  144. /* 存入FIFO */
  145. rkfifo_in(&canRxFifo, &can_RxMessage, 1);
  146. }
  147. /* 处理发送完成中断 */
  148. if ((flags & (CAN_EVENT_TX_PRIMARY_BUF | CAN_EVENT_TX_SECONDARY_BUF)) != 0) {
  149. /* 设置发送完成标志 */
  150. has_sent_out = true;
  151. /* 检查发送FIFO中是否有待发送消息 */
  152. if (rkfifo_out(&canTxFifo, &can_TxMessage, 1) == 1) {
  153. /* 直接发送(已经是HPM格式) */
  154. can_send_message_nonblocking(CAN2, &can_TxMessage);
  155. }
  156. }
  157. /* 清除发送接收标志 */
  158. can_clear_tx_rx_flags(CAN2, flags);
  159. /* 处理错误中断 */
  160. uint8_t error_flags = can_get_error_interrupt_flags(CAN2);
  161. if (error_flags != 0) {
  162. // 可以在这里处理错误
  163. can_clear_error_interrupt_flags(CAN2, error_flags);
  164. }
  165. }