#include #include #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