123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- /*
- * Copyright (c) 2025 Wingcool Technology Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <soc.h>
- #include <board.h>
- #include <device.h>
- #include <drivers/uart.h>
- #include <aem_core_if.h>
- #include <logging/log.h>
- //#include <gps/gps.h>
- LOG_MODULE_REGISTER(uart2_rec, LOG_LEVEL_INF);
- #define CONFIG_UART2_REC_DEV_NAME "uart2_rec"
- #define UART2_REC_DEV_NAME CONFIG_UART_2_NAME
- #define UART_FIFO_MAX 256
- #define REC_DATA_BUFFER_SIZE 256
- #define PRODUCT_INFO_SIZE 64
- #define WRITE_KEY_SIZE 160
- // 定义命令
- #define DEVICE_ID_CMD 0xB1
- #define PROJECT_ID_CMD 0xB2
- #define WRITE_KEY_CMD 0xB3
- #define IS_KEY_INSIDE_CMD 0xB4
- #define SET_TIME_CMD 0xC1
- // 定义帧头和帧尾
- #define FRAME_HEADER1 0xAA
- #define FRAME_HEADER2 0x55
- #define FRAME_TAIL1 0x55
- #define FRAME_TAIL2 0xAA
- struct uart2_rec_data {
- const struct device *uart_gpio_dev;
- uint8_t rec_data[REC_DATA_BUFFER_SIZE];
- //gps_notify_t notify;
- };
- static struct uart2_rec_data uart2_rec_data;
- uint8_t bySetTimeStep = 0;
- extern uint8_t bySetHour;
- extern uint8_t bySetMinute;
- extern uint8_t bySetWeekday;
- extern uint16_t wSetYear;
- extern uint8_t bySetMonth;
- extern uint8_t bySetDay;
- extern void uart2_poll_out_ch(int c); // UART2发送一个字节
- extern bool aem_read_aem_key_record(aem_key_w_record_t *record); // 读取AEM KEY记录
- extern bool aem_defender_factory_write_key(uint8_t * data, uint16_t len); // 写入KEY
- extern uint16_t aem_factory_get_product_info(uint8_t *data, uint16_t in_len); // 获取产品信息
- // 计算累加和校验值
- //1 字节,对命令码、数据长度和数据内容的所有字节进行累加求和,取低8位作为校验值,用于检测数据在传输过程中是否出错
- uint8_t calculate_checksum(uint8_t cmd, uint8_t *data, uint8_t data_len)
- {
- uint8_t checksum = cmd + data_len;
- for (uint8_t i = 0; i < data_len; i++) {
- checksum += data[i];
- }
- return checksum;
- }
- // 发送一帧数据
- void send_frame(uint8_t cmd, uint8_t *data, uint8_t data_len)
- {
- uint8_t checksum = calculate_checksum(cmd, data, data_len);
- // 发送帧头
- uart2_poll_out_ch(FRAME_HEADER1);
- uart2_poll_out_ch(FRAME_HEADER2);
- // 发送命令码
- uart2_poll_out_ch(cmd);
- // 发送数据长度
- uart2_poll_out_ch(data_len);
- // 发送数据内容
- for (uint8_t i = 0; i < data_len; i++) {
- uart2_poll_out_ch(data[i]);
- }
- // 发送累加和校验值
- uart2_poll_out_ch(checksum);
- // 发送帧尾
- uart2_poll_out_ch(FRAME_TAIL1);
- uart2_poll_out_ch(FRAME_TAIL2);
- }
- // 检查一帧数据是否正确
- bool check_receive_frame(uint8_t *data)
- {
- uint8_t calculated_checksum;
- uint8_t data_len = data[3];
- // 帧头
- if (data[0] != FRAME_HEADER1)
- {
- return false; // 帧头错误
- }
- if (data[1] != FRAME_HEADER2)
- {
- return false; // 帧头错误
- }
-
- // 计算本地累加和校验值
- calculated_checksum = calculate_checksum(data[2], data + 4, data_len);
-
- if (data[data_len + 4] != calculated_checksum) {
- return false; // 累加和校验错误
- }
- // 读取帧尾
- if (data[data_len + 5] != FRAME_TAIL1 || data[data_len + 6] != FRAME_TAIL2) {
- return false; // 帧尾错误
- }
- return true; // 接收成功
- }
- static uint8_t byAACnt = 2;
- static bool bReceiveFrameDone = false;
- static void uart_fifo_callback(const struct device *dev, void *user_data)
- {
- uint8_t rx_buff[UART_FIFO_MAX];
- uint8_t tx_buff[UART_FIFO_MAX];
- int read_size;
- static uint8_t cnt;
- aem_key_w_record_t *key_record = NULL;
- printk("uart_fifo_callback start\n");
- uart_irq_update(dev);
- if (uart_irq_rx_ready(dev)) {
- read_size = uart_fifo_read(dev, rx_buff, UART_FIFO_MAX);
- printk("read_size: %d\n", read_size);
- if (read_size == UART_FIFO_MAX)
- printk("uart fifo buffer overflow\n");
- for (int i = 0; i < read_size; i++)
- {
- switch (rx_buff[i]) {
- case FRAME_HEADER1:
- byAACnt++;
- if (byAACnt > 2)
- {
- byAACnt = 1;
- cnt = 0;
- bReceiveFrameDone = false;
- }
- else if (byAACnt == 2)
- {
- bReceiveFrameDone = true;
- }
- uart2_rec_data.rec_data[cnt++] = rx_buff[i];
- break;
-
- default:
- uart2_rec_data.rec_data[cnt++] = rx_buff[i];
- /* protection data cannot exceed boundary */
- if (cnt >= REC_DATA_BUFFER_SIZE)
- cnt--;
- break;
- }
- }
- if (bReceiveFrameDone && check_receive_frame(uart2_rec_data.rec_data))
- {
- printk("receive frame success\n");
- switch (uart2_rec_data.rec_data[2])
- {
- case DEVICE_ID_CMD:
- aem_factory_get_product_info(tx_buff, PRODUCT_INFO_SIZE);
- send_frame(PROJECT_ID_CMD, tx_buff, PRODUCT_INFO_SIZE);
- break;
- case PROJECT_ID_CMD:
- tx_buff[0] = 0x0F;
- tx_buff[1] = 0x6B;
- tx_buff[2] = 0x3B;
- tx_buff[3] = 0xD8;
- send_frame(PROJECT_ID_CMD, tx_buff, 4);
- break;
- case WRITE_KEY_CMD:
- //uart_fifo_fill(dev,rx_buff,read_size);
-
- tx_buff[0] = 0;
- if (aem_defender_factory_write_key(uart2_rec_data.rec_data, WRITE_KEY_SIZE))
- {
- tx_buff[0] = 0xAA;
- }
- send_frame(WRITE_KEY_CMD, tx_buff, 1);
- break;
- case IS_KEY_INSIDE_CMD:
- tx_buff[0] = 0;
- aem_read_aem_key_record(key_record);
- if (key_record != NULL)
- {
- if (key_record->is_pass)
- tx_buff[0] = 0xAA;
- }
- send_frame(IS_KEY_INSIDE_CMD, tx_buff, 1);
- break;
- case SET_TIME_CMD:
- bySetMinute = uart2_rec_data.rec_data[4];
- bySetHour = uart2_rec_data.rec_data[5];
- bySetDay = uart2_rec_data.rec_data[6];
- bySetWeekday = uart2_rec_data.rec_data[7];
- bySetMonth = uart2_rec_data.rec_data[8];
- wSetYear = uart2_rec_data.rec_data[9];
- bySetTimeStep = 1;
- send_frame(SET_TIME_CMD, tx_buff, 0);
- break;
- default:
- break;
- }
- }
- }
- }
- /*
- static void uart2_rec_enable(const struct device *dev)
- {
- struct uart2_rec_data *data = (struct uart2_rec_data *)dev->data;
- printk("uart2_rec_enable\n");
- uart_irq_rx_enable(data->uart_gpio_dev);
- }
- static void uart2_rec_disable(const struct device *dev)
- {
- struct uart2_rec_data *data = (struct uart2_rec_data *)dev->data;
-
- printk("uart2_rec_disable\n");
- uart_irq_rx_disable(data->uart_gpio_dev);
- }
- static void uart2_rec_register_notify(const struct device *dev, gps_notify_t notify)
- {
- printk("uart2_rec_register_notify\n");
- struct uart2_rec_data *data = (struct uart2_rec_data *)dev->data;
- data->notify = notify;
- }
- static void uart2_rec_unregister_notify(const struct device *dev, gps_notify_t notify)
- {
- struct uart2_rec_data *data = (struct uart2_rec_data *)dev->data;
- data->notify = NULL;
- }
- static const struct gps_dev_driver_api uart2_rec_api = {
- .enable = uart2_rec_enable,
- .disable = uart2_rec_disable,
- .inquiry = NULL,
- .register_notify = uart2_rec_register_notify,
- .unregister_notify = uart2_rec_unregister_notify,
- };
- */
- static int uart2_rec_init(const struct device *dev)
- {
- struct uart2_rec_data *data = (struct uart2_rec_data *)dev->data;
- printk("uart2_rec_init\n");
- data->uart_gpio_dev = device_get_binding(UART2_REC_DEV_NAME);
- if (data->uart_gpio_dev == NULL) {
- printk("Couldn't find uart2\n");
- return -ENODEV;
- }
- uart_irq_callback_set(data->uart_gpio_dev, uart_fifo_callback);
-
- uart_irq_rx_enable(data->uart_gpio_dev);
- return 0;
- }
- #if IS_ENABLED(CONFIG_UART_ACTS)
- DEVICE_DEFINE(uart2_rec, CONFIG_UART2_REC_DEV_NAME, &uart2_rec_init, NULL, &uart2_rec_data, NULL, POST_KERNEL, 60, NULL);
- #endif
|