#include "oem_portmisc.h"
static cyg_io_handle_t ser_hndl;
static char stack[UART_READ_TASK_STACK_SZ];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;
static char pf_stack[PARSE_TASK_STACK_SZ];
static cyg_thread pf_thread_data;
static cyg_handle_t pf_thread_handle;
/* Mailbox的结构是一个FIFO类型的循环队列,存储的是指针 */
/* Search "cyg_mbox_create fifo" in baidu for more info */
static cyg_handle_t uart_mbox_h;
static cyg_mbox uart_mbox;
static cyg_mutex_t uart_mutex;
static u8 ring_buf[MSG_SZ * NR_MSG];
static u32 rb_write_seq = 0;
static u32 rb_read_seq = 0;
#define rb_lock() do { \
cyg_mutex_lock(&uart_mutex); \
} while (0)
#define rb_unlock() do { \
cyg_mutex_unlock(&uart_mutex); \
} while (0)
static bool snd_data(const u8 *data)
{
if (uart_mbox_h && cyg_mbox_tryput(uart_mbox_h, (void *)data)) {
return true;
}
return false;
}
void *uart_get_data(void)
{
if (uart_mbox_h) {
return cyg_mbox_get(uart_mbox_h);
}
return NULL;
}
static void push_msg(u8 *msg)
{
u32 offset;
if (!msg) {
return;
}
rb_lock();
offset = (rb_write_seq & (NR_MSG - 1)) * MSG_SZ;
memcpy(&(ring_buf[offset]), msg, MSG_SZ);
rb_write_seq++;
if ((rb_write_seq - rb_read_seq) > NR_MSG) {
rb_read_seq = rb_write_seq - NR_MSG;
}
rb_unlock();
}
static bool pull_msg(u8 *msg)
{
u32 offset;
if (!msg) {
return false;
}
rb_lock();
if (rb_read_seq == rb_write_seq) {
rb_unlock();
return false;
}
offset = (rb_read_seq & (NR_MSG - 1)) * MSG_SZ;
memcpy(msg, &(ring_buf[offset]), MSG_SZ);
rb_read_seq++;
rb_unlock();
return true;
}
static void uart_read_task(cyg_addrword_t data)
{
u8 frame[MSG_SZ];
u8 i;
u32 nread;
u32 ret = 0;
diag_printf("[OEM][%s] enter uart_read_task\n", __func__);
while (1) {
rx_2bytes_hdr:
i = 0;
while (i < 1) {
nread = 1;
ret = cyg_io_read(ser_hndl, &frame[i], &nread);
if (ENOERR != ret) {
continue;
}
if (frame[i] != 0x55) {
continue;
}
i++;
break;
}
while (i < 2) {
nread = 1;
ret = cyg_io_read(ser_hndl, &frame[i], &nread);
if (ENOERR != ret) {
continue;
}
if (frame[i] != 0x5A) {
goto rx_2bytes_hdr;
}
i++;
break;
}
while (i < MSG_SZ) {
nread = MSG_SZ - i;
ret = cyg_io_read(ser_hndl, &frame[i], &nread);
if (ENOERR != ret) {
continue;
}
i += nread;
}
push_msg(frame);
}
diag_printf("[OEM][%s] finished\n", __func__);
}
static void parse_frame_task(cyg_addrword_t data)
{
u8 frame[MSG_SZ];
u8 i;
while (1) {
if (pull_msg(frame)) {
#if defined(DEBUG)
for (i = 0; i < MSG_SZ; i++) {
diag_printf("%02x ", frame[i]);
}
diag_printf("\n");
#endif
cyg_thread_delay(100);
}
}
}
void uart_init(void)
{
int ret;
// fuelgauge uart config
cyg_serial_info_t serial_info =
CYG_SERIAL_INFO_INIT(CYGNUM_SERIAL_BAUD_4800,
CYGNUM_SERIAL_STOP_1,
CYGNUM_SERIAL_PARITY_EVEN,
CYGNUM_SERIAL_WORD_LENGTH_8,
0 );
cyg_uint32 size = sizeof(serial_info);
cyg_mbox_create(&uart_mbox_h, &uart_mbox);
cyg_mutex_init(&uart_mutex);
ret = cyg_io_lookup(FG_UART, &ser_hndl);
if (ret != ENOERR) {
diag_printf("[OEM] failed to opening \"%s\"\n", FG_UART);
return 0;
}
ret = cyg_io_set_config(ser_hndl, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &size);
if (ret != ENOERR)
diag_printf("[OEM] set_config flow_control returned an error\n");
diag_printf("[OEM] succeeded in opening \"%s\"\n", FG_UART);
cyg_thread_create(UART_READ_TASK_PRIORITY, // Priority - just a number
uart_read_task, // entry
0, // entry parameter
"uart_read_task", // Name
&stack[0], // Stack
UART_READ_TASK_STACK_SZ, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle); // Start it
#if 1
// Decode frame thread
cyg_thread_create(PARSE_TASK_PRIORITY, // Priority - just a number
parse_frame_task, // entry
0, // entry parameter
"parse_frame_task", // Name
&pf_stack[0], // Stack
PARSE_TASK_STACK_SZ, // Size
&pf_thread_handle, // Handle
&pf_thread_data // Thread data structure
);
cyg_thread_resume(pf_thread_handle); // Start it
#endif
}
module_init(uart_init);
07-27
7150
