初版
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".ci_transport_uart.data.bss")
|
||||
#pragma data_seg(".ci_transport_uart.data")
|
||||
#pragma const_seg(".ci_transport_uart.text.const")
|
||||
#pragma code_seg(".ci_transport_uart.text")
|
||||
#endif
|
||||
#include "system/includes.h"
|
||||
#include "config/config_interface.h"
|
||||
#include "system/event.h"
|
||||
#include "app_online_cfg.h"
|
||||
#include "uart.h"
|
||||
#include "app_config.h"
|
||||
#include "asm/crc16.h"
|
||||
#include "cfg_tool.h"
|
||||
#include "app_msg.h"
|
||||
|
||||
#define LOG_TAG "[CI-UART]"
|
||||
/* #define LOG_ERROR_ENABLE */
|
||||
/* #define LOG_INFO_ENABLE */
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#include "debug.h"
|
||||
|
||||
extern u16 crc_get_16bit(const void *src, u32 len);
|
||||
|
||||
#if (TCFG_ONLINE_ENABLE || TCFG_CFG_TOOL_ENABLE)
|
||||
struct config_uart {
|
||||
u32 baudrate;
|
||||
int flowcontrol;
|
||||
const char *dev_name;
|
||||
};
|
||||
|
||||
struct uart_hdl {
|
||||
|
||||
struct config_uart config;
|
||||
|
||||
int 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;
|
||||
u16 length;
|
||||
u8 type;
|
||||
u8 sq;
|
||||
u8 payload[0];
|
||||
} _GNU_PACKED_ uart_tool_packet_t;
|
||||
|
||||
#define UART_TOOL_FORMAT_HEAD sizeof(uart_tool_packet_t)
|
||||
|
||||
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 0x500
|
||||
#define UART_TX_SIZE 0x30
|
||||
#define UART_DB_SIZE 0x500
|
||||
#define UART_BAUD_RATE 115200
|
||||
|
||||
/* #define HAVE_MALLOC */
|
||||
#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
|
||||
|
||||
s16 get_ci_tx_size()
|
||||
{
|
||||
return UART_TX_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取工具串口最大支持的协议包大小
|
||||
*/
|
||||
u16 get_ci_rx_size()
|
||||
{
|
||||
return UART_RX_SIZE;
|
||||
}
|
||||
|
||||
static u8 procotol = 0;
|
||||
void ci_data_rx_handler(u8 type)
|
||||
{
|
||||
u16 crc16;
|
||||
uart_tool_packet_t *p_newtool;
|
||||
uart_packet_t *p;
|
||||
|
||||
__this->rx_type = type;
|
||||
|
||||
if (type == CI_UART && __this->udev) {
|
||||
int bytes_read = uart_recv_bytes(__this->udev, &__this->pRxBuffer[__this->data_length], (UART_RX_SIZE - __this->data_length)); //串口读取buf剩余空间的长度,实际长度比buf长,导致越界改写问题
|
||||
if (bytes_read > 0) {
|
||||
__this->data_length += bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
procotol = 1;
|
||||
break;
|
||||
} else if (tmp_buf[i] == 0xD6 && tmp_buf[i + 1] == 0xBE) {
|
||||
procotol = 0;
|
||||
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 (procotol) {
|
||||
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 + 7)) {
|
||||
// crc校验统一放到业务层处理
|
||||
/* crc16 = crc_get_16bit(&p_newtool->length, p_newtool->length + 2); */
|
||||
/* log_info("CRC16 0x%x / 0x%x", crc16, p_newtool->crc16); */
|
||||
/* if (p_newtool->crc16 != crc16) { */
|
||||
/* log_error("crc16 err\n"); */
|
||||
/* goto reset_buf; */
|
||||
/* } */
|
||||
/* printf("cfg_tool rx:\n"); */
|
||||
/* log_info_hexdump((u8 *)p_newtool, p_newtool->length + 7); */
|
||||
online_cfg_tool_data_deal(p_newtool, p_newtool->length + 7);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (__this->data_length <= UART_FORMAT_HEAD) {
|
||||
return;
|
||||
}
|
||||
p = __this->pRxBuffer;
|
||||
|
||||
if (p->preamble != UART_PREAMBLE) {
|
||||
log_info("preamble err\n");
|
||||
log_info_hexdump(__this->pRxBuffer, __this->data_length);
|
||||
goto reset_buf;
|
||||
}
|
||||
|
||||
crc16 = crc_get_16bit(__this->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 = crc_get_16bit(p->payload, p->length);
|
||||
/* log_info("CRC16 0x%x / 0x%x", crc16, p->crc16); */
|
||||
if (p->crc16 != crc16) {
|
||||
log_info("crc16 err\n");
|
||||
goto reset_buf;
|
||||
}
|
||||
__this->packet_handler(p->payload, p->length);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
reset_buf:
|
||||
__this->data_length = 0;
|
||||
}
|
||||
|
||||
static void ci_uart_isr_cb(int uart_num, enum uart_event event)
|
||||
{
|
||||
|
||||
os_taskq_post_type("app_core", MSG_FROM_CI_UART, 0, NULL);
|
||||
}
|
||||
|
||||
static int ci_data_rx_handler_entry(int *msg)
|
||||
{
|
||||
ci_data_rx_handler(CI_UART);
|
||||
return 0;
|
||||
}
|
||||
|
||||
APP_MSG_HANDLER(ci_uart_msg_entry) = {
|
||||
.owner = 0xff,
|
||||
.from = MSG_FROM_CI_UART,
|
||||
.handler = ci_data_rx_handler_entry,
|
||||
};
|
||||
|
||||
static int ci_uart_init()
|
||||
{
|
||||
/* JL_CLOCK->CLK_CON1 |= BIT(11); */
|
||||
/* JL_CLOCK->CLK_CON1 &= ~BIT(10); */
|
||||
__this->data_length = 0;
|
||||
|
||||
struct uart_config config = {
|
||||
.baud_rate = __this->config.baudrate,
|
||||
.tx_pin = TCFG_ONLINE_TX_PORT,
|
||||
.rx_pin = TCFG_ONLINE_RX_PORT,
|
||||
};
|
||||
struct uart_dma_config dma = {
|
||||
.rx_timeout_thresh = 1000,
|
||||
.frame_size = UART_DB_SIZE,
|
||||
.event_mask = UART_EVENT_RX_DATA | UART_EVENT_RX_TIMEOUT | UART_EVENT_RX_FIFO_OVF,
|
||||
.irq_callback = ci_uart_isr_cb,
|
||||
.rx_cbuffer = __this->dbuf,
|
||||
.rx_cbuffer_size = UART_DB_SIZE,
|
||||
};
|
||||
__this->udev = uart_init(-1, &config);
|
||||
if (__this->udev < 0) {
|
||||
log_error("open uart dev err\n");
|
||||
__this->udev = -1;
|
||||
return -1;
|
||||
}
|
||||
uart_dma_init(__this->udev, &dma);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ci_uart_putbyte(char a)
|
||||
{
|
||||
if (__this->udev != -1) {
|
||||
uart_putbyte(__this->udev, a);
|
||||
}
|
||||
}
|
||||
|
||||
void ci_uart_write(u8 *buf, u16 len)
|
||||
{
|
||||
if (__this->udev != -1) {
|
||||
uart_send_bytes(__this->udev, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void dummy_handler(const u8 *packet, int size)
|
||||
{
|
||||
log_error("Dummy");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 = dma_malloc(UART_RX_SIZE);
|
||||
ASSERT(__this->pRxBuffer, "Fatal error");
|
||||
|
||||
__this->pTxBuffer = dma_malloc(UART_TX_SIZE);
|
||||
ASSERT(__this->pTxBuffer, "Fatal error");
|
||||
|
||||
__this->dbuf = dma_malloc(UART_DB_SIZE);
|
||||
ASSERT(__this->dbuf, "Fatal error");
|
||||
#else
|
||||
log_info("Static");
|
||||
__this->pRxBuffer = pRxBuffer_static;
|
||||
__this->pTxBuffer = pTxBuffer_static;
|
||||
__this->dbuf = devBuffer_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"); */
|
||||
if (size > UART_TX_SIZE) {
|
||||
log_e("Fatal Error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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((u8 *)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
|
||||
|
||||
Reference in New Issue
Block a user