KT24-1110_65E-HA-651B/apps/common/config/ci_transport_uart.c

351 lines
8.8 KiB
C
Raw Permalink Normal View History

2024-11-10 10:44:17 +00:00
#include "system/includes.h"
#include "config/config_interface.h"
#include "system/event.h"
#include "app_online_cfg.h"
#include "asm/uart_dev.h"
#include "app_config.h"
#include "app_sound_box_tool.h"
#define LOG_TAG "[CI-UART]"
/* #define LOG_ERROR_ENABLE */
/* #define LOG_INFO_ENABLE */
/* #define LOG_DUMP_ENABLE */
#include "debug.h"
#if (TCFG_ONLINE_ENABLE || TCFG_SOUNDBOX_TOOL_ENABLE)
struct config_uart {
u32 baudrate;
int flowcontrol;
const char *dev_name;
};
struct uart_hdl {
struct config_uart config;
uart_bus_t *udev;
void *dbuf;
void *pRxBuffer;
u8 ucRxIndex;
u8 rx_type;
u16 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)
typedef struct {
//head
u16 preamble0;
u8 preamble1;
u16 crc16;
u8 length;
u8 type;
u8 sq;
u8 payload[0];
} _GNU_PACKED_ uart_tool_packet_t;
#define UART_TOOL_FORMAT_HEAD sizeof(uart_tool_packet_t)
extern u16 crc_get_16bit(const void *src, u32 len);
static void dummy_handler(const u8 *packet, int size);
#define UART_PREAMBLE 0xBED6
#define UART_NEW_TOOL_PREAMBLE0 0xAA5A
#define UART_NEW_TOOL_PREAMBLE1 0xA5
#define UART_RX_SIZE 0x100
#define UART_TX_SIZE 0x30
#define UART_DB_SIZE 0x100
#define UART_BAUD_RATE 115200
#ifdef HAVE_MALLOC
static struct uart_hdl *hdl;
#define __this (hdl)
#else
static struct uart_hdl hdl;
#define __this (&hdl)
static u8 pRxBuffer_static[UART_RX_SIZE] __attribute__((aligned(4))); //rx memory
static u8 pTxBuffer_static[UART_TX_SIZE] __attribute__((aligned(4))); //tx memory
static u8 devBuffer_static[UART_DB_SIZE] __attribute__((aligned(4))); //dev DMA memory
#endif
void ci_data_rx_handler(u8 type)
{
u16 crc16;
uart_tool_packet_t *p_newtool;
__this->rx_type = type;
if (type == CI_UART && __this->udev) {
__this->data_length += __this->udev->read(&__this->pRxBuffer[__this->data_length], (UART_RX_SIZE - __this->data_length), 0);//串口读取buf剩余空间的长度实际长度比buf长导致越界改写问题
}
/* log_info("Rx : %d", __this->data_length); */
/* log_info_hexdump(__this->pRxBuffer, __this->data_length); */
if (__this->data_length > UART_RX_SIZE) {
log_error("Wired");
}
u8 *tmp_buf = NULL;
tmp_buf = __this->pRxBuffer;
if (__this->data_length >= 2) {
unsigned i = 0;
for (i = 0; i < __this->data_length - 1; ++i) {
if ((tmp_buf[i] == 0x5A) && (tmp_buf[i + 1] == 0xAA) && (tmp_buf[i + 2] == 0xA5)) {
break;
}
}
if (i != 0) {
__this->data_length -= i;
/* printf("__this->data_length %d i %d\n", __this->data_length, i); */
if (__this->data_length > 0) {
memmove(&__this->pRxBuffer[0], &tmp_buf[i], __this->data_length);
}
}
}
if (__this->data_length <= UART_TOOL_FORMAT_HEAD) {
return;
}
p_newtool = __this->pRxBuffer;
if ((p_newtool->preamble0 != UART_NEW_TOOL_PREAMBLE0) || (p_newtool->preamble1 != UART_NEW_TOOL_PREAMBLE1)) {
log_error("preamble err\n");
log_info_hexdump(__this->pRxBuffer, __this->data_length);
goto reset_buf;
}
if (__this->data_length >= p_newtool->length + 6) {
crc16 = crc_get_16bit(&p_newtool->length, p_newtool->length + 1);
/* log_info("CRC16 0x%x / 0x%x", crc16, p_newtool->crc16); */
if (p_newtool->crc16 != crc16) {
log_error("crc16 err\n");
log_info_hexdump(__this->pRxBuffer, __this->data_length);
goto reset_buf;
}
/* log_info_hexdump(p_newtool, p_newtool->length + 6); */
online_cfg_tool_data_deal(p_newtool, p_newtool->length + 6);
} else {
return;
}
reset_buf:
__this->data_length = 0;
}
static void ci_uart_isr_cb(void *ut_bus, u32 status)
{
if (status == UT_TX) {
return ;
}
struct sys_event e;
e.type = SYS_DEVICE_EVENT;
e.arg = (void *)DEVICE_EVENT_FROM_CI_UART;
e.u.dev.event = 0;
e.u.dev.value = 0;
sys_event_notify(&e);
}
static int ci_uart_init()
{
struct uart_platform_data_t ut = {0};
ut.tx_pin = TCFG_ONLINE_TX_PORT;
ut.rx_pin = TCFG_ONLINE_RX_PORT;
ut.baud = __this->config.baudrate;
ut.rx_timeout = 1;
ut.isr_cbfun = ci_uart_isr_cb;
ut.rx_cbuf = devBuffer_static;
ut.rx_cbuf_size = UART_DB_SIZE;
ut.frame_length = UART_DB_SIZE;
/* JL_CLOCK->CLK_CON1 |= BIT(11); */
/* JL_CLOCK->CLK_CON1 &= ~BIT(10); */
__this->dbuf = devBuffer_static;
__this->data_length = 0;
__this->udev = (uart_bus_t *)uart_dev_open(&ut);
if (__this->udev == NULL) {
log_error("open uart dev err\n");
return -1;
}
return 0;
}
static void ci_uart_putbyte(char a)
{
if (__this->udev) {
__this->udev->putbyte(a);
}
}
void ci_uart_write(char *buf, u16 len)
{
if (__this->udev) {
__this->udev->write(buf, len);
}
}
static void dummy_handler(const u8 *packet, int size)
{
log_error("Dummy");
}
static void clock_critical_enter(void)
{
}
static void clock_critical_exit(void)
{
if (__this->udev) {
__this->udev->set_baud(__this->config.baudrate);
}
}
CLOCK_CRITICAL_HANDLE_REG(ci, clock_critical_enter, clock_critical_exit)
static void ci_dev_init(const void *config)
{
#ifdef HAVE_MALLOC
__this = malloc(sizeof(struct uart_hdl));
ASSERT(__this, "Fatal error");
memset(__this, 0x0, sizeof(struct uart_hdl));
__this->pRxBuffer = malloc(UART_RX_SIZE);
ASSERT(__this->pRxBuffer, "Fatal error");
__this->pTxBuffer = malloc(UART_TX_SIZE);
ASSERT(__this->pTxBuffer, "Fatal error");
#else
log_info("Static");
__this->pRxBuffer = pRxBuffer_static;
__this->pTxBuffer = pTxBuffer_static;
#endif
__this->packet_handler = dummy_handler;
ci_transport_config_uart_t *ci_config_uart = (ci_transport_config_uart_t *)config;
__this->config.baudrate = ci_config_uart->baudrate_init;
__this->config.flowcontrol = ci_config_uart->flowcontrol;
__this->config.dev_name = ci_config_uart->device_name;
log_info("baudrate : %d", __this->config.baudrate);
log_info("flowcontrol: %d", __this->config.flowcontrol);
}
static int ci_dev_open(void)
{
ci_uart_init();
return 0;
}
static int ci_dev_close(void)
{
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)
{
/* dev_stream_out(); */
int i = 0;
uart_packet_t *p = (uart_packet_t *)__this->pTxBuffer;
p->preamble = UART_PREAMBLE;
p->type = 0;
p->length = size;
p->crc8 = crc_get_16bit(p, UART_FORMAT_HEAD - 3) & 0xff;
p->crc16 = crc_get_16bit(packet, size);
size += UART_FORMAT_HEAD;
ASSERT(size <= UART_TX_SIZE, "Fatal Error");
memcpy(p->payload, packet, size);
/* log_info("Tx : %d", size); */
/* log_info_hexdump(p, size); */
if (__this->rx_type == CI_UART) {
#if 0
while (size--) {
ci_uart_putbyte(((char *)p)[i++]);
}
#else
ci_uart_write(p, size);
#endif
}
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;
}
#endif
#ifdef CONFIG_AC608N
//该函数在蓝牙库实现608没有蓝牙库在此重定义
u16 crc_get_16bit(const void *src, u32 len)
{
/* log_info(__func__); */
u8 *p = (u8 *)src;
u16 ret;
OS_SR_ALLOC();
// vm_mutex_enter();
OS_ENTER_CRITICAL();
JL_CRC->REG = 0 ;
while (len--) {
JL_CRC->FIFO = *p++;
}
__asm__ volatile("csync");
ret = JL_CRC->REG;
OS_EXIT_CRITICAL();
// vm_mutex_exit();
/* printf("CRC16 %02x\r\n", ret); */
return ret;
}
#endif