Implement thread-safe uart
This commit is contained in:
parent
17c8ceb1b9
commit
242bca9451
@ -40,14 +40,21 @@ static int s_uart_debug_nr = 0;
|
||||
|
||||
struct uart_struct_t {
|
||||
uart_dev_t * dev;
|
||||
xSemaphoreHandle lock;
|
||||
uint8_t num;
|
||||
xQueueHandle queue;
|
||||
};
|
||||
|
||||
#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS)
|
||||
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
||||
|
||||
#define UART_MUTEX_LOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) do {} while (xSemaphoreTake(_uart_bus_array[i].lock, portMAX_DELAY) != pdPASS)
|
||||
#define UART_MUTEX_UNLOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) xSemaphoreGive(_uart_bus_array[i].lock)
|
||||
|
||||
static uart_t _uart_bus_array[3] = {
|
||||
{(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL},
|
||||
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL},
|
||||
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL}
|
||||
{(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL},
|
||||
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL},
|
||||
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL}
|
||||
};
|
||||
|
||||
static void IRAM_ATTR _uart_isr(void *arg)
|
||||
@ -88,6 +95,7 @@ void uartDisableGlobalInterrupt()
|
||||
|
||||
void uartEnableInterrupt(uart_t* uart)
|
||||
{
|
||||
UART_MUTEX_LOCK();
|
||||
uart->dev->conf1.rxfifo_full_thrhd = 112;
|
||||
uart->dev->conf1.rx_tout_thrhd = 2;
|
||||
uart->dev->conf1.rx_tout_en = 1;
|
||||
@ -97,13 +105,16 @@ void uartEnableInterrupt(uart_t* uart)
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
|
||||
intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM);
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartDisableInterrupt(uart_t* uart)
|
||||
{
|
||||
UART_MUTEX_LOCK();
|
||||
uart->dev->conf1.val = 0;
|
||||
uart->dev->int_ena.val = 0;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartDetachRx(uart_t* uart)
|
||||
@ -155,6 +166,13 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
|
||||
uart_t* uart = &_uart_bus_array[uart_nr];
|
||||
|
||||
if(uart->lock == NULL) {
|
||||
uart->lock = xSemaphoreCreateMutex();
|
||||
if(uart->lock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(queueLen && uart->queue == NULL) {
|
||||
uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
|
||||
if(uart->queue == NULL) {
|
||||
@ -164,7 +182,9 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
|
||||
uartFlush(uart);
|
||||
uartSetBaudRate(uart, baudrate);
|
||||
UART_MUTEX_LOCK();
|
||||
uart->dev->conf0.val = config;
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
if(rxPin != -1) {
|
||||
uartAttachRx(uart, rxPin, inverted);
|
||||
@ -183,6 +203,7 @@ void uartEnd(uart_t* uart)
|
||||
return;
|
||||
}
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
if(uart->queue != NULL) {
|
||||
vQueueDelete(uart->queue);
|
||||
}
|
||||
@ -191,6 +212,7 @@ void uartEnd(uart_t* uart)
|
||||
uartDetachTx(uart);
|
||||
|
||||
uart->dev->conf0.val = 0;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
uint32_t uartAvailable(uart_t* uart)
|
||||
@ -230,8 +252,10 @@ void uartWrite(uart_t* uart, uint8_t c)
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
while(uart->dev->status.rxfifo_cnt == 0x7F);
|
||||
uart->dev->fifo.rw_byte = c;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
|
||||
@ -239,12 +263,14 @@ void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
while(len) {
|
||||
while(len && uart->dev->status.rxfifo_cnt < 0x7F) {
|
||||
uart->dev->fifo.rw_byte = *data++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartFlush(uart_t* uart)
|
||||
@ -253,6 +279,7 @@ void uartFlush(uart_t* uart)
|
||||
return;
|
||||
}
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
while(uart->dev->status.txfifo_cnt);
|
||||
|
||||
uart->dev->conf0.txfifo_rst = 1;
|
||||
@ -260,6 +287,7 @@ void uartFlush(uart_t* uart)
|
||||
|
||||
uart->dev->conf0.rxfifo_rst = 1;
|
||||
uart->dev->conf0.rxfifo_rst = 0;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
||||
@ -267,9 +295,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate);
|
||||
uart->dev->clk_div.div_int = clk_div>>4 ;
|
||||
uart->dev->clk_div.div_frag = clk_div & 0xf;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
uint32_t uartGetBaudRate(uart_t* uart)
|
||||
@ -283,20 +313,26 @@ uint32_t uartGetBaudRate(uart_t* uart)
|
||||
|
||||
static void IRAM_ATTR uart0_write_char(char c)
|
||||
{
|
||||
UART_MUTEX_LOCK_NUM(0);
|
||||
while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||
ESP_REG(DR_REG_UART_BASE) = c;
|
||||
UART_MUTEX_UNLOCK_NUM(0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR uart1_write_char(char c)
|
||||
{
|
||||
UART_MUTEX_LOCK_NUM(1);
|
||||
while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||
ESP_REG(DR_REG_UART1_BASE) = c;
|
||||
UART_MUTEX_UNLOCK_NUM(1);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR uart2_write_char(char c)
|
||||
{
|
||||
UART_MUTEX_LOCK_NUM(2);
|
||||
while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||
ESP_REG(DR_REG_UART2_BASE) = c;
|
||||
UART_MUTEX_UNLOCK_NUM(2);
|
||||
}
|
||||
|
||||
void uartSetDebug(uart_t* uart)
|
||||
|
Loading…
Reference in New Issue
Block a user