#include "can_task.h" #include "can_interface.h" #include "hal_math.h" #include "iap.h" #include "queue.h" #include "utils.h" #include #include queue_entry(pdu_tag, 40) can_rx_queue; queue_entry(pdu_tag, 40) can_tx_queue; uint8_t recv_can_id; static uint64_t base_data; void data_bit_move(uint8_t start_bit, uint8_t bit_len, uint64_t data) { uint64_t mask = 0; uint64_t source_data = (uint64_t)data; mask = hal_pow(2, bit_len) - 1; base_data |= (mask & source_data) << start_bit; } void product_array(uint8_t send_array[8]) { send_array[0] = (uint8_t)base_data; send_array[1] = (uint8_t)(base_data >> 8); send_array[2] = (uint8_t)(base_data >> 16); send_array[3] = (uint8_t)(base_data >> 24); send_array[4] = (uint8_t)(base_data >> 32); send_array[5] = (uint8_t)(base_data >> 40); send_array[6] = (uint8_t)(base_data >> 48); send_array[7] = (uint8_t)(base_data >> 56); base_data = 0; } uint8_t push_can_message_to_queue(uint32_t id, uint8_t len, uint8_t *p_data) { pdu_tag response_msg; QUEUE_STATUS result_status; response_msg.id.r = id; response_msg.reg.dlc = len; memcpy(&response_msg.data.u8_buf[0], p_data, len); if (id > 0x7FF) { response_msg.reg.ide = CAN_ID_EXT; } else { response_msg.reg.ide = CAN_ID_STD; } __disable_irq(); en_queue(&can_tx_queue, response_msg, result_status); __enable_irq(); if (result_status != Q_OK) { return 0; } return 1; } static uint8_t can_tx_frame(pdu_tag can_message) { can_write(can_message.id.r, can_message.reg.ide, can_message.data.u8_buf, can_message.reg.dlc); return 1; } void can_tx_callback(void) { pdu_tag tx_data; QUEUE_STATUS result_status; de_queue(&can_tx_queue, tx_data, result_status); // 返回值为1代表读取成功 if (result_status == Q_OK) { can_tx_frame(tx_data); CAN_IT_TME_ENABLE(); } else { CAN_IT_TME_DISABLE(); } } void can_rx_callback(CAN_RxHeaderTypeDef rx_header, uint8_t *buff) { pdu_tag data; uint8_t ps; uint8_t pf; QUEUE_STATUS result; switch (rx_header.ExtId) { case 0x18011801: data.id.r = 0x18011801; data.reg.dlc = rx_header.DLC; memcpy(&data.data.u8_buf[0], buff, rx_header.DLC); en_queue(&can_rx_queue, data, result); break; default: pf = (rx_header.ExtId & CAN_PGN_PF) >> 16; if (pf >= 0xF0) { data.id.r = rx_header.ExtId; recv_can_id = data.id.b.sa; memcpy(&data.data.u8_buf[0], buff, rx_header.DLC); en_queue(&can_rx_queue, data, result); } else { ps = (rx_header.ExtId & CAN_PGN_PS) >> 8; if (ps == 0xF4) { data.id.r = rx_header.ExtId; recv_can_id = data.id.b.sa; data.reg.dlc = rx_header.DLC; memcpy(&data.data.u8_buf[0], buff, rx_header.DLC); if (data.id.b.pf == 0xDF) { en_queue(&can_rx_queue, data, result); } else { en_queue(&can_rx_queue, data, result); } } else { memcpy(&data.data.u8_buf[0], buff, rx_header.DLC); en_queue(&can_rx_queue, data, result); if (result == 1) { return; } } } } } uint8_t tx_flag = 0; void can_rx_update(pdu_tag rec_msg) { if ((rec_msg.data.u8_buf[0] == 'A') && (rec_msg.data.u8_buf[1] == 'P') && (rec_msg.data.u8_buf[2] == 'P') && (rec_msg.data.u8_buf[3] == 'L') && (rec_msg.data.u8_buf[4] == 'O') && (rec_msg.data.u8_buf[5] == 'A') && (rec_msg.data.u8_buf[6] == 'D') && (rec_msg.data.u8_buf[7] == 0x01)) { __set_FAULTMASK(1); // 关闭所有中断 NVIC_SystemReset(); // 复位 } } can_rx_tab can_tab[] = {{0x18DFF4E1, iap_rec_handler}}; void can_start_send(void) { pdu_tag tx_msg; QUEUE_STATUS result_status; if (0 == ((CAN_IER) & 0x1)) { de_queue(&can_tx_queue, tx_msg, result_status); if (result_status == Q_OK) // 返回值为1代表读取成功 { can_tx_frame(tx_msg); CAN_IT_TME_ENABLE(); } } } static void can_rx_process(void) { uint8_t i; uint8_t flg = 0; pdu_tag rec_msg; QUEUE_STATUS result; for (uint8_t j = 0; j < 15; j++) { __disable_irq(); de_queue(&can_rx_queue, rec_msg, result); __enable_irq(); if (Q_OK == result) { for (i = 0; i < ARR_SIZE(can_tab); i++) { if (can_tab[i].id == rec_msg.id.r) { can_tab[i].p_func(rec_msg); flg = 1; break; } else if (can_tab[i].id == (uint32_t)(rec_msg.id.b.pf << 8 | rec_msg.id.b.ps)) { can_tab[i].p_func(rec_msg); flg = 1; break; } else if (can_tab[i].id == rec_msg.id.b.pf) { can_tab[i].p_func(rec_msg); flg = 1; break; } } if (flg == 0) { // j1939_msg_push_queue(&rec_msg); } flg = 0; } } } void can_tx_0x18010023_message(void) { uint8_t send_data[8] = {0}; data_bit_move(0, 8, 'A'); data_bit_move(8, 8, 'A'); data_bit_move(16, 8, 'A'); data_bit_move(24, 8, 'C'); data_bit_move(32, 8, 'A'); data_bit_move(40, 8, '-'); data_bit_move(48, 8, 'A'); data_bit_move(56, 8, 'B'); product_array(send_data); push_can_message_to_queue(0x18010023, 8, send_data); } void can_tx_0x18180003_message(void) { uint8_t data[8] = {0}; data_bit_move(0, 16, 0); data_bit_move(16, 16, 0x2710); data_bit_move(32, 16, 0x4E20); data_bit_move(48, 16, 0x7530); product_array(data); push_can_message_to_queue(0x18190006, 8, data); } void can_tx_0x18190007_message(void) { uint8_t data[8] = {0}; data_bit_move(0, 16, 0xDFFF); data_bit_move(16, 16, 0xF000); data_bit_move(32, 16, 0xE800); data_bit_move(48, 16, 0xE13D); product_array(data); push_can_message_to_queue(0x18190005, 8, data); } void can_tx_0x18190009_message(void) { uint8_t data[8] = {0}; data_bit_move(0, 16, 0xDFFF); data_bit_move(16, 16, 0xF000); data_bit_move(32, 16, 0xE800); data_bit_move(48, 16, 0xE13D); product_array(data); push_can_message_to_queue(0x18190005, 0, data); } void send_message(void) { static volatile uint8_t times = 0; if (times >= 100) { times = 0; } if (times % 100 == 0) { // can_tx_0x18010001_message(); // can_tx_0x18010002_message(); // can_tx_0x18010004_message(); // can_tx_0x18010005_message(); } else if (times % 100 == 5) { // can_tx_0x18010006_message(); // can_tx_0x18010007_message(); // can_tx_0x18010008_message(); // can_tx_0x18010009_message(); // can_tx_0x1801000A_message(); } else if (times % 100 == 10) { // can_tx_0x1801000B_message(); // can_tx_0x1801000C_message(); // can_tx_0x1801000D_message(); // can_tx_0x18010023_message(); // can_tx_0x18010010_message(); } else if (times % 100 == 15) { // can_tx_0x18010018_message(); // can_tx_0x18010019_message(); // can_tx_0x1801001A_message(); // can_tx_0x1801001B_message(); // can_tx_0x1801001C_message(); } else if (times % 100 == 20) { // can_tx_0x1801001D_message(); // can_tx_0x1801000F_message(); // can_tx_0x18030003_message(); // can_tx_0x18030001_message(); // can_tx_0x18010000_message(); } else if (times % 100 == 25) { // can_tx_0x18010017_message(); // can_tx_0x18010012_message(); // can_tx_0x18011802_message(); // can_tx_0x18011803_message(); // can_tx_0x18011803_2_message(); can_tx_0x18180003_message(); can_tx_0x18190007_message(); } else { // return; } times++; } void can_network_init(void) { queue_init(&can_rx_queue); queue_init(&can_tx_queue); can_rx_back_init(can_rx_callback); can_tx_back_init(can_tx_callback); } void can_process(void) { can_rx_process(); send_message(); can_start_send(); }