hard_can.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include "board.h"
  4. #include "hpm_can_drv.h"
  5. #include "hard_can.h"
  6. #include "test.h"
  7. // PD20 PD25 CAN2 调试使用
  8. #define CAN2 HPM_CAN2
  9. #define CAN2_IRQ IRQn_CAN2
  10. #define CAN2_CLK_NAME clock_can2
  11. #define BAUD_1000k (1000000)
  12. #define BAUD_500k (500000)
  13. void can_gpio_cofig(void)
  14. {
  15. HPM_IOC->PAD[IOC_PAD_PD20].FUNC_CTL = IOC_PD20_FUNC_CTL_CAN2_TXD;
  16. HPM_IOC->PAD[IOC_PAD_PD25].FUNC_CTL = IOC_PD25_FUNC_CTL_CAN2_RXD;
  17. }
  18. /**
  19. * @brief CAN1 硬件初始化 具体使用哪个CAN口配置
  20. * @param baudrate 波特率,如 500000 (500Kbps) 或 1000000 (1Mbps)
  21. */
  22. void CAN1_Mode_Init(uint32_t baudrate)
  23. {
  24. can_config_t can_config;
  25. can_filter_config_t can_filter;
  26. hpm_stat_t status;
  27. /* 配置IO 获取时钟*/
  28. can_gpio_cofig(); // 配置IO
  29. clock_set_source_divider(CAN2_CLK_NAME, clk_src_pll1_clk1, 5); //80M
  30. clock_add_to_group(CAN2_CLK_NAME, 0);
  31. uint32_t freq = clock_get_frequency(CAN2_CLK_NAME);
  32. /* 配置过滤器 - 接收所有消息 */
  33. can_filter.enable = true;
  34. can_filter.index = 0;
  35. can_filter.id_mode = can_filter_id_mode_both_frames; // 接收标准与扩展帧
  36. can_filter.code = 0; // 期望接收的报文ID的基础值
  37. can_filter.mask = 0x1FFFFFFF; // 关键点:掩码全部设为 1:忽略
  38. /* 默认配置并修改 */
  39. can_get_default_config(&can_config);
  40. can_config.baudrate = baudrate;
  41. can_config.mode = can_mode_normal;
  42. /* 使能中断 */
  43. // 接收事件 主发送缓冲器发送完成 次发送缓冲器发送完成 错误事件
  44. // 仲裁丢失错误 被动错误状态 总线错误
  45. can_config.irq_txrx_enable_mask = CAN_EVENT_RECEIVE |
  46. CAN_EVENT_TX_PRIMARY_BUF |
  47. CAN_EVENT_TX_SECONDARY_BUF |
  48. CAN_EVENT_ERROR;
  49. can_config.irq_error_enable_mask = CAN_ERROR_ARBITRATION_LOST_INT_ENABLE |
  50. CAN_ERROR_PASSIVE_INT_ENABLE |
  51. CAN_ERROR_BUS_ERROR_INT_ENABLE;
  52. /* 关联滤波器 */
  53. can_config.filter_list = &can_filter; // 最多可以给一个can配置16个滤波器 每个都有16路 牛逼
  54. can_config.filter_list_num = 1;
  55. /* 初始化 CAN */
  56. status = can_init(CAN2, &can_config, freq);
  57. if (status != status_success) {
  58. printf("CAN initialization failed, error code: %d\n", status);
  59. return;
  60. }
  61. /* 使能中断 */
  62. intc_m_enable_irq_with_priority(CAN2_IRQ, 1);
  63. printf("CAN0 initialized successfully at %d bps\n", baudrate);
  64. }
  65. #ifdef CAN2_TEST
  66. #include "hpm_sysctl_drv.h"
  67. static volatile bool has_new_rcv_msg;
  68. static volatile bool has_sent_out;
  69. static volatile bool has_error;
  70. static volatile can_receive_buf_t s_can_rx_buf;
  71. static volatile uint8_t error_flags;
  72. // 中断函数在soft can 那里
  73. #ifdef TEST_EN
  74. SDK_DECLARE_EXT_ISR_M(CAN2_IRQ, can2_isr)
  75. void can2_isr(void)
  76. {
  77. uint8_t flags = can_get_tx_rx_flags(CAN2);
  78. if ((flags & CAN_EVENT_RECEIVE) != 0) {
  79. can_read_received_message(CAN2, (can_receive_buf_t *)&s_can_rx_buf);
  80. has_new_rcv_msg = true;
  81. }
  82. if ((flags & (CAN_EVENT_TX_PRIMARY_BUF | CAN_EVENT_TX_SECONDARY_BUF))) {
  83. has_sent_out = true;
  84. }
  85. if ((flags & CAN_EVENT_ERROR) != 0) {
  86. has_error = true;
  87. }
  88. can_clear_tx_rx_flags(CAN2, flags);
  89. error_flags = can_get_error_interrupt_flags(CAN2);
  90. if (error_flags != 0) {
  91. has_error = true;
  92. }
  93. can_clear_error_interrupt_flags(CAN2, error_flags);
  94. }
  95. #endif
  96. static uint8_t can_get_data_bytes_from_dlc(uint32_t dlc)
  97. {
  98. uint32_t data_bytes = 0;
  99. dlc &= 0xFU;
  100. if (dlc <= 8U) {
  101. data_bytes = dlc;
  102. }
  103. else {
  104. switch (dlc) {
  105. case can_payload_size_12:
  106. data_bytes = 12U;
  107. break;
  108. case can_payload_size_16:
  109. data_bytes = 16U;
  110. break;
  111. case can_payload_size_20:
  112. data_bytes = 20U;
  113. break;
  114. case can_payload_size_24:
  115. data_bytes = 24U;
  116. break;
  117. case can_payload_size_32:
  118. data_bytes = 32U;
  119. break;
  120. case can_payload_size_48:
  121. data_bytes = 48U;
  122. break;
  123. case can_payload_size_64:
  124. data_bytes = 64U;
  125. break;
  126. default:
  127. /* Code should never touch here */
  128. break;
  129. }
  130. }
  131. return data_bytes;
  132. }
  133. static void show_received_can_message(const can_receive_buf_t *rx_msg)
  134. {
  135. uint32_t msg_len = can_get_data_bytes_from_dlc(rx_msg->dlc);
  136. printf("CAN message info:\nID=%08x\nContent=:\n", rx_msg->id);
  137. uint32_t remaining_size = msg_len;
  138. uint32_t print_size;
  139. for (uint32_t i = 0; i < msg_len; i += 16) {
  140. print_size = MIN(remaining_size, 16);
  141. for (uint32_t j = 0; j < print_size; j++) {
  142. printf("%02x ", rx_msg->data[i + j]);
  143. }
  144. printf("\n");
  145. remaining_size -= print_size;
  146. }
  147. }
  148. static void can_echo_test_responder(void)
  149. {
  150. hpm_stat_t status = 1;
  151. printf("CAN echo test: Responder is waiting for echo message...\n");
  152. while (!has_new_rcv_msg) {
  153. }
  154. has_new_rcv_msg = false;
  155. show_received_can_message((const can_receive_buf_t *)&s_can_rx_buf);
  156. can_transmit_buf_t tx_buf;
  157. memset(&tx_buf, 0, sizeof(tx_buf));
  158. tx_buf.dlc = s_can_rx_buf.dlc;
  159. tx_buf.id = 0x321;
  160. uint32_t msg_len = can_get_data_bytes_from_dlc(s_can_rx_buf.dlc);
  161. memcpy(&tx_buf.data, (uint8_t *)&s_can_rx_buf.data, msg_len);
  162. status = can_send_message_blocking(CAN2, &tx_buf);
  163. if (status != status_success) {
  164. printf("CAN sent message failed, error_code:%d\n", status);
  165. return;
  166. }
  167. printf("Sent echo message back\n");
  168. }
  169. static const char *get_can_error_kind_str(uint8_t error_kind)
  170. {
  171. const char *error_info_str = NULL;
  172. switch (error_kind) {
  173. case CAN_KIND_OF_ERROR_NO_ERROR:
  174. error_info_str = "No error";
  175. break;
  176. case CAN_KIND_OF_ERROR_BIT_ERROR:
  177. error_info_str = "Bit error";
  178. break;
  179. case CAN_KIND_OF_ERROR_FORM_ERROR:
  180. error_info_str = "Form error";
  181. break;
  182. case CAN_KIND_OF_ERROR_STUFF_ERROR:
  183. error_info_str = "Stuff error";
  184. break;
  185. case CAN_KIND_OF_ERROR_ACK_ERROR:
  186. error_info_str = "ACK error";
  187. break;
  188. case CAN_KIND_OF_ERROR_CRC_ERROR:
  189. error_info_str = "CRC error";
  190. break;
  191. case CAN_KIND_OF_ERROR_OTHER_ERROR:
  192. error_info_str = "Other errors";
  193. break;
  194. default:
  195. error_info_str = "Uknown error";
  196. break;
  197. }
  198. return error_info_str;
  199. }
  200. /* can2 demo test 2026/03/14 ok 扩展canid*/
  201. /*
  202. CAN message info:
  203. ID=00000001
  204. Content=:
  205. e2 80 00 00 00 fe fe 00
  206. Sent echo message back
  207. */
  208. void can2_test(void)
  209. {
  210. CAN1_Mode_Init(BAUD_1000k);
  211. board_delay_ms(3000);
  212. can_echo_test_responder();
  213. }
  214. #endif