diff --git a/CMakeLists.txt b/CMakeLists.txt index 61d5aef3..19cff29e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,8 @@ set(CORE_SRCS cores/esp32/esp32-hal-spi.c cores/esp32/esp32-hal-tinyusb.c cores/esp32/esp32-hal-touch.c - cores/esp32/esp32-hal-uart.c cores/esp32/esp32-hal-rmt.c cores/esp32/FunctionalInterrupt.cpp - cores/esp32/HardwareSerial.cpp cores/esp32/IPv6Address.cpp cores/esp32/stdlib_noniso.c cores/esp32/USB.cpp diff --git a/cores/esp32/Arduino.h b/cores/esp32/Arduino.h index 192aa7e5..4ed088a8 100644 --- a/cores/esp32/Arduino.h +++ b/cores/esp32/Arduino.h @@ -134,7 +134,6 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); #include #include "WCharacter.h" -#include "HardwareSerial.h" using std::abs; using std::isinf; diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp deleted file mode 100644 index c59da847..00000000 --- a/cores/esp32/HardwareSerial.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include -#include -#include - -#include "pins_arduino.h" -#include "HardwareSerial.h" -#include "esp32-hal-log.h" - -#if CONFIG_IDF_TARGET_ESP32 - -#ifndef RX1 -#define RX1 9 -#endif - -#ifndef TX1 -#define TX1 10 -#endif - -#ifndef RX2 -#define RX2 16 -#endif - -#ifndef TX2 -#define TX2 17 -#endif - -#else - -#ifndef RX1 -#define RX1 18 -#endif - -#ifndef TX1 -#define TX1 17 -#endif - -#endif - -#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) -#if ARDUINO_SERIAL_PORT //Serial used for USB CDC -HardwareSerial Serial0(0); -#else -HardwareSerial Serial(0); -#endif -HardwareSerial Serial1(1); -#if CONFIG_IDF_TARGET_ESP32 -HardwareSerial Serial2(2); -#endif -#endif - -HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {} - -void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms) -{ - if(0 > _uart_nr || _uart_nr > 2) { - log_e("Serial number is invalid, please use 0, 1 or 2"); - return; - } - if(_uart) { - end(); - } - if(_uart_nr == 0 && rxPin < 0 && txPin < 0) { -#if CONFIG_IDF_TARGET_ESP32 - rxPin = 3; - txPin = 1; -#elif CONFIG_IDF_TARGET_ESP32S2 - rxPin = 44; - txPin = 43; -#endif - } - if(_uart_nr == 1 && rxPin < 0 && txPin < 0) { - rxPin = RX1; - txPin = TX1; - } -#if CONFIG_IDF_TARGET_ESP32 - if(_uart_nr == 2 && rxPin < 0 && txPin < 0) { - rxPin = RX2; - txPin = TX2; - } -#endif - _uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert); - _tx_pin = txPin; - _rx_pin = rxPin; - - if(!baud) { - uartStartDetectBaudrate(_uart); - time_t startMillis = esp_timer_get_time() / 1000ULL; - unsigned long detectedBaudRate = 0; - while((esp_timer_get_time() / 1000ULL) - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) { - yield(); - } - - end(); - - if(detectedBaudRate) { - vTaskDelay(100 / portTICK_PERIOD_MS); // Give some time... - _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert); - } else { - log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible"); - _uart = NULL; - _tx_pin = 255; - _rx_pin = 255; - } - } -} - -void HardwareSerial::updateBaudRate(unsigned long baud) -{ - uartSetBaudRate(_uart, baud); -} - -void HardwareSerial::end() -{ - log_v("pins %d %d",_tx_pin, _rx_pin); - uartEnd(_uart, _tx_pin, _rx_pin); - _uart = 0; -} - -size_t HardwareSerial::setRxBufferSize(size_t new_size) { - return uartResizeRxBuffer(_uart, new_size); -} - -int HardwareSerial::available(void) -{ - return uartAvailable(_uart); -} -int HardwareSerial::availableForWrite(void) -{ - return uartAvailableForWrite(_uart); -} - -int HardwareSerial::peek(void) -{ - if (available()) { - return uartPeek(_uart); - } - return -1; -} - -int HardwareSerial::read(void) -{ - if(available()) { - return uartRead(_uart); - } - return -1; -} - -// read characters into buffer -// terminates if size characters have been read, or no further are pending -// returns the number of characters placed in the buffer -// the buffer is NOT null terminated. -size_t HardwareSerial::read(uint8_t *buffer, size_t size) -{ - size_t avail = available(); - if (size < avail) { - avail = size; - } - size_t count = 0; - while(count < avail) { - *buffer++ = uartRead(_uart); - count++; - } - return count; -} - -void HardwareSerial::flush(void) -{ - uartFlush(_uart); -} - -void HardwareSerial::flush(bool txOnly) -{ - uartFlushTxOnly(_uart, txOnly); -} - -size_t HardwareSerial::write(std::basic_string_view buf) -{ - uartWriteBuf(_uart, buf.data(), buf.size()); - return buf.size(); -} -uint32_t HardwareSerial::baudRate() - -{ - return uartGetBaudRate(_uart); -} -HardwareSerial::operator bool() const -{ - return true; -} - -void HardwareSerial::setRxInvert(bool invert) -{ - uartSetRxInvert(_uart, invert); -} diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h deleted file mode 100644 index 3954b0b6..00000000 --- a/cores/esp32/HardwareSerial.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - HardwareSerial.h - Hardware serial library for Wiring - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 28 September 2010 by Mark Sproul - Modified 14 August 2012 by Alarus - Modified 3 December 2013 by Matthijs Kooijman - Modified 18 December 2014 by Ivan Grokhotkov (esp8266 platform support) - Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266) - Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266) - Modified 13 October 2018 by Jeroen Döll (add baudrate detection) - Baudrate detection example usage (detection on Serial1): - void setup() { - Serial.begin(115200); - vTaskDelay(100 / portTICK_PERIOD_MS); - Serial.println(); - - Serial1.begin(0, SERIAL_8N1, -1, -1, true, 11000UL); // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms - - unsigned long detectedBaudRate = Serial1.baudRate(); - if(detectedBaudRate) { - Serial.printf("Detected baudrate is %lu\n", detectedBaudRate); - } else { - Serial.println("No baudrate detected, Serial1 will not work!"); - } - } - - Pay attention: the baudrate returned by baudRate() may be rounded, eg 115200 returns 115201 - */ - -#ifndef HardwareSerial_h -#define HardwareSerial_h - -#include - -#include - -#include "esp32-hal.h" - -class HardwareSerial -{ -public: - HardwareSerial(int uart_nr); - - void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL); - void end(); - void updateBaudRate(unsigned long baud); - int available(void); - int availableForWrite(void); - int peek(void); - int read(void); - size_t read(uint8_t *buffer, size_t size); - inline size_t read(char * buffer, size_t size) - { - return read((uint8_t*) buffer, size); - } - void flush(void); - void flush( bool txOnly); - size_t write(std::string_view buf) { return write(std::basic_string_view{reinterpret_cast(buf.data()), buf.size()}); } - size_t write(std::basic_string_view buf); - uint32_t baudRate(); - operator bool() const; - - size_t setRxBufferSize(size_t); - void setRxInvert(bool); - -protected: - int _uart_nr; - uart_t* _uart; - uint8_t _tx_pin; - uint8_t _rx_pin; -}; - -#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) -#ifndef ARDUINO_SERIAL_PORT -#define ARDUINO_SERIAL_PORT 0 -#endif -#if ARDUINO_SERIAL_PORT //Serial used for USB CDC -#include "USB.h" -#include "USBCDC.h" -extern HardwareSerial Serial0; -#else -extern HardwareSerial Serial; -#endif -extern HardwareSerial Serial1; -#if CONFIG_IDF_TARGET_ESP32 -extern HardwareSerial Serial2; -#endif -#endif - -#endif // HardwareSerial_h diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c deleted file mode 100644 index 2907a96b..00000000 --- a/cores/esp32/esp32-hal-uart.c +++ /dev/null @@ -1,616 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// 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 "esp_attr.h" -#include "soc/uart_reg.h" -#include "soc/uart_struct.h" -#include "soc/io_mux_reg.h" -#include "soc/gpio_sig_map.h" -#include "soc/dport_reg.h" -#include "soc/rtc.h" -#include "esp_intr_alloc.h" - -#include "esp_system.h" -#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ -#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 -#include "esp32/rom/ets_sys.h" -#include "esp32/rom/uart.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/ets_sys.h" -#include "esp32s2/rom/uart.h" -#include "soc/periph_defs.h" -#else -#error Target CONFIG_IDF_TARGET is not supported -#endif -#else // ESP32 Before IDF 4.0 -#include "rom/ets_sys.h" -#include "rom/uart.h" -#include "esp_intr.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32S2 -#define UART_PORTS_NUM 2 -#define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:0)) -#define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:0)) -#define UART_TXD_IDX(u) ((u==0)?U0TXD_OUT_IDX:( (u==1)?U1TXD_OUT_IDX:0)) -#define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:0)) -#else -#define UART_PORTS_NUM 3 -#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))) -#define UART_TXD_IDX(u) ((u==0)?U0TXD_OUT_IDX:( (u==1)?U1TXD_OUT_IDX:( (u==2)?U2TXD_OUT_IDX:0))) -#define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:((u==2)?ETS_UART2_INTR_SOURCE:0))) -#endif - -struct uart_struct_t { - uart_dev_t * dev; -#if !CONFIG_DISABLE_HAL_LOCKS - xSemaphoreHandle lock; -#endif - uint8_t num; - xQueueHandle queue; - intr_handle_t intr_handle; -}; - -#if CONFIG_DISABLE_HAL_LOCKS -#define UART_MUTEX_LOCK() -#define UART_MUTEX_UNLOCK() - -static uart_t _uart_bus_array[] = { - {&UART0, 0, NULL, NULL}, - {&UART1, 1, NULL, NULL}, -#if CONFIG_IDF_TARGET_ESP32 - {&UART2, 2, NULL, NULL} -#endif -}; -#else -#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) -#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) - -static uart_t _uart_bus_array[] = { - {&UART0, NULL, 0, NULL, NULL}, - {&UART1, NULL, 1, NULL, NULL}, -#if CONFIG_IDF_TARGET_ESP32 - {&UART2, NULL, 2, NULL, NULL} -#endif -}; -#endif - -static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); - -static void ARDUINO_ISR_ATTR _uart_isr(void *arg) -{ - uint8_t i, c; - BaseType_t xHigherPriorityTaskWoken; - uart_t* uart; - - for(i=0;iintr_handle == NULL){ - continue; - } - uart->dev->int_clr.rxfifo_full = 1; - uart->dev->int_clr.frm_err = 1; - uart->dev->int_clr.rxfifo_tout = 1; -#if CONFIG_IDF_TARGET_ESP32 - while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { - c = uart->dev->fifo.rw_byte; -#else - uint32_t fifo_reg = UART_FIFO_AHB_REG(i); - while(uart->dev->status.rxfifo_cnt) { - c = ESP_REG(fifo_reg); -#endif - if(uart->queue != NULL) { - xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); - } - } - } - - if (xHigherPriorityTaskWoken) { - portYIELD_FROM_ISR(); - } -} - -void uartEnableInterrupt(uart_t* uart) -{ - UART_MUTEX_LOCK(); - uart->dev->conf1.rxfifo_full_thrhd = 112; -#if CONFIG_IDF_TARGET_ESP32 - uart->dev->conf1.rx_tout_thrhd = 2; -#else - uart->dev->mem_conf.rx_tout_thrhd = 2; -#endif - 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; - - esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ARDUINO_ISR_FLAG, _uart_isr, NULL, &uart->intr_handle); - 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; - - esp_intr_free(uart->intr_handle); - uart->intr_handle = NULL; - - UART_MUTEX_UNLOCK(); -} - -void uartDetachRx(uart_t* uart, uint8_t rxPin) -{ - if(uart == NULL) { - return; - } - pinMatrixInDetach(rxPin, false, false); - uartDisableInterrupt(uart); -} - -void uartDetachTx(uart_t* uart, uint8_t txPin) -{ - if(uart == NULL) { - return; - } - pinMatrixOutDetach(txPin, false, false); -} - -void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) -{ - if(uart == NULL || rxPin >= GPIO_PIN_COUNT) { - return; - } - pinMode(rxPin, INPUT); - uartEnableInterrupt(uart); - pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); -} - -void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) -{ - if(uart == NULL || txPin >= GPIO_PIN_COUNT) { - 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) -{ - if(uart_nr >= UART_PORTS_NUM) { - return NULL; - } - - if(rxPin == -1 && txPin == -1) { - return NULL; - } - - uart_t* uart = &_uart_bus_array[uart_nr]; - -#if !CONFIG_DISABLE_HAL_LOCKS - if(uart->lock == NULL) { - uart->lock = xSemaphoreCreateMutex(); - if(uart->lock == NULL) { - return NULL; - } - } -#endif - - if(queueLen && uart->queue == NULL) { - uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue - if(uart->queue == NULL) { - return NULL; - } - } - if(uart_nr == 1){ - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST); -#if CONFIG_IDF_TARGET_ESP32 - } else if(uart_nr == 2){ - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST); -#endif - } else { - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST); - } - uartFlush(uart); - uartSetBaudRate(uart, baudrate); - UART_MUTEX_LOCK(); - uart->dev->conf0.val = config; - #define TWO_STOP_BITS_CONF 0x3 - #define ONE_STOP_BITS_CONF 0x1 - - if ( uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) { - uart->dev->conf0.stop_bit_num = ONE_STOP_BITS_CONF; - uart->dev->rs485_conf.dl1_en = 1; - } - - // tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate) - // Setting it to 0 prevents line idle time/delays when sending messages with small intervals - uart->dev->idle_conf.tx_idle_num = 0; // - - UART_MUTEX_UNLOCK(); - - if(rxPin != -1) { - uartAttachRx(uart, rxPin, inverted); - } - - if(txPin != -1) { - uartAttachTx(uart, txPin, inverted); - } - addApbChangeCallback(uart, uart_on_apb_change); - return uart; -} - -void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin) -{ - if(uart == NULL) { - return; - } - removeApbChangeCallback(uart, uart_on_apb_change); - - UART_MUTEX_LOCK(); - if(uart->queue != NULL) { - vQueueDelete(uart->queue); - uart->queue = NULL; - } - - uart->dev->conf0.val = 0; - - UART_MUTEX_UNLOCK(); - - uartDetachRx(uart, rxPin); - uartDetachTx(uart, txPin); -} - -size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { - if(uart == NULL) { - return 0; - } - - UART_MUTEX_LOCK(); - if(uart->queue != NULL) { - vQueueDelete(uart->queue); - uart->queue = xQueueCreate(new_size, sizeof(uint8_t)); - if(uart->queue == NULL) { - UART_MUTEX_UNLOCK(); - return 0; - } - } - UART_MUTEX_UNLOCK(); - - return new_size; -} - -void uartSetRxInvert(uart_t* uart, bool invert) -{ - if (uart == NULL) - return; - - if (invert) - uart->dev->conf0.rxd_inv = 1; - else - uart->dev->conf0.rxd_inv = 0; -} - -uint32_t uartAvailable(uart_t* uart) -{ - if(uart == NULL || uart->queue == NULL) { - return 0; - } - return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ; -} - -uint32_t uartAvailableForWrite(uart_t* uart) -{ - if(uart == NULL) { - return 0; - } - return 0x7f - uart->dev->status.txfifo_cnt; -} - -void uartRxFifoToQueue(uart_t* uart) -{ - uint8_t c; - UART_MUTEX_LOCK(); - //disable interrupts - uart->dev->int_ena.val = 0; - uart->dev->int_clr.val = 0xffffffff; -#if CONFIG_IDF_TARGET_ESP32 - while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { - c = uart->dev->fifo.rw_byte; -#else - uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num); - while (uart->dev->status.rxfifo_cnt) { - c = ESP_REG(fifo_reg); -#endif - xQueueSend(uart->queue, &c, 0); - } - //enable interrupts - 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; - UART_MUTEX_UNLOCK(); -} - -uint8_t uartRead(uart_t* uart) -{ - if(uart == NULL || uart->queue == NULL) { - return 0; - } - uint8_t c; - if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) - { - uartRxFifoToQueue(uart); - } - if(xQueueReceive(uart->queue, &c, 0)) { - return c; - } - return 0; -} - -uint8_t uartPeek(uart_t* uart) -{ - if(uart == NULL || uart->queue == NULL) { - return 0; - } - uint8_t c; - if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) - { - uartRxFifoToQueue(uart); - } - if(xQueuePeek(uart->queue, &c, 0)) { - return c; - } - return 0; -} - -void uartWrite(uart_t* uart, uint8_t c) -{ - if(uart == NULL) { - return; - } - UART_MUTEX_LOCK(); - while(uart->dev->status.txfifo_cnt == 0x7F); -#if CONFIG_IDF_TARGET_ESP32 - uart->dev->fifo.rw_byte = c; -#else - ESP_REG(UART_FIFO_AHB_REG(uart->num)) = c; -#endif - UART_MUTEX_UNLOCK(); -} - -void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) -{ - if(uart == NULL) { - return; - } - UART_MUTEX_LOCK(); -#ifndef CONFIG_IDF_TARGET_ESP32 - uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num); -#endif - while(len) { - while(uart->dev->status.txfifo_cnt == 0x7F); -#if CONFIG_IDF_TARGET_ESP32 - uart->dev->fifo.rw_byte = *data++; -#else - ESP_REG(fifo_reg) = *data++; -#endif - len--; - } - UART_MUTEX_UNLOCK(); -} - -void uartFlush(uart_t* uart) -{ - uartFlushTxOnly(uart,true); -} - -void uartFlushTxOnly(uart_t* uart, bool txOnly) -{ - if(uart == NULL) { - return; - } - - UART_MUTEX_LOCK(); -#if CONFIG_IDF_TARGET_ESP32 - while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - - if( !txOnly ){ - //Due to hardware issue, we can not use fifo_rst to reset uart fifo. - //See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <> v2.6 or later. - - // we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`. - while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { - READ_PERI_REG(UART_FIFO_REG(uart->num)); - } - - xQueueReset(uart->queue); - } -#else - while(uart->dev->status.txfifo_cnt); - uart->dev->conf0.txfifo_rst = 1; - uart->dev->conf0.txfifo_rst = 0; -#endif - - UART_MUTEX_UNLOCK(); -} - -void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) -{ - if(uart == NULL) { - return; - } - UART_MUTEX_LOCK(); - uint32_t clk_div = ((getApbFrequency()<<4)/baud_rate); - uart->dev->clk_div.div_int = clk_div>>4 ; - uart->dev->clk_div.div_frag = clk_div & 0xf; - UART_MUTEX_UNLOCK(); -} - -static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb) -{ - uart_t* uart = (uart_t*)arg; - if(ev_type == APB_BEFORE_CHANGE){ - UART_MUTEX_LOCK(); - //disabple interrupt - uart->dev->int_ena.val = 0; - uart->dev->int_clr.val = 0xffffffff; - // read RX fifo - uint8_t c; - // BaseType_t xHigherPriorityTaskWoken; -#if CONFIG_IDF_TARGET_ESP32 - while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { - c = uart->dev->fifo.rw_byte; -#else - uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num); - while(uart->dev->status.rxfifo_cnt != 0) { - c = ESP_REG(fifo_reg); -#endif - if(uart->queue != NULL ) { - xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); - } - } - UART_MUTEX_UNLOCK(); - - // wait TX empty -#if CONFIG_IDF_TARGET_ESP32 - while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); -#else - while(uart->dev->status.txfifo_cnt); -#endif - } else { - //todo: - // set baudrate - UART_MUTEX_LOCK(); - uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F); - uint32_t baud_rate = ((old_apb<<4)/clk_div); - clk_div = ((new_apb<<4)/baud_rate); - uart->dev->clk_div.div_int = clk_div>>4 ; - uart->dev->clk_div.div_frag = clk_div & 0xf; - //enable interrupts - 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; - UART_MUTEX_UNLOCK(); - } -} - -uint32_t uartGetBaudRate(uart_t* uart) -{ - if(uart == NULL) { - return 0; - } - - uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F); - if(!clk_div) { - return 0; - } - - return ((getApbFrequency()<<4)/clk_div); -} - -/* - * if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two. - * This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses. - */ -unsigned long uartBaudrateDetect(uart_t *uart, bool flg) -{ - while(uart->dev->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num) - if(flg) return 0; - ets_delay_us(1000); - } - - UART_MUTEX_LOCK(); - unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12; - UART_MUTEX_UNLOCK(); - - return ret; -} - -/* - * To start detection of baud rate with the uart the auto_baud.en bit needs to be cleared and set. The bit period is - * detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is - * rounded to the closed real baudrate. -*/ -void uartStartDetectBaudrate(uart_t *uart) { - if(!uart) return; - - uart->dev->auto_baud.glitch_filt = 0x08; - uart->dev->auto_baud.en = 0; - uart->dev->auto_baud.en = 1; -} - -unsigned long -uartDetectBaudrate(uart_t *uart) -{ - static bool uartStateDetectingBaudrate = false; - - if(!uartStateDetectingBaudrate) { - uart->dev->auto_baud.glitch_filt = 0x08; - uart->dev->auto_baud.en = 0; - uart->dev->auto_baud.en = 1; - uartStateDetectingBaudrate = true; - } - - unsigned long divisor = uartBaudrateDetect(uart, true); - if (!divisor) { - return 0; - } - - uart->dev->auto_baud.en = 0; - uartStateDetectingBaudrate = false; // Initialize for the next round - - unsigned long baudrate = getApbFrequency() / divisor; - - static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400}; - - size_t i; - for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate - { - if (baudrate <= default_rates[i]) - { - if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) { - i--; - } - break; - } - } - - return default_rates[i]; -} - -/* - * Returns the status of the RX state machine, if the value is non-zero the state machine is active. - */ -bool uartRxActive(uart_t* uart) { -#if CONFIG_IDF_TARGET_ESP32 - return uart->dev->status.st_urx_out != 0; -#else - return 0; -#endif -} diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h deleted file mode 100644 index 6dd80a90..00000000 --- a/cores/esp32/esp32-hal-uart.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef MAIN_ESP32_HAL_UART_H_ -#define MAIN_ESP32_HAL_UART_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#define SERIAL_5N1 0x8000010 -#define SERIAL_6N1 0x8000014 -#define SERIAL_7N1 0x8000018 -#define SERIAL_8N1 0x800001c -#define SERIAL_5N2 0x8000030 -#define SERIAL_6N2 0x8000034 -#define SERIAL_7N2 0x8000038 -#define SERIAL_8N2 0x800003c -#define SERIAL_5E1 0x8000012 -#define SERIAL_6E1 0x8000016 -#define SERIAL_7E1 0x800001a -#define SERIAL_8E1 0x800001e -#define SERIAL_5E2 0x8000032 -#define SERIAL_6E2 0x8000036 -#define SERIAL_7E2 0x800003a -#define SERIAL_8E2 0x800003e -#define SERIAL_5O1 0x8000013 -#define SERIAL_6O1 0x8000017 -#define SERIAL_7O1 0x800001b -#define SERIAL_8O1 0x800001f -#define SERIAL_5O2 0x8000033 -#define SERIAL_6O2 0x8000037 -#define SERIAL_7O2 0x800003b -#define SERIAL_8O2 0x800003f - -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, uint8_t rxPin, uint8_t txPin); - -uint32_t uartAvailable(uart_t* uart); -uint32_t uartAvailableForWrite(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 uartFlushTxOnly(uart_t* uart, bool txOnly ); - -void uartSetBaudRate(uart_t* uart, uint32_t baud_rate); -uint32_t uartGetBaudRate(uart_t* uart); - -size_t uartResizeRxBuffer(uart_t* uart, size_t new_size); - -void uartSetRxInvert(uart_t* uart, bool invert); - -void uartStartDetectBaudrate(uart_t *uart); -unsigned long uartDetectBaudrate(uart_t *uart); - -bool uartRxActive(uart_t* uart); - -#ifdef __cplusplus -} -#endif - -#endif /* MAIN_ESP32_HAL_UART_H_ */ diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index 12f2306a..19819c64 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -62,7 +62,6 @@ void yield(void); //#include "esp32-hal-log.h" #include "esp32-hal-matrix.h" -#include "esp32-hal-uart.h" #include "esp32-hal-gpio.h" #include "esp32-hal-touch.h" #include "esp32-hal-dac.h"