added async buffers for uart0, maybe improved byte drop ratio
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "uart_driver.h"
|
||||
#include "cgi_sockets.h"
|
||||
#include "version.h"
|
||||
#include "uart_buffer.h"
|
||||
|
||||
/**
|
||||
* Send a response to UART0
|
||||
@@ -18,7 +19,8 @@
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_respond(const char *str)
|
||||
{
|
||||
UART_WriteString(UART0, str, UART_TIMEOUT_US);
|
||||
UART_SendAsync(str, -1);
|
||||
//UART_WriteString(UART0, str, UART_TIMEOUT_US);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,10 @@ enum ASCII_CODES {
|
||||
US = 31,
|
||||
SP = 32,
|
||||
DEL = 127,
|
||||
|
||||
// aliases
|
||||
XON = DC1,
|
||||
XOFF = DC3,
|
||||
};
|
||||
|
||||
#endif //ESP_VT100_FIRMWARE_ASCII_H
|
||||
|
||||
+4
-3
@@ -5,6 +5,7 @@
|
||||
#include "cgi_sockets.h"
|
||||
#include "uart_driver.h"
|
||||
#include "screen.h"
|
||||
#include "uart_buffer.h"
|
||||
|
||||
#define SOCK_BUF_LEN 1024
|
||||
static char sock_buff[SOCK_BUF_LEN];
|
||||
@@ -113,13 +114,13 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
|
||||
|
||||
if (strstarts(data, "STR:")) {
|
||||
// pass string verbatim
|
||||
UART_WriteString(UART0, data+4, UART_TIMEOUT_US);
|
||||
UART_SendAsync(data+4, -1);
|
||||
}
|
||||
else if (strstarts(data, "BTN:")) {
|
||||
// send button as low ASCII value 1-9
|
||||
int btnNum = data[4] - '0';
|
||||
u8 btnNum = (u8) (data[4] - '0');
|
||||
if (btnNum > 0 && btnNum < 10) {
|
||||
UART_WriteChar(UART0, (unsigned char)btnNum, UART_TIMEOUT_US);
|
||||
UART_SendAsync((const char *) &btnNum, 1);
|
||||
}
|
||||
}
|
||||
else if (strstarts(data, "TAP:")) {
|
||||
|
||||
+8
-2
@@ -30,7 +30,7 @@ static void buf_pop(void *unused)
|
||||
lb_ls++;
|
||||
if (lb_ls >= LOGBUF_SIZE) lb_ls = 0;
|
||||
|
||||
if (OK == UART_WriteCharCRLF(UART1, logbuf[lb_ls], 2000)) {
|
||||
if (OK == UART_WriteCharCRLF(UART1, logbuf[lb_ls], 1000)) {
|
||||
quantity--;
|
||||
} else {
|
||||
// try another time
|
||||
@@ -40,6 +40,11 @@ static void buf_pop(void *unused)
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL void my_putc(char c)
|
||||
{
|
||||
UART_WriteCharCRLF(UART1, (u8) c, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the serial ports
|
||||
*/
|
||||
@@ -50,8 +55,9 @@ void ICACHE_FLASH_ATTR serialInitBase(void)
|
||||
UART_SetParity(UART1, PARITY_NONE);
|
||||
UART_SetStopBits(UART1, ONE_STOP_BIT);
|
||||
UART_SetBaudrate(UART1, BIT_RATE_115200);
|
||||
//UART_SetPrintPort(UART1);
|
||||
UART_SetPrintPort(UART1);
|
||||
os_install_putc1(buf_putc);
|
||||
//os_install_putc1(my_putc);
|
||||
UART_SetupAsyncReceiver();
|
||||
|
||||
// 1 ms timer
|
||||
|
||||
+35
-27
@@ -8,7 +8,7 @@
|
||||
#include <esp8266.h>
|
||||
#include <uart_register.h>
|
||||
|
||||
#define UART_TX_BUFFER_SIZE 512 //Ring buffer length of tx buffer
|
||||
#define UART_TX_BUFFER_SIZE 256 //Ring buffer length of tx buffer
|
||||
#define UART_RX_BUFFER_SIZE 512 //Ring buffer length of rx buffer
|
||||
|
||||
struct UartBuffer {
|
||||
@@ -83,7 +83,6 @@ static void UART_WriteToAsyncBuffer(struct UartBuffer *pCur, const char *pdata,
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize);
|
||||
pCur->Space -= (data_len - tail_len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -98,6 +97,11 @@ void ICACHE_FLASH_ATTR UART_FreeAsyncBuffer(struct UartBuffer *pBuff)
|
||||
os_free(pBuff);
|
||||
}
|
||||
|
||||
u16 ICACHE_FLASH_ATTR UART_AsyncRxCount(void)
|
||||
{
|
||||
return (u16) (pRxBuffer->UartBuffSize - pRxBuffer->Space);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve some data from the RX buffer
|
||||
* @param pdata - target
|
||||
@@ -139,6 +143,7 @@ UART_ReadAsync(char *pdata, uint16 data_len)
|
||||
pRxBuffer->Space += len_tmp;
|
||||
}
|
||||
}
|
||||
// this maybe shouldnt be here??
|
||||
if (pRxBuffer->Space >= UART_FIFO_LEN) {
|
||||
uart_rx_intr_enable(UART0);
|
||||
}
|
||||
@@ -146,13 +151,13 @@ UART_ReadAsync(char *pdata, uint16 data_len)
|
||||
}
|
||||
|
||||
//move data from uart fifo to rx buffer
|
||||
void UART_RxFifoDeq(void)
|
||||
void UART_RxFifoCollect(void)
|
||||
{
|
||||
uint8 fifo_len, buf_idx;
|
||||
uint8 fifo_data;
|
||||
fifo_len = (uint8) ((READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT);
|
||||
if (fifo_len >= pRxBuffer->Space) {
|
||||
os_printf("buf full!!!\n\r");
|
||||
UART_WriteChar(UART1, '%', 100);
|
||||
}
|
||||
else {
|
||||
buf_idx = 0;
|
||||
@@ -165,8 +170,8 @@ void UART_RxFifoDeq(void)
|
||||
}
|
||||
}
|
||||
pRxBuffer->Space -= fifo_len;
|
||||
|
||||
if (pRxBuffer->Space >= UART_FIFO_LEN) {
|
||||
//os_printf("after rx enq buf enough\n\r");
|
||||
uart_rx_intr_enable(UART0);
|
||||
}
|
||||
}
|
||||
@@ -175,29 +180,32 @@ void UART_RxFifoDeq(void)
|
||||
/**
|
||||
* Schedule data to be sent
|
||||
* @param pdata
|
||||
* @param data_len
|
||||
* @param data_len - can be -1 for strlen
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SendAsync(char *pdata, uint16 data_len)
|
||||
UART_SendAsync(const char *pdata, int16_t data_len)
|
||||
{
|
||||
if (pTxBuffer == NULL) {
|
||||
info("\n\rnull, create buffer struct\n\r");
|
||||
pTxBuffer = UART_AsyncBufferInit(UART_TX_BUFFER_SIZE);
|
||||
if (pTxBuffer != NULL) {
|
||||
UART_WriteToAsyncBuffer(pTxBuffer, pdata, data_len);
|
||||
u16 real_len = (u16) data_len;
|
||||
if (data_len <= 0) real_len = (u16) strlen(pdata);
|
||||
|
||||
// if (pTxBuffer == NULL) {
|
||||
// printf("init tx buf\n\r");
|
||||
// pTxBuffer = UART_AsyncBufferInit(UART_TX_BUFFER_SIZE);
|
||||
// if (pTxBuffer != NULL) {
|
||||
// UART_WriteToAsyncBuffer(pTxBuffer, pdata, real_len);
|
||||
// }
|
||||
// else {
|
||||
// printf("tx alloc fail\r\n");
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
if (real_len <= pTxBuffer->Space) {
|
||||
UART_WriteToAsyncBuffer(pTxBuffer, pdata, real_len);
|
||||
}
|
||||
else {
|
||||
error("uart tx MALLOC no buf \n\r");
|
||||
UART_WriteChar(UART1, '^', 100);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (data_len <= pTxBuffer->Space) {
|
||||
UART_WriteToAsyncBuffer(pTxBuffer, pdata, data_len);
|
||||
}
|
||||
else {
|
||||
error("UART TX BUF FULL!!!!\n\r");
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
// Here we enable TX empty interrupt that will take care of sending the content
|
||||
SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S);
|
||||
@@ -233,7 +241,7 @@ void UART_DispatchFromTxBuffer(uint8 uart_no)
|
||||
uint8 len_tmp;
|
||||
uint16 data_len;
|
||||
|
||||
if (pTxBuffer) {
|
||||
// if (pTxBuffer) {
|
||||
data_len = (uint8) (pTxBuffer->UartBuffSize - pTxBuffer->Space);
|
||||
if (data_len > fifo_remain) {
|
||||
len_tmp = fifo_remain;
|
||||
@@ -244,8 +252,8 @@ void UART_DispatchFromTxBuffer(uint8 uart_no)
|
||||
len_tmp = (uint8) data_len;
|
||||
UART_TxFifoEnq(pTxBuffer, len_tmp, uart_no);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error("pTxBuff null \n\r");
|
||||
}
|
||||
// }
|
||||
// else {
|
||||
// error("pTxBuff null \n\r");
|
||||
// }
|
||||
}
|
||||
|
||||
+6
-4
@@ -8,17 +8,19 @@
|
||||
#include <esp8266.h>
|
||||
|
||||
// the init func
|
||||
void ICACHE_FLASH_ATTR UART_AllocBuffers(void);
|
||||
void UART_AllocBuffers(void);
|
||||
|
||||
// read from rx buffer
|
||||
uint16 ICACHE_FLASH_ATTR UART_ReadAsync(char *pdata, uint16 data_len);
|
||||
uint16 UART_ReadAsync(char *pdata, uint16 data_len);
|
||||
|
||||
// write to tx buffer
|
||||
void ICACHE_FLASH_ATTR UART_SendAsync(char *pdata, uint16 data_len);
|
||||
void UART_SendAsync(const char *pdata, int16_t data_len);
|
||||
|
||||
//move data from uart fifo to rx buffer
|
||||
void UART_RxFifoDeq(void);
|
||||
void UART_RxFifoCollect(void);
|
||||
//move data from uart tx buffer to fifo
|
||||
void UART_DispatchFromTxBuffer(uint8 uart_no);
|
||||
|
||||
u16 UART_AsyncRxCount(void);
|
||||
|
||||
#endif //ESP_VT100_FIRMWARE_UART_BUFFER_H
|
||||
|
||||
+2
-2
@@ -84,7 +84,7 @@ bool ICACHE_FLASH_ATTR UART_CheckOutputFinished(UARTn uart_no, uint32 time_out_u
|
||||
uint8 tx_fifo_len;
|
||||
|
||||
while (1) {
|
||||
tx_fifo_len = UART_TxQueLen(uart_no);
|
||||
tx_fifo_len = UART_TxFifoCount(uart_no);
|
||||
|
||||
// TODO If using output circbuf, check if empty
|
||||
|
||||
@@ -162,7 +162,7 @@ STATUS UART_WriteChar(UARTn uart_no, uint8 c, uint32 timeout_us)
|
||||
uint32 t_s = system_get_time();
|
||||
|
||||
while ((system_get_time() - t_s) < timeout_us) {
|
||||
uint8 fifo_cnt = UART_TxQueLen(uart_no);
|
||||
uint8 fifo_cnt = UART_TxFifoCount(uart_no);
|
||||
|
||||
if (fifo_cnt < UART_TX_FULL_THRESH_VAL) {
|
||||
WRITE_PERI_REG(UART_FIFO(uart_no), c);
|
||||
|
||||
+2
-2
@@ -172,8 +172,8 @@ extern UartDevice UartDev;
|
||||
//==============================================
|
||||
|
||||
// FIFO used count
|
||||
#define UART_TxQueLen(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT)
|
||||
#define UART_RxQueLen(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT)
|
||||
#define UART_TxFifoCount(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT)
|
||||
#define UART_RxFifoCount(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT)
|
||||
|
||||
STATUS UART_WriteCharCRLF(UARTn uart_no, uint8 c, uint32 timeout_us);
|
||||
STATUS UART_WriteChar(UARTn uart_no, uint8 c, uint32 timeout_us);
|
||||
|
||||
+65
-32
@@ -19,11 +19,21 @@
|
||||
// messy irq/task based UART handling below
|
||||
|
||||
static void uart0_rx_intr_handler(void *para);
|
||||
|
||||
static void uart_recvTask(os_event_t *events);
|
||||
static void uart_processTask(os_event_t *events);
|
||||
|
||||
// Those heavily affect the byte loss ratio
|
||||
#define PROCESS_CHUNK_LEN 1
|
||||
#define FIFO_FULL_THRES 4
|
||||
|
||||
#define uart_recvTaskPrio 1
|
||||
#define uart_recvTaskQueueLen 15
|
||||
#define uart_recvTaskQueueLen 25
|
||||
static os_event_t uart_recvTaskQueue[uart_recvTaskQueueLen];
|
||||
//
|
||||
#define uart_processTaskPrio 0
|
||||
#define uart_processTaskQueueLen 25
|
||||
static os_event_t uart_processTaskQueue[uart_processTaskQueueLen];
|
||||
|
||||
/** Clear the fifos */
|
||||
void ICACHE_FLASH_ATTR clear_rxtx(int uart_no)
|
||||
@@ -62,14 +72,16 @@ void ICACHE_FLASH_ATTR UART_SetupAsyncReceiver(void)
|
||||
|
||||
// Start the Rx reading task
|
||||
system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen);
|
||||
system_os_task(uart_processTask, uart_processTaskPrio, uart_processTaskQueue, uart_processTaskQueueLen);
|
||||
|
||||
// set handler
|
||||
ETS_UART_INTR_ATTACH((void *)uart0_rx_intr_handler, &(UartDev.rcv_buff)); // the buf will be used as an arg
|
||||
|
||||
// fifo threshold config (max: UART_RXFIFO_FULL_THRHD = 127)
|
||||
uint32_t conf = ((90) << UART_RXFIFO_FULL_THRHD_S);
|
||||
uint32_t conf = ((FIFO_FULL_THRES & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S);
|
||||
conf |= ((0x10 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S);
|
||||
// timeout config
|
||||
conf |= ((0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S); // timeout threshold
|
||||
conf |= ((0x06 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S); // timeout threshold
|
||||
conf |= UART_RX_TOUT_EN; // enable timeout
|
||||
WRITE_PERI_REG(UART_CONF1(UART0), conf);
|
||||
|
||||
@@ -82,32 +94,12 @@ void ICACHE_FLASH_ATTR UART_SetupAsyncReceiver(void)
|
||||
|
||||
// Enable IRQ in Extensa
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
// Start the periodic reading event
|
||||
system_os_post(uart_recvTaskPrio, 5, 0);
|
||||
}
|
||||
|
||||
|
||||
// ---- async receive stuff ----
|
||||
|
||||
|
||||
void uart_rx_intr_disable(uint8 uart_no)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||
}
|
||||
|
||||
|
||||
void uart_rx_intr_enable(uint8 uart_no)
|
||||
{
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief get number of bytes in UART tx fifo
|
||||
* @param UART number
|
||||
*/
|
||||
#define UART_GetRxFifoCount(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT)
|
||||
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR UART_PollRx(void)
|
||||
@@ -120,29 +112,67 @@ void uart_rx_intr_enable(uint8 uart_no)
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
static void ICACHE_FLASH_ATTR uart_recvTask(os_event_t *events)
|
||||
/**
|
||||
* This is the system task handling UART Rx bytes.
|
||||
* The function must be re-entrant.
|
||||
*
|
||||
* @param events
|
||||
*/
|
||||
static void uart_recvTask(os_event_t *events)
|
||||
{
|
||||
static char buf[200];
|
||||
//#define PROCESS_CHUNK_LEN 64
|
||||
// static char buf[PROCESS_CHUNK_LEN];
|
||||
|
||||
if (events->sig == 0) {
|
||||
UART_RxFifoDeq();
|
||||
UART_RxFifoCollect();
|
||||
|
||||
// clear irq flags
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);
|
||||
// enable rx irq again
|
||||
uart_rx_intr_enable(UART0);
|
||||
|
||||
// Trigger the Reading task
|
||||
system_os_post(uart_processTaskPrio, 5, 0);
|
||||
}
|
||||
else if (events->sig == 1) {
|
||||
// ???
|
||||
}
|
||||
else if (events->sig == 5) {
|
||||
// else if (events->sig == 5) {
|
||||
// // Send a few to the parser...
|
||||
// int bytes = UART_ReadAsync(buf, PROCESS_CHUNK_LEN);
|
||||
// for (uint8 idx = 0; idx < bytes; idx++) {
|
||||
// UART_HandleRxByte(buf[idx]);
|
||||
// }
|
||||
//
|
||||
// // ask for another run
|
||||
// if (UART_AsyncRxCount() > 0) {
|
||||
// system_os_post(uart_recvTaskPrio, 5, 0);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the system task handling UART Rx bytes.
|
||||
* The function must be re-entrant.
|
||||
*
|
||||
* @param events
|
||||
*/
|
||||
static void uart_processTask(os_event_t *events)
|
||||
{
|
||||
static char buf[PROCESS_CHUNK_LEN];
|
||||
|
||||
if (events->sig == 5) {
|
||||
// Send a few to the parser...
|
||||
int bytes = UART_ReadAsync(buf, 200);
|
||||
int bytes = UART_ReadAsync(buf, PROCESS_CHUNK_LEN);
|
||||
for (uint8 idx = 0; idx < bytes; idx++) {
|
||||
UART_HandleRxByte(buf[idx]);
|
||||
}
|
||||
system_os_post(uart_recvTaskPrio, 5, 0); // call me later
|
||||
|
||||
// ask for another run
|
||||
if (UART_AsyncRxCount() > 0) {
|
||||
system_os_post(uart_processTaskPrio, 5, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +202,7 @@ uart0_rx_intr_handler(void *para)
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
|
||||
|
||||
// run handler
|
||||
system_os_post(uart_recvTaskPrio, 0, 0); /* -> notify the polling thread */
|
||||
system_os_post(uart_recvTaskPrio, 0, 1); /* -> notify the polling thread */
|
||||
}
|
||||
|
||||
if (status_reg & UART_RXFIFO_TOUT_INT_ST) {
|
||||
@@ -187,10 +217,13 @@ uart0_rx_intr_handler(void *para)
|
||||
if (status_reg & UART_TXFIFO_EMPTY_INT_ST) {
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
UART_DispatchFromTxBuffer(UART0);
|
||||
// WRITE_PERI_REG(UART_INT_CLR(UART0), UART_TXFIFO_EMPTY_INT_CLR); - is called by the dispatch func if more data is to be sent.
|
||||
// WRITE_PERI_REG(UART_INT_CLR(UART0), UART_TXFIFO_EMPTY_INT_CLR); //- is called by the dispatch func if more data is to be sent.
|
||||
}
|
||||
|
||||
if (status_reg & UART_RXFIFO_OVF_INT_ST) {
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_OVF_INT_CLR);
|
||||
|
||||
// overflow error
|
||||
UART_WriteChar(UART1, '!', 100);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-3
@@ -18,11 +18,25 @@ void UART_Init(void);
|
||||
/** Configure async Rx on UART0 */
|
||||
void UART_SetupAsyncReceiver(void);
|
||||
|
||||
///** User must provide this func for handling received bytes */
|
||||
/** User must provide this func for handling received bytes */
|
||||
extern void UART_HandleRxByte(char c);
|
||||
|
||||
void uart_rx_intr_disable(uint8 uart_no);
|
||||
static inline void uart_rx_intr_disable(uint8 uart_no)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||
}
|
||||
|
||||
void uart_rx_intr_enable(uint8 uart_no);
|
||||
static inline void uart_rx_intr_enable(uint8 uart_no)
|
||||
{
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get number of bytes in UART tx fifo
|
||||
* @param UART number
|
||||
*/
|
||||
static inline u8 UART_GetRxFifoCount(u8 uart_no) {
|
||||
return (u8) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user