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 {
|
struct uart_struct_t {
|
||||||
uart_dev_t * dev;
|
uart_dev_t * dev;
|
||||||
|
xSemaphoreHandle lock;
|
||||||
uint8_t num;
|
uint8_t num;
|
||||||
xQueueHandle queue;
|
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] = {
|
static uart_t _uart_bus_array[3] = {
|
||||||
{(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL},
|
{(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL},
|
||||||
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL},
|
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL},
|
||||||
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL}
|
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void IRAM_ATTR _uart_isr(void *arg)
|
static void IRAM_ATTR _uart_isr(void *arg)
|
||||||
@ -88,6 +95,7 @@ void uartDisableGlobalInterrupt()
|
|||||||
|
|
||||||
void uartEnableInterrupt(uart_t* uart)
|
void uartEnableInterrupt(uart_t* uart)
|
||||||
{
|
{
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
uart->dev->conf1.rxfifo_full_thrhd = 112;
|
uart->dev->conf1.rxfifo_full_thrhd = 112;
|
||||||
uart->dev->conf1.rx_tout_thrhd = 2;
|
uart->dev->conf1.rx_tout_thrhd = 2;
|
||||||
uart->dev->conf1.rx_tout_en = 1;
|
uart->dev->conf1.rx_tout_en = 1;
|
||||||
@ -97,13 +105,16 @@ void uartEnableInterrupt(uart_t* uart)
|
|||||||
uart->dev->int_clr.val = 0xffffffff;
|
uart->dev->int_clr.val = 0xffffffff;
|
||||||
|
|
||||||
intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM);
|
intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM);
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uartDisableInterrupt(uart_t* uart)
|
void uartDisableInterrupt(uart_t* uart)
|
||||||
{
|
{
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
uart->dev->conf1.val = 0;
|
uart->dev->conf1.val = 0;
|
||||||
uart->dev->int_ena.val = 0;
|
uart->dev->int_ena.val = 0;
|
||||||
uart->dev->int_clr.val = 0xffffffff;
|
uart->dev->int_clr.val = 0xffffffff;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uartDetachRx(uart_t* uart)
|
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];
|
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) {
|
if(queueLen && uart->queue == NULL) {
|
||||||
uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
|
uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
|
||||||
if(uart->queue == NULL) {
|
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);
|
uartFlush(uart);
|
||||||
uartSetBaudRate(uart, baudrate);
|
uartSetBaudRate(uart, baudrate);
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
uart->dev->conf0.val = config;
|
uart->dev->conf0.val = config;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
|
|
||||||
if(rxPin != -1) {
|
if(rxPin != -1) {
|
||||||
uartAttachRx(uart, rxPin, inverted);
|
uartAttachRx(uart, rxPin, inverted);
|
||||||
@ -183,6 +203,7 @@ void uartEnd(uart_t* uart)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
if(uart->queue != NULL) {
|
if(uart->queue != NULL) {
|
||||||
vQueueDelete(uart->queue);
|
vQueueDelete(uart->queue);
|
||||||
}
|
}
|
||||||
@ -191,6 +212,7 @@ void uartEnd(uart_t* uart)
|
|||||||
uartDetachTx(uart);
|
uartDetachTx(uart);
|
||||||
|
|
||||||
uart->dev->conf0.val = 0;
|
uart->dev->conf0.val = 0;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uartAvailable(uart_t* uart)
|
uint32_t uartAvailable(uart_t* uart)
|
||||||
@ -230,8 +252,10 @@ void uartWrite(uart_t* uart, uint8_t c)
|
|||||||
if(uart == NULL) {
|
if(uart == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
while(uart->dev->status.rxfifo_cnt == 0x7F);
|
while(uart->dev->status.rxfifo_cnt == 0x7F);
|
||||||
uart->dev->fifo.rw_byte = c;
|
uart->dev->fifo.rw_byte = c;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
|
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) {
|
if(uart == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
while(len) {
|
while(len) {
|
||||||
while(len && uart->dev->status.rxfifo_cnt < 0x7F) {
|
while(len && uart->dev->status.rxfifo_cnt < 0x7F) {
|
||||||
uart->dev->fifo.rw_byte = *data++;
|
uart->dev->fifo.rw_byte = *data++;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uartFlush(uart_t* uart)
|
void uartFlush(uart_t* uart)
|
||||||
@ -253,6 +279,7 @@ void uartFlush(uart_t* uart)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
while(uart->dev->status.txfifo_cnt);
|
while(uart->dev->status.txfifo_cnt);
|
||||||
|
|
||||||
uart->dev->conf0.txfifo_rst = 1;
|
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 = 1;
|
||||||
uart->dev->conf0.rxfifo_rst = 0;
|
uart->dev->conf0.rxfifo_rst = 0;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
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) {
|
if(uart == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate);
|
uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate);
|
||||||
uart->dev->clk_div.div_int = clk_div>>4 ;
|
uart->dev->clk_div.div_int = clk_div>>4 ;
|
||||||
uart->dev->clk_div.div_frag = clk_div & 0xf;
|
uart->dev->clk_div.div_frag = clk_div & 0xf;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uartGetBaudRate(uart_t* uart)
|
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)
|
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);
|
while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||||
ESP_REG(DR_REG_UART_BASE) = c;
|
ESP_REG(DR_REG_UART_BASE) = c;
|
||||||
|
UART_MUTEX_UNLOCK_NUM(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR uart1_write_char(char c)
|
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);
|
while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||||
ESP_REG(DR_REG_UART1_BASE) = c;
|
ESP_REG(DR_REG_UART1_BASE) = c;
|
||||||
|
UART_MUTEX_UNLOCK_NUM(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR uart2_write_char(char c)
|
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);
|
while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||||
ESP_REG(DR_REG_UART2_BASE) = c;
|
ESP_REG(DR_REG_UART2_BASE) = c;
|
||||||
|
UART_MUTEX_UNLOCK_NUM(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uartSetDebug(uart_t* uart)
|
void uartSetDebug(uart_t* uart)
|
||||||
|
Loading…
Reference in New Issue
Block a user