| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- #include <stdio.h>
- #include <assert.h>
- #include "board.h"
- #include "hpm_can_drv.h"
- #include "hard_can.h"
- #include "test.h"
- // PD20 PD25 CAN2 调试使用
- #define CAN2 HPM_CAN2
- #define CAN2_IRQ IRQn_CAN2
- #define CAN2_CLK_NAME clock_can2
- #define BAUD_1000k (1000000)
- #define BAUD_500k (500000)
- void can_gpio_cofig(void)
- {
- HPM_IOC->PAD[IOC_PAD_PD20].FUNC_CTL = IOC_PD20_FUNC_CTL_CAN2_TXD;
- HPM_IOC->PAD[IOC_PAD_PD25].FUNC_CTL = IOC_PD25_FUNC_CTL_CAN2_RXD;
- }
- /**
- * @brief CAN1 硬件初始化 具体使用哪个CAN口配置
- * @param baudrate 波特率,如 500000 (500Kbps) 或 1000000 (1Mbps)
- */
- void CAN1_Mode_Init(uint32_t baudrate)
- {
- can_config_t can_config;
- can_filter_config_t can_filter;
- hpm_stat_t status;
- /* 配置IO 获取时钟*/
- can_gpio_cofig(); // 配置IO
- clock_set_source_divider(CAN2_CLK_NAME, clk_src_pll1_clk1, 5); //80M
- clock_add_to_group(CAN2_CLK_NAME, 0);
- uint32_t freq = clock_get_frequency(CAN2_CLK_NAME);
- /* 配置过滤器 - 接收所有消息 */
- can_filter.enable = true;
- can_filter.index = 0;
- can_filter.id_mode = can_filter_id_mode_both_frames; // 接收标准与扩展帧
- can_filter.code = 0; // 期望接收的报文ID的基础值
- can_filter.mask = 0x1FFFFFFF; // 关键点:掩码全部设为 1:忽略
- /* 默认配置并修改 */
- can_get_default_config(&can_config);
- can_config.baudrate = baudrate;
- can_config.mode = can_mode_normal;
-
- /* 使能中断 */
- // 接收事件 主发送缓冲器发送完成 次发送缓冲器发送完成 错误事件
- // 仲裁丢失错误 被动错误状态 总线错误
- can_config.irq_txrx_enable_mask = CAN_EVENT_RECEIVE |
- CAN_EVENT_TX_PRIMARY_BUF |
- CAN_EVENT_TX_SECONDARY_BUF |
- CAN_EVENT_ERROR;
- can_config.irq_error_enable_mask = CAN_ERROR_ARBITRATION_LOST_INT_ENABLE |
- CAN_ERROR_PASSIVE_INT_ENABLE |
- CAN_ERROR_BUS_ERROR_INT_ENABLE;
-
- /* 关联滤波器 */
- can_config.filter_list = &can_filter; // 最多可以给一个can配置16个滤波器 每个都有16路 牛逼
- can_config.filter_list_num = 1;
-
- /* 初始化 CAN */
- status = can_init(CAN2, &can_config, freq);
- if (status != status_success) {
- printf("CAN initialization failed, error code: %d\n", status);
- return;
- }
-
- /* 使能中断 */
- intc_m_enable_irq_with_priority(CAN2_IRQ, 1);
- printf("CAN0 initialized successfully at %d bps\n", baudrate);
- }
- #ifdef CAN2_TEST
- #include "hpm_sysctl_drv.h"
- static volatile bool has_new_rcv_msg;
- static volatile bool has_sent_out;
- static volatile bool has_error;
- static volatile can_receive_buf_t s_can_rx_buf;
- static volatile uint8_t error_flags;
- // 中断函数在soft can 那里
- #ifdef TEST_EN
- SDK_DECLARE_EXT_ISR_M(CAN2_IRQ, can2_isr)
- void can2_isr(void)
- {
- uint8_t flags = can_get_tx_rx_flags(CAN2);
- if ((flags & CAN_EVENT_RECEIVE) != 0) {
- can_read_received_message(CAN2, (can_receive_buf_t *)&s_can_rx_buf);
- has_new_rcv_msg = true;
- }
- if ((flags & (CAN_EVENT_TX_PRIMARY_BUF | CAN_EVENT_TX_SECONDARY_BUF))) {
- has_sent_out = true;
- }
- if ((flags & CAN_EVENT_ERROR) != 0) {
- has_error = true;
- }
- can_clear_tx_rx_flags(CAN2, flags);
- error_flags = can_get_error_interrupt_flags(CAN2);
- if (error_flags != 0) {
- has_error = true;
- }
- can_clear_error_interrupt_flags(CAN2, error_flags);
- }
- #endif
- static uint8_t can_get_data_bytes_from_dlc(uint32_t dlc)
- {
- uint32_t data_bytes = 0;
- dlc &= 0xFU;
- if (dlc <= 8U) {
- data_bytes = dlc;
- }
- else {
- switch (dlc) {
- case can_payload_size_12:
- data_bytes = 12U;
- break;
- case can_payload_size_16:
- data_bytes = 16U;
- break;
- case can_payload_size_20:
- data_bytes = 20U;
- break;
- case can_payload_size_24:
- data_bytes = 24U;
- break;
- case can_payload_size_32:
- data_bytes = 32U;
- break;
- case can_payload_size_48:
- data_bytes = 48U;
- break;
- case can_payload_size_64:
- data_bytes = 64U;
- break;
- default:
- /* Code should never touch here */
- break;
- }
- }
- return data_bytes;
- }
- static void show_received_can_message(const can_receive_buf_t *rx_msg)
- {
- uint32_t msg_len = can_get_data_bytes_from_dlc(rx_msg->dlc);
- printf("CAN message info:\nID=%08x\nContent=:\n", rx_msg->id);
- uint32_t remaining_size = msg_len;
- uint32_t print_size;
- for (uint32_t i = 0; i < msg_len; i += 16) {
- print_size = MIN(remaining_size, 16);
- for (uint32_t j = 0; j < print_size; j++) {
- printf("%02x ", rx_msg->data[i + j]);
- }
- printf("\n");
- remaining_size -= print_size;
- }
- }
- static void can_echo_test_responder(void)
- {
-
- hpm_stat_t status = 1;
- printf("CAN echo test: Responder is waiting for echo message...\n");
- while (!has_new_rcv_msg) {
- }
- has_new_rcv_msg = false;
- show_received_can_message((const can_receive_buf_t *)&s_can_rx_buf);
- can_transmit_buf_t tx_buf;
- memset(&tx_buf, 0, sizeof(tx_buf));
- tx_buf.dlc = s_can_rx_buf.dlc;
- tx_buf.id = 0x321;
- uint32_t msg_len = can_get_data_bytes_from_dlc(s_can_rx_buf.dlc);
- memcpy(&tx_buf.data, (uint8_t *)&s_can_rx_buf.data, msg_len);
- status = can_send_message_blocking(CAN2, &tx_buf);
- if (status != status_success) {
- printf("CAN sent message failed, error_code:%d\n", status);
- return;
- }
- printf("Sent echo message back\n");
- }
- static const char *get_can_error_kind_str(uint8_t error_kind)
- {
- const char *error_info_str = NULL;
- switch (error_kind) {
- case CAN_KIND_OF_ERROR_NO_ERROR:
- error_info_str = "No error";
- break;
- case CAN_KIND_OF_ERROR_BIT_ERROR:
- error_info_str = "Bit error";
- break;
- case CAN_KIND_OF_ERROR_FORM_ERROR:
- error_info_str = "Form error";
- break;
- case CAN_KIND_OF_ERROR_STUFF_ERROR:
- error_info_str = "Stuff error";
- break;
- case CAN_KIND_OF_ERROR_ACK_ERROR:
- error_info_str = "ACK error";
- break;
- case CAN_KIND_OF_ERROR_CRC_ERROR:
- error_info_str = "CRC error";
- break;
- case CAN_KIND_OF_ERROR_OTHER_ERROR:
- error_info_str = "Other errors";
- break;
- default:
- error_info_str = "Uknown error";
- break;
- }
- return error_info_str;
- }
- /* can2 demo test 2026/03/14 ok 扩展canid*/
- /*
- CAN message info:
- ID=00000001
- Content=:
- e2 80 00 00 00 fe fe 00
- Sent echo message back
- */
- void can2_test(void)
- {
- CAN1_Mode_Init(BAUD_1000k);
- board_delay_ms(3000);
- can_echo_test_responder();
- }
- #endif
|