hard_can.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. //SDK_DECLARE_EXT_ISR_M(CAN2_IRQ, can2_isr)
  74. //void can2_isr(void)
  75. //{
  76. // uint8_t flags = can_get_tx_rx_flags(CAN2);
  77. // if ((flags & CAN_EVENT_RECEIVE) != 0) {
  78. // can_read_received_message(CAN2, (can_receive_buf_t *)&s_can_rx_buf);
  79. // has_new_rcv_msg = true;
  80. // }
  81. // if ((flags & (CAN_EVENT_TX_PRIMARY_BUF | CAN_EVENT_TX_SECONDARY_BUF))) {
  82. // has_sent_out = true;
  83. // }
  84. // if ((flags & CAN_EVENT_ERROR) != 0) {
  85. // has_error = true;
  86. // }
  87. // can_clear_tx_rx_flags(CAN2, flags);
  88. // error_flags = can_get_error_interrupt_flags(CAN2);
  89. // if (error_flags != 0) {
  90. // has_error = true;
  91. // }
  92. // can_clear_error_interrupt_flags(CAN2, error_flags);
  93. //}
  94. static uint8_t can_get_data_bytes_from_dlc(uint32_t dlc)
  95. {
  96. uint32_t data_bytes = 0;
  97. dlc &= 0xFU;
  98. if (dlc <= 8U) {
  99. data_bytes = dlc;
  100. }
  101. else {
  102. switch (dlc) {
  103. case can_payload_size_12:
  104. data_bytes = 12U;
  105. break;
  106. case can_payload_size_16:
  107. data_bytes = 16U;
  108. break;
  109. case can_payload_size_20:
  110. data_bytes = 20U;
  111. break;
  112. case can_payload_size_24:
  113. data_bytes = 24U;
  114. break;
  115. case can_payload_size_32:
  116. data_bytes = 32U;
  117. break;
  118. case can_payload_size_48:
  119. data_bytes = 48U;
  120. break;
  121. case can_payload_size_64:
  122. data_bytes = 64U;
  123. break;
  124. default:
  125. /* Code should never touch here */
  126. break;
  127. }
  128. }
  129. return data_bytes;
  130. }
  131. static void show_received_can_message(const can_receive_buf_t *rx_msg)
  132. {
  133. uint32_t msg_len = can_get_data_bytes_from_dlc(rx_msg->dlc);
  134. printf("CAN message info:\nID=%08x\nContent=:\n", rx_msg->id);
  135. uint32_t remaining_size = msg_len;
  136. uint32_t print_size;
  137. for (uint32_t i = 0; i < msg_len; i += 16) {
  138. print_size = MIN(remaining_size, 16);
  139. for (uint32_t j = 0; j < print_size; j++) {
  140. printf("%02x ", rx_msg->data[i + j]);
  141. }
  142. printf("\n");
  143. remaining_size -= print_size;
  144. }
  145. }
  146. static void can_echo_test_responder(void)
  147. {
  148. hpm_stat_t status = 1;
  149. printf("CAN echo test: Responder is waiting for echo message...\n");
  150. while (!has_new_rcv_msg) {
  151. }
  152. has_new_rcv_msg = false;
  153. show_received_can_message((const can_receive_buf_t *)&s_can_rx_buf);
  154. can_transmit_buf_t tx_buf;
  155. memset(&tx_buf, 0, sizeof(tx_buf));
  156. tx_buf.dlc = s_can_rx_buf.dlc;
  157. tx_buf.id = 0x321;
  158. uint32_t msg_len = can_get_data_bytes_from_dlc(s_can_rx_buf.dlc);
  159. memcpy(&tx_buf.data, (uint8_t *)&s_can_rx_buf.data, msg_len);
  160. status = can_send_message_blocking(CAN2, &tx_buf);
  161. if (status != status_success) {
  162. printf("CAN sent message failed, error_code:%d\n", status);
  163. return;
  164. }
  165. printf("Sent echo message back\n");
  166. }
  167. static const char *get_can_error_kind_str(uint8_t error_kind)
  168. {
  169. const char *error_info_str = NULL;
  170. switch (error_kind) {
  171. case CAN_KIND_OF_ERROR_NO_ERROR:
  172. error_info_str = "No error";
  173. break;
  174. case CAN_KIND_OF_ERROR_BIT_ERROR:
  175. error_info_str = "Bit error";
  176. break;
  177. case CAN_KIND_OF_ERROR_FORM_ERROR:
  178. error_info_str = "Form error";
  179. break;
  180. case CAN_KIND_OF_ERROR_STUFF_ERROR:
  181. error_info_str = "Stuff error";
  182. break;
  183. case CAN_KIND_OF_ERROR_ACK_ERROR:
  184. error_info_str = "ACK error";
  185. break;
  186. case CAN_KIND_OF_ERROR_CRC_ERROR:
  187. error_info_str = "CRC error";
  188. break;
  189. case CAN_KIND_OF_ERROR_OTHER_ERROR:
  190. error_info_str = "Other errors";
  191. break;
  192. default:
  193. error_info_str = "Uknown error";
  194. break;
  195. }
  196. return error_info_str;
  197. }
  198. /* can2 demo test 2026/03/14 ok 扩展canid*/
  199. /*
  200. CAN message info:
  201. ID=00000001
  202. Content=:
  203. e2 80 00 00 00 fe fe 00
  204. Sent echo message back
  205. */
  206. void can2_test(void)
  207. {
  208. CAN1_Mode_Init(BAUD_1000k);
  209. board_delay_ms(3000);
  210. can_echo_test_responder();
  211. }
  212. #endif