KT24-1110_65E-HA-651B/apps/common/config/ci_transport_uart.c
2024-11-10 18:44:17 +08:00

351 lines
8.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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