doubao_chat/apps/common/config/ci_transport_uart.c

226 lines
5.5 KiB
C

#include "system/includes.h"
#include "syscfg/config_interface.h"
#include "os/os_api.h"
#include "asm/uart_dev.h"
#include "asm/crc16.h"
#include "device/device.h"
#include "device/uart.h"
#include "app_config.h"
#define LOG_TAG "[CI-UART]"
/* #define LOG_ERROR_ENABLE */
/* #define LOG_INFO_ENABLE */
/* #define LOG_DUMP_ENABLE */
#include "debug.h"
#if TCFG_EQ_ONLINE_ENABLE
struct config_uart {
u32 baudrate;
int flowcontrol;
const char *dev_name;
};
struct uart_hdl {
struct config_uart config;
void *uart_dev;
u8 rx_type;
volatile u8 run_flag;
s16 data_length;
void *pTxBuffer;
void (*packet_handler)(const u8 *packet, int size);
};
typedef struct {
//head
u16 preamble;
u8 type;
u16 length;
u8 crc8;
u16 crc16;
u8 payload[0];
} _GNU_PACKED_ uart_packet_t;
#define UART_FORMAT_HEAD sizeof(uart_packet_t)
#define UART_PREAMBLE 0xBED6
#define UART_RX_SIZE 0x200
#define UART_TX_SIZE 0x200
static struct uart_hdl hdl;
#define __this (&hdl)
static u8 pTxBuffer_static[UART_TX_SIZE] __attribute__((aligned(4))); //tx memory
static void ci_data_rx_handler(u8 type)
{
u8 pRxBuffer[UART_RX_SIZE];
u16 crc16;
uart_packet_t *p;
__this->data_length = dev_read(__this->uart_dev, pRxBuffer, UART_RX_SIZE);
if (__this->data_length <= 0) {
/* log_e("ci_data_rx_handler err\n"); */
return;
}
/* log_info_hexdump(pRxBuffer, __this->data_length); */
if (__this->data_length <= UART_FORMAT_HEAD) {
return;
}
p = (uart_packet_t *)pRxBuffer;
if (p->preamble != UART_PREAMBLE) {
log_info("preamble err\n");
put_buf(pRxBuffer, __this->data_length);
goto reset_buf;
}
crc16 = CRC16(pRxBuffer, UART_FORMAT_HEAD - 3);
log_info("CRC8 0x%x / 0x%x", crc16, p->crc8);
if (p->crc8 != (crc16 & 0xff)) {
log_info("crc8 err\n");
goto reset_buf;
}
if (__this->data_length >= p->length + UART_FORMAT_HEAD) {
log_info("Total length : 0x%x / Rx length : 0x%x", __this->data_length, p->length + CI_FORMAT_HEAD);
crc16 = CRC16(p->payload, p->length);
/* log_info("CRC16 0x%x / 0x%x", crc16, p->crc16); */
if (p->crc16 != crc16) {
log_info("crc8 err\n");
goto reset_buf;
}
__this->packet_handler(p->payload, p->length);
}
reset_buf:
__this->data_length = 0;
}
static void ci_uart_write(void *buf, u16 len)
{
dev_write(__this->uart_dev, buf, len);
}
static void ci_dev_init(const void *config)
{
__this->pTxBuffer = pTxBuffer_static;
}
static void ci_transport_task(void *arg)
{
while (__this->run_flag) {
ci_data_rx_handler(0);
}
}
static int ci_dev_open(void)
{
static char uart_circlebuf[1 * 1024] __attribute__((aligned(32))); //串口循环数据buf,根据需要设置大小
int parm;
__this->uart_dev = dev_open("uart1", 0);
dev_ioctl(__this->uart_dev, UART_SET_CIRCULAR_BUFF_ADDR, (int)uart_circlebuf);
parm = sizeof(uart_circlebuf);
dev_ioctl(__this->uart_dev, UART_SET_CIRCULAR_BUFF_LENTH, (int)parm);
#if 0 // 是否设置为 接收完指定长度数据, spec_uart_recv才出来
parm = 1;
dev_ioctl(__this->uart_dev, UART_SET_RECV_ALL, (int)parm);
#endif
#if 1 // 是否设置为阻塞方式读
parm = 1;
dev_ioctl(__this->uart_dev, UART_SET_RECV_BLOCK, (int)parm);
#endif
parm = 1000;
dev_ioctl(__this->uart_dev, UART_SET_RECV_TIMEOUT, (u32)parm);
__this->run_flag = 1;
thread_fork("ci_transport_task", 11, 256 * 3, 0, 0, ci_transport_task, NULL);
dev_ioctl(__this->uart_dev, UART_START, (int)0);
return 0;
}
static int ci_dev_close(void)
{
__this->run_flag = 0;
dev_close(__this->uart_dev);
return 0;
}
static void ci_dev_register_packet_handler(void (*handler)(const u8 *packet, int size))
{
__this->packet_handler = handler;
}
static int ci_dev_send_packet(const u8 *packet, int size)
{
uart_packet_t *p = (uart_packet_t *)__this->pTxBuffer;
p->preamble = UART_PREAMBLE;
p->type = 0;
p->length = size;
p->crc8 = CRC16(p, UART_FORMAT_HEAD - 3) & 0xff;
p->crc16 = CRC16(packet, size);
size += UART_FORMAT_HEAD;
ASSERT(size <= UART_TX_SIZE, "Fatal Error");
memcpy(p->payload, packet, size);
log_info("Tx : %d", size);
put_buf((u8 *)p, size);
ci_uart_write(p, size);
return 0;
}
static int ci_dev_can_send_packet_now(uint8_t packet_type)
{
return 0;
}
// get dev api skeletons
static const ci_transport_t ci_transport_uart = {
/* const char * name; */ "CI_UART",
/* void (*init) (const void *transport_config); */ &ci_dev_init,
/* int (*open)(void); */ &ci_dev_open,
/* int (*close)(void); */ &ci_dev_close,
/* void (*register_packet_handler)(void (*handler)(...); */ &ci_dev_register_packet_handler,
/* int (*can_send_packet_now)(uint8_t packet_type); */ &ci_dev_can_send_packet_now,
/* int (*send_packet)(...); */ &ci_dev_send_packet,
};
const ci_transport_t *ci_transport_uart_instance(void)
{
return &ci_transport_uart;
}
static const ci_transport_config_uart_t config = {
CI_TRANSPORT_CONFIG_UART,
115200,
0,
0,
NULL,
};
static int config_online_init(void)
{
config_layer_init(ci_transport_uart_instance(), (void *)&config);
return 0;
}
__initcall(config_online_init);
#endif