diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 423c512a..c198b74d 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -33,11 +33,7 @@ void HardwareSerial::setDebugOutput(bool en) return; } if(en) { - if(_uart->txEnabled) { - uartSetDebug(_uart); - } else { - uartSetDebug(0); - } + uartSetDebug(_uart); } else { if(uartGetDebug() == _uart_nr) { uartSetDebug(0); @@ -45,33 +41,14 @@ void HardwareSerial::setDebugOutput(bool en) } } -bool HardwareSerial::isTxEnabled(void) -{ - if(_uart == 0) { - return false; - } - return _uart->txEnabled; -} - -bool HardwareSerial::isRxEnabled(void) -{ - if(_uart == 0) { - return false; - } - return _uart->rxEnabled; -} - int HardwareSerial::available(void) { - if (_uart && _uart->rxEnabled) { - return uartAvailable(_uart); - } - return 0; + return uartAvailable(_uart); } int HardwareSerial::peek(void) { - if (_uart && _uart->rxEnabled) { + if (available()) { return uartPeek(_uart); } return -1; @@ -79,7 +56,7 @@ int HardwareSerial::peek(void) int HardwareSerial::read(void) { - if(_uart && _uart->rxEnabled) { + if(available()) { return uartRead(_uart); } return -1; @@ -87,26 +64,17 @@ int HardwareSerial::read(void) void HardwareSerial::flush() { - if(_uart == 0 || !_uart->txEnabled) { - return; - } uartFlush(_uart); } size_t HardwareSerial::write(uint8_t c) { - if(_uart == 0 || !_uart->txEnabled) { - return 0; - } uartWrite(_uart, c); return 1; } size_t HardwareSerial::write(const uint8_t *buffer, size_t size) { - if(_uart == 0 || !_uart->txEnabled) { - return 0; - } uartWriteBuf(_uart, buffer, size); return size; } diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 924b1408..122b910c 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -65,8 +65,6 @@ public: operator bool() const; void setDebugOutput(bool); - bool isTxEnabled(void); - bool isRxEnabled(void); protected: int _uart_nr; diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 25547991..589c840f 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -13,18 +13,22 @@ // limitations under the License. #include "esp32-hal-uart.h" +#include "esp32-hal.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "freertos/semphr.h" #include "rom/ets_sys.h" #include "esp_attr.h" #include "esp_intr.h" #include "rom/uart.h" #include "soc/uart_reg.h" +#include "soc/uart_struct.h" #include "soc/io_mux_reg.h" #include "soc/gpio_sig_map.h" -#define ETS_UART2_INUM 5 +#define ETS_UART_INUM 5 +#define ETS_UART2_INUM ETS_UART_INUM #define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:( (u==2)?DR_REG_UART2_BASE:0))) #define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:( (u==2)?U2RXD_IN_IDX:0))) @@ -34,17 +38,34 @@ static int s_uart_debug_nr = 0; +struct uart_struct_t { + uart_dev_t * dev; + uint8_t num; + xQueueHandle queue; +}; + +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} +}; + static void IRAM_ATTR _uart_isr(void *arg) { - uint8_t c; + uint8_t i, c; BaseType_t xHigherPriorityTaskWoken; - uart_t* uart = (uart_t*)arg; + uart_t* uart; - uart->dev->int_clr.val = UART_RXFIFO_FULL_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_TOUT_INT_ENA; //Acknowledge the interrupt - while(uart->dev->status.rxfifo_cnt) { - c = uart->dev->fifo.rw_byte; - if(!xQueueIsQueueFullFromISR(uart->queue)) { - xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); + for(i=0;i<3;i++){ + uart = &_uart_bus_array[i]; + uart->dev->int_clr.rxfifo_full = 1; + uart->dev->int_clr.frm_err = 1; + uart->dev->int_clr.rxfifo_tout = 1; + while(uart->dev->status.rxfifo_cnt) { + c = uart->dev->fifo.rw_byte; + if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) { + xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); + } } } @@ -53,10 +74,77 @@ static void IRAM_ATTR _uart_isr(void *arg) } } +void uartEnableGlobalInterrupt() +{ + xt_set_interrupt_handler(ETS_UART_INUM, _uart_isr, NULL); + ESP_INTR_ENABLE(ETS_UART_INUM); +} + +void uartDisableGlobalInterrupt() +{ + ESP_INTR_DISABLE(ETS_UART_INUM); + xt_set_interrupt_handler(ETS_UART_INUM, NULL, NULL); +} + +void uartEnableInterrupt(uart_t* uart) +{ + uart->dev->conf1.rxfifo_full_thrhd = 112; + uart->dev->conf1.rx_tout_thrhd = 2; + uart->dev->conf1.rx_tout_en = 1; + uart->dev->int_ena.rxfifo_full = 1; + uart->dev->int_ena.frm_err = 1; + uart->dev->int_ena.rxfifo_tout = 1; + uart->dev->int_clr.val = 0xffffffff; + + intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM); +} + +void uartDisableInterrupt(uart_t* uart) +{ + uart->dev->conf1.val = 0; + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; +} + +void uartDetachRx(uart_t* uart) +{ + if(uart == NULL) { + return; + } + pinMatrixInDetach(UART_RXD_IDX(uart->num), false, false); + uartDisableInterrupt(uart); +} + +void uartDetachTx(uart_t* uart) +{ + if(uart == NULL) { + return; + } + pinMatrixOutDetach(UART_TXD_IDX(uart->num), false, false); +} + +void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) +{ + if(uart == NULL || rxPin > 39) { + return; + } + pinMode(rxPin, INPUT); + pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); + uartEnableInterrupt(uart); + uartEnableGlobalInterrupt(); +} + +void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) +{ + if(uart == NULL || txPin > 39) { + return; + } + pinMode(txPin, OUTPUT); + pinMatrixOutAttach(txPin, UART_TXD_IDX(uart->num), inverted, false); +} + uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted) { - uint32_t conf1 = 0; - if(uart_nr > 2) { return NULL; } @@ -65,87 +153,59 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx return NULL; } - uart_t* uart = (uart_t*) malloc(sizeof(uart_t)); - if(uart == 0) { - return NULL; - } - - uart->dev = (uart_dev_t *)UART_REG_BASE(uart_nr); - uart->num = uart_nr; - uart->inverted = inverted; - - uart->rxPin = rxPin; - uart->txPin = txPin; - uart->rxEnabled = (uart->rxPin != -1); - uart->txEnabled = (uart->txPin != -1); - - uartFlush(uart); - - if(uart->rxEnabled) { + uart_t* uart = &_uart_bus_array[uart_nr]; + + if(queueLen && uart->queue == NULL) { uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue if(uart->queue == NULL) { - free(uart); return NULL; } - - pinMode(uart->rxPin, INPUT); - pinMatrixInAttach(uart->rxPin, UART_RXD_IDX(uart->num), uart->inverted); - intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), UART_INUM(uart->num)); - xt_set_interrupt_handler(UART_INUM(uart->num), _uart_isr, uart); - ESP_INTR_ENABLE(UART_INUM(uart->num)); - conf1 = (112 << UART_RXFIFO_FULL_THRHD_S) | (0x02 << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN; - uart->dev->int_ena.val = UART_RXFIFO_FULL_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_TOUT_INT_ENA; - uart->dev->int_clr.val = 0xffff; - } - if(uart->txEnabled) { - pinMode(uart->txPin, OUTPUT); - pinMatrixOutAttach(uart->txPin, UART_TXD_IDX(uart->num), uart->inverted, false); } + uartFlush(uart); uartSetBaudRate(uart, baudrate); uart->dev->conf0.val = config; - uart->dev->conf1.val = conf1; + + if(rxPin != -1) { + uartAttachRx(uart, rxPin, inverted); + } + + if(txPin != -1) { + uartAttachTx(uart, txPin, inverted); + } + return uart; } void uartEnd(uart_t* uart) { - if(uart == 0) { + if(uart == NULL) { return; } - if(uart->rxEnabled) { - pinMode(uart->rxPin, INPUT); - if(uart->num || uart->rxPin != 3) { - pinMatrixInDetach(UART_RXD_IDX(uart->num), uart->inverted, false); - } - - ESP_INTR_DISABLE(UART_INUM(uart->num)); - xt_set_interrupt_handler(UART_INUM(uart->num), NULL, NULL); + if(uart->queue != NULL) { vQueueDelete(uart->queue); } - if(uart->txEnabled) { - pinMode(uart->txPin, INPUT); - if(uart->num || uart->txPin != 1) { - pinMatrixInDetach(UART_TXD_IDX(uart->num), !uart->inverted, uart->inverted); - } - } + + uartDetachRx(uart); + uartDetachTx(uart); uart->dev->conf0.val = 0; - uart->dev->conf1.val = 0; - uart->dev->int_ena.val = 0; - uart->dev->int_clr.val = 0xffff; - - free(uart); } uint32_t uartAvailable(uart_t* uart) { + if(uart == NULL || uart->queue == NULL) { + return 0; + } return uxQueueMessagesWaiting(uart->queue); } uint8_t uartRead(uart_t* uart) { + if(uart == NULL || uart->queue == NULL) { + return 0; + } uint8_t c; if(xQueueReceive(uart->queue, &c, 0)) { return c; @@ -155,6 +215,9 @@ uint8_t uartRead(uart_t* uart) uint8_t uartPeek(uart_t* uart) { + if(uart == NULL || uart->queue == NULL) { + return 0; + } uint8_t c; if(xQueuePeek(uart->queue, &c, 0)) { return c; @@ -164,14 +227,20 @@ uint8_t uartPeek(uart_t* uart) void uartWrite(uart_t* uart, uint8_t c) { + if(uart == NULL) { + return; + } while(uart->dev->status.rxfifo_cnt == 0x7F); uart->dev->fifo.rw_byte = c; } void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) { + if(uart == NULL) { + return; + } while(len) { - while(len && uart->dev->status.txfifo_cnt < 0x7F) { + while(len && uart->dev->status.rxfifo_cnt < 0x7F) { uart->dev->fifo.rw_byte = *data++; len--; } @@ -180,31 +249,24 @@ void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) void uartFlush(uart_t* uart) { - uint32_t tmp = 0x00000000; - - if(uart == 0) { + if(uart == NULL) { return; } - if(uart->rxEnabled) { - tmp |= UART_RXFIFO_RST; - } + while(uart->dev->status.txfifo_cnt); - if(uart->txEnabled) { - while(uart->dev->status.txfifo_cnt); - tmp |= UART_TXFIFO_RST; - } + uart->dev->conf0.txfifo_rst = 1; + uart->dev->conf0.txfifo_rst = 0; - uart->dev->conf0.val |= (tmp); - uart->dev->conf0.val &= ~(tmp); + uart->dev->conf0.rxfifo_rst = 1; + uart->dev->conf0.rxfifo_rst = 0; } void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) { - if(uart == 0) { + if(uart == NULL) { return; } - uart->baud_rate = 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_frag = clk_div & 0xf; @@ -212,10 +274,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) uint32_t uartGetBaudRate(uart_t* uart) { - if(uart == 0) { + if(uart == NULL) { return 0; } - return uart->baud_rate; + uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F); + return ((UART_CLK_FREQ<<4)/clk_div); } static void IRAM_ATTR uart0_write_char(char c) diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index d3669f83..ce83f146 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -19,10 +19,9 @@ extern "C" { #endif -#include "esp32-hal.h" -#include "soc/uart_struct.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" +#include +#include +#include #define SERIAL_5N1 0x8000010 #define SERIAL_6N1 0x8000014 @@ -49,17 +48,8 @@ extern "C" { #define SERIAL_7O2 0x800003b #define SERIAL_8O2 0x800003f -typedef struct { - uart_dev_t * dev; - xQueueHandle queue; - uint32_t baud_rate; - uint8_t num; - int8_t rxPin; - int8_t txPin; - bool rxEnabled; - bool txEnabled; - bool inverted; -} uart_t; +struct uart_struct_t; +typedef struct uart_struct_t uart_t; uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted); void uartEnd(uart_t* uart); @@ -67,8 +57,10 @@ void uartEnd(uart_t* uart); uint32_t uartAvailable(uart_t* uart); uint8_t uartRead(uart_t* uart); uint8_t uartPeek(uart_t* uart); + void uartWrite(uart_t* uart, uint8_t c); void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len); + void uartFlush(uart_t* uart); void uartSetBaudRate(uart_t* uart, uint32_t baud_rate);