From a4df65f22e9309fc431351d43317dc1a9c3f56d0 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 11:57:41 +0100 Subject: [PATCH 01/44] Added UART RX interrupt function --- cores/esp32/esp32-hal-uart.c | 11 +++++++---- cores/esp32/esp32-hal-uart.h | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 7ee23b95c95..42c757b4830 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -85,7 +85,10 @@ static void IRAM_ATTR _uart_isr(void *arg) uart->dev->int_clr.rxfifo_tout = 1; 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; - if(uart->queue != NULL) { + if(arg != NULL){ // Check if an interrupt handler function has been specified + // Fully optimized code would not create the queue anymore if an function has been specified as an argument. + (*((void(**)())arg))(c); // There is, call it with c as an parameter. Don't pass it to the queue anymore + }else if(uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } } @@ -96,7 +99,7 @@ static void IRAM_ATTR _uart_isr(void *arg) } } -void uartEnableInterrupt(uart_t* uart) +void uartEnableInterrupt(uart_t* uart, void * func) { UART_MUTEX_LOCK(); uart->dev->conf1.rxfifo_full_thrhd = 112; @@ -107,7 +110,7 @@ void uartEnableInterrupt(uart_t* uart) uart->dev->int_ena.rxfifo_tout = 1; uart->dev->int_clr.val = 0xffffffff; - esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); + esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, func, &uart->intr_handle); UART_MUTEX_UNLOCK(); } @@ -148,7 +151,7 @@ void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) } pinMode(rxPin, INPUT); pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); - uartEnableInterrupt(uart); + uartEnableInterrupt(uart, NULL); // No interrupt handler function by default } void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index e35f05d4cff..f5c153e4446 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -80,6 +80,9 @@ unsigned long uartDetectBaudrate(uart_t *uart); bool uartRxActive(uart_t* uart); +void uartDisableInterrupt(uart_t* uart); +void uartEnableInterrupt(uart_t* uart,void * func ); + #ifdef __cplusplus } #endif From 725ad1156c1073c2a10a2b22613836043bf32cd8 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 12:07:36 +0100 Subject: [PATCH 02/44] Updated HardwareSerial class with the interrupt functions --- cores/esp32/HardwareSerial.cpp | 6 ++++++ cores/esp32/HardwareSerial.h | 1 + 2 files changed, 7 insertions(+) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index b06e0735a71..d4f08ede1cc 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -83,6 +83,12 @@ void HardwareSerial::updateBaudRate(unsigned long baud) uartSetBaudRate(_uart, baud); } +// Make sure that the function that the function pointer is pointing to is inside IRAM +void HardwareSerial::setRXInterrupt(void (*arg)()){ + uartDisableInterrupt(_uart); + uartEnableInterrupt(_uart, &arg); +} + void HardwareSerial::end() { if(uartGetDebug() == _uart_nr) { diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index e776e939d0b..d2aa3ec9cfc 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -58,6 +58,7 @@ class HardwareSerial: public Stream 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); + void setRXInterrupt(void (*arg)()); int available(void); int availableForWrite(void); int peek(void); From e8272c781b298b9a2143e9fe0094d49920b7462c Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 14:07:22 +0100 Subject: [PATCH 03/44] Added Serial 'tests' for Interrupt and stock code --- .../examples/Serial/Interrupt/Interrupt.ino | 19 +++++++++++++++++++ .../Serial/NoInterrupt/NoInterrupt.ino | 13 +++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino create mode 100644 libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino new file mode 100644 index 00000000000..a8f8a849559 --- /dev/null +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -0,0 +1,19 @@ +HardwareSerial hwSerial(0); +HardwareSerial hwSerial2(2); + +void setup() +{ + hwSerial.begin(115200); + hwSerial2.begin(115200); + hwSerial2.setRXInterrupt(onSerialRX); + +} + +void loop() +{ + delay(1); +} + +void onSerialRX(char* c){ + hwSerial.print(c); +} diff --git a/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino b/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino new file mode 100644 index 00000000000..ae3d51ab0b5 --- /dev/null +++ b/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino @@ -0,0 +1,13 @@ +HardwareSerial hwSerial(0); +HardwareSerial hwSerial2(2); + +void setup() +{ + hwSerial.begin(115200); + hwSerial2.begin(115200); +} + +void loop() +{ + hwSerial.print(hwSerial2.read()); +} From 623796aa7752d1b17c7c12316efee52a3dd8b2e5 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 14:36:57 +0100 Subject: [PATCH 04/44] This should add the Serial interrupt and no interrupt ino's to the compilation test --- .github/scripts/on-push.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index e0e14ec2b26..9b6e015514d 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -42,14 +42,18 @@ if [ "$BUILD_PIO" -eq 0 ]; then build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" elif [ "$OS_IS_MACOS" == "1" ]; then build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" else # CMake Test if [ "$CHUNK_INDEX" -eq 0 ]; then @@ -66,6 +70,8 @@ else build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" #build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries" fi From 000482e7f757794deb4e6b73e71011a05e1c7de3 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 14:55:56 +0100 Subject: [PATCH 05/44] Platform IO sketch sources are messing everything up --- .github/scripts/on-push.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 9b6e015514d..d525817314f 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -65,13 +65,13 @@ else # PlatformIO Test source ./.github/scripts/install-platformio-esp32.sh BOARD="esp32dev" + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" #build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries" fi From 2e657a70430a165e6353e7a8765632fb96311293 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 14:59:49 +0100 Subject: [PATCH 06/44] Platform IO install script fixed --- .github/scripts/install-platformio-esp32.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh index c065b0a029c..4b4ea314804 100755 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio-esp32.sh @@ -14,13 +14,14 @@ python -m platformio platform install https://github.com/platformio/platform-esp echo "Replacing the framework version ..." python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif32']['version'] = '*'; del data['packages']['framework-arduinoespressif32']['owner']; fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()" -if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then - echo "Linking Core..." - ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" -else - echo "Cloning Core Repository ..." - git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 -fi +# I don't get the code below, you'd want to test the source code in the current repository (forked or not), not in the espressif repo right? +#if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then +echo "Linking Core..." +ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" +#else +# echo "Cloning Core Repository ..." +# git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 +#fi echo "PlatformIO for ESP32 has been installed" echo "" From 38914ffbd001ce1bb52380fbbd208dd8b86ff3c7 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 15:34:05 +0100 Subject: [PATCH 07/44] Arduino Core install script fixed --- .github/scripts/install-arduino-core-esp32.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh index cf1026d6a71..664cf90fd04 100755 --- a/.github/scripts/install-arduino-core-esp32.sh +++ b/.github/scripts/install-arduino-core-esp32.sh @@ -15,13 +15,14 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then pip install requests > /dev/null fi - if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then - echo "Linking Core..." - ln -s $GITHUB_WORKSPACE esp32 - else - echo "Cloning Core Repository..." - git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 - fi +# I don't get the code below, you'd want to test the source code in the current repository (forked or not), not in the espressif repo right? +#if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then + echo "Linking Core..." + ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" +#else +# echo "Cloning Core Repository ..." +# git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 +#fi echo "Updating Submodules ..." cd esp32 From 8a2728481ba9e8f43d0396899fbf8c2546cefef8 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 15:36:42 +0100 Subject: [PATCH 08/44] Fixed HardwareSerial setRXInterrupt argument type --- cores/esp32/HardwareSerial.cpp | 2 +- cores/esp32/HardwareSerial.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index d4f08ede1cc..c8977e9bbf1 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -84,7 +84,7 @@ void HardwareSerial::updateBaudRate(unsigned long baud) } // Make sure that the function that the function pointer is pointing to is inside IRAM -void HardwareSerial::setRXInterrupt(void (*arg)()){ +void HardwareSerial::setRXInterrupt(void (*arg)(char* c)){ uartDisableInterrupt(_uart); uartEnableInterrupt(_uart, &arg); } diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index d2aa3ec9cfc..017471dee24 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -58,7 +58,7 @@ class HardwareSerial: public Stream 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); - void setRXInterrupt(void (*arg)()); + void setRXInterrupt(void (*arg)(char* c)); int available(void); int availableForWrite(void); int peek(void); From ba351a827592bfd51ed7d99d20f4f2f0100625ec Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 23 Dec 2020 16:43:39 +0100 Subject: [PATCH 09/44] Whoopsie --- .github/scripts/install-arduino-core-esp32.sh | 2 +- .github/scripts/on-push.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh index 664cf90fd04..bd6f9d62858 100755 --- a/.github/scripts/install-arduino-core-esp32.sh +++ b/.github/scripts/install-arduino-core-esp32.sh @@ -18,7 +18,7 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then # I don't get the code below, you'd want to test the source code in the current repository (forked or not), not in the espressif repo right? #if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then echo "Linking Core..." - ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" + ln -s $GITHUB_WORKSPACE "$ARDUINO_ESP32_PATH" #else # echo "Cloning Core Repository ..." # git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index d525817314f..d9c32e02e1a 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -71,7 +71,7 @@ else build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" #build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries" fi From 8db7e7f2c95b0b0aee107fedd482527b9dc9d2d6 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Thu, 24 Dec 2020 14:28:06 +0100 Subject: [PATCH 10/44] tested and verified to work --- cores/esp32/HardwareSerial.cpp | 2 +- cores/esp32/HardwareSerial.h | 2 +- cores/esp32/esp32-hal-uart.c | 6 +++--- cores/esp32/esp32-hal-uart.h | 2 +- .../ESP32/examples/Serial/Interrupt/Interrupt.ino | 10 +++++----- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index c8977e9bbf1..c208d43e4bc 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -84,7 +84,7 @@ void HardwareSerial::updateBaudRate(unsigned long baud) } // Make sure that the function that the function pointer is pointing to is inside IRAM -void HardwareSerial::setRXInterrupt(void (*arg)(char* c)){ +void HardwareSerial::setRXInterrupt(void (*arg)(char c)){ uartDisableInterrupt(_uart); uartEnableInterrupt(_uart, &arg); } diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 017471dee24..3d0a525be81 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -58,7 +58,7 @@ class HardwareSerial: public Stream 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); - void setRXInterrupt(void (*arg)(char* c)); + void setRXInterrupt(void (*arg)(char)); int available(void); int availableForWrite(void); int peek(void); diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 42c757b4830..bdbd16fff4f 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -69,7 +69,7 @@ static uart_t _uart_bus_array[3] = { static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); -static void IRAM_ATTR _uart_isr(void *arg) +static void IRAM_ATTR _uart_isr(void (*arg)(char)) { uint8_t i, c; BaseType_t xHigherPriorityTaskWoken; @@ -87,7 +87,7 @@ static void IRAM_ATTR _uart_isr(void *arg) c = uart->dev->fifo.rw_byte; if(arg != NULL){ // Check if an interrupt handler function has been specified // Fully optimized code would not create the queue anymore if an function has been specified as an argument. - (*((void(**)())arg))(c); // There is, call it with c as an parameter. Don't pass it to the queue anymore + (*arg)((char*)&c); // There is, call it with c as an parameter. Don't pass it to the queue anymore }else if(uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } @@ -99,7 +99,7 @@ static void IRAM_ATTR _uart_isr(void *arg) } } -void uartEnableInterrupt(uart_t* uart, void * func) +void uartEnableInterrupt(uart_t* uart, void (*func)(char)) { UART_MUTEX_LOCK(); uart->dev->conf1.rxfifo_full_thrhd = 112; diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index f5c153e4446..1f64d3d31bb 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -81,7 +81,7 @@ unsigned long uartDetectBaudrate(uart_t *uart); bool uartRxActive(uart_t* uart); void uartDisableInterrupt(uart_t* uart); -void uartEnableInterrupt(uart_t* uart,void * func ); +void uartEnableInterrupt(uart_t* uart, void (*func)(char)); #ifdef __cplusplus } diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index a8f8a849559..041bbc3c536 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,11 +1,15 @@ HardwareSerial hwSerial(0); HardwareSerial hwSerial2(2); +static void IRAM_ATTR onSerialRX(char c){ + hwSerial.print(c); +} + void setup() { hwSerial.begin(115200); hwSerial2.begin(115200); - hwSerial2.setRXInterrupt(onSerialRX); + hwSerial2.setRXInterrupt(&onSerialRX); } @@ -13,7 +17,3 @@ void loop() { delay(1); } - -void onSerialRX(char* c){ - hwSerial.print(c); -} From 96fa55fed4c6a3d93ec0728e78a8fde81fb5d970 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 29 Dec 2020 14:58:25 +0100 Subject: [PATCH 11/44] Should fix compilation error --- cores/esp32/HardwareSerial.cpp | 2 +- cores/esp32/esp32-hal-uart.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index c208d43e4bc..902133b1bc8 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -86,7 +86,7 @@ void HardwareSerial::updateBaudRate(unsigned long baud) // Make sure that the function that the function pointer is pointing to is inside IRAM void HardwareSerial::setRXInterrupt(void (*arg)(char c)){ uartDisableInterrupt(_uart); - uartEnableInterrupt(_uart, &arg); + uartEnableInterrupt(_uart, arg); } void HardwareSerial::end() diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index bdbd16fff4f..0dbce169448 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -87,7 +87,7 @@ static void IRAM_ATTR _uart_isr(void (*arg)(char)) c = uart->dev->fifo.rw_byte; if(arg != NULL){ // Check if an interrupt handler function has been specified // Fully optimized code would not create the queue anymore if an function has been specified as an argument. - (*arg)((char*)&c); // There is, call it with c as an parameter. Don't pass it to the queue anymore + (*arg)((char)c); }else if(uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } From 7d84946208968107dfac19496e6347b94ff158f1 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Fri, 8 Jan 2021 14:13:40 +0100 Subject: [PATCH 12/44] Rewrite of the interrupt handlers for the uart devs --- cores/esp32/HardwareSerial.cpp | 10 +- cores/esp32/HardwareSerial.h | 4 +- cores/esp32/esp32-hal-uart.c | 427 +++++++++++------- cores/esp32/esp32-hal-uart.h | 5 +- .../examples/Serial/Interrupt/Interrupt.ino | 9 +- 5 files changed, 288 insertions(+), 167 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 902133b1bc8..23dfa7bb11c 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -84,9 +84,15 @@ void HardwareSerial::updateBaudRate(unsigned long baud) } // Make sure that the function that the function pointer is pointing to is inside IRAM -void HardwareSerial::setRXInterrupt(void (*arg)(char c)){ +void HardwareSerial::setRXInterrupt(void (*arg)(uint8_t, void*), void* user_arg){ + + // Make sure that the previous interrupt_info is not used anymore uartDisableInterrupt(_uart); - uartEnableInterrupt(_uart, arg); + + if(interrupt_info) + delete(interrupt_info); + + uartEnableInterrupt(_uart, &interrupt_info, arg, user_arg); } void HardwareSerial::end() diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 3d0a525be81..3bc37b79900 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -23,6 +23,7 @@ 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) + Modified 08 januari 2012 by Tim Koers (added RX IRQ handling) Baudrate detection example usage (detection on Serial1): void setup() { Serial.begin(115200); @@ -58,7 +59,7 @@ class HardwareSerial: public Stream 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); - void setRXInterrupt(void (*arg)(char)); + void setRXInterrupt(void (*arg)(uint8_t, void*), void* user_arg); int available(void); int availableForWrite(void); int peek(void); @@ -109,6 +110,7 @@ class HardwareSerial: public Stream uart_t* _uart; uint8_t _tx_pin; uint8_t _rx_pin; + uart_interrupt_struct_t* interrupt_info; }; extern void serialEventRun(void) __attribute__((weak)); diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 0dbce169448..de87dcd06bb 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -30,15 +30,16 @@ #include "soc/rtc.h" #include "esp_intr_alloc.h" -#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))) +#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))) static int s_uart_debug_nr = 0; -struct uart_struct_t { - uart_dev_t * dev; +struct uart_struct_t +{ + uart_dev_t *dev; #if !CONFIG_DISABLE_HAL_LOCKS xSemaphoreHandle lock; #endif @@ -47,6 +48,13 @@ struct uart_struct_t { intr_handle_t intr_handle; }; +struct uart_interrupt_struct_t +{ + void (*func)(uint8_t, void*); + void *user_arg; + uart_t *dev; +}; + #if CONFIG_DISABLE_HAL_LOCKS #define UART_MUTEX_LOCK() #define UART_MUTEX_UNLOCK() @@ -54,52 +62,68 @@ struct uart_struct_t { static uart_t _uart_bus_array[3] = { {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} -}; + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL}}; #else -#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) -#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) +#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[3] = { {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} -}; + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL}}; #endif -static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); +static uart_interrupt_t *_uart_interrupt_array[3] = {NULL, NULL, NULL}; -static void IRAM_ATTR _uart_isr(void (*arg)(char)) +static void uart_on_apb_change(void *arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); + +static void IRAM_ATTR _uart_isr() { uint8_t i, c; BaseType_t xHigherPriorityTaskWoken; - uart_t* uart; + uart_t *uart; + uart_interrupt_t *uart_interrupt; - for(i=0;i<3;i++){ + for (i = 0; i < 3; i++) + { uart = &_uart_bus_array[i]; - if(uart->intr_handle == NULL){ + uart_interrupt = _uart_interrupt_array[i]; + + if (uart->intr_handle == NULL) + { continue; } - 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 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { + + 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; - if(arg != NULL){ // Check if an interrupt handler function has been specified + if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) + { // Fully optimized code would not create the queue anymore if an function has been specified as an argument. - (*arg)((char)c); - }else if(uart->queue != NULL) { + (*uart_interrupt->func)(c, uart_interrupt->user_arg); + } + if (uart->queue != NULL) + { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } } + + // Clear the interrupts after everything was read + uart->dev->int_clr.rxfifo_full = 1; + uart->dev->int_clr.frm_err = 1; + uart->dev->int_clr.rxfifo_tout = 1; } - if (xHigherPriorityTaskWoken) { + if (xHigherPriorityTaskWoken) + { portYIELD_FROM_ISR(); } } -void uartEnableInterrupt(uart_t* uart, void (*func)(char)) +void uartEnableInterrupt(uart_t *uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) { UART_MUTEX_LOCK(); uart->dev->conf1.rxfifo_full_thrhd = 112; @@ -110,93 +134,120 @@ void uartEnableInterrupt(uart_t* uart, void (*func)(char)) uart->dev->int_ena.rxfifo_tout = 1; uart->dev->int_clr.val = 0xffffffff; - esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, func, &uart->intr_handle); + if (arg != NULL) + { + (*arg) = malloc(sizeof(uart_interrupt_t)); + (*arg)->func = func; + (*arg)->dev = uart; + (*arg)->user_arg = user_arg; + _uart_interrupt_array[uart->num] = (*arg); + } + + esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); UART_MUTEX_UNLOCK(); } -void uartDisableInterrupt(uart_t* uart) +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; + // Free uart rx interrupt + _uart_interrupt_array[uart->num] = NULL; + esp_intr_free(uart->intr_handle); uart->intr_handle = NULL; UART_MUTEX_UNLOCK(); } -void uartDetachRx(uart_t* uart, uint8_t rxPin) +void uartDetachRx(uart_t *uart, uint8_t rxPin) { - if(uart == NULL) { + if (uart == NULL) + { return; } pinMatrixInDetach(rxPin, false, false); uartDisableInterrupt(uart); } -void uartDetachTx(uart_t* uart, uint8_t txPin) +void uartDetachTx(uart_t *uart, uint8_t txPin) { - if(uart == NULL) { + if (uart == NULL) + { return; } pinMatrixOutDetach(txPin, false, false); } -void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) +void uartAttachRx(uart_t *uart, uint8_t rxPin, bool inverted) { - if(uart == NULL || rxPin > 39) { + if (uart == NULL || rxPin > 39) + { return; } pinMode(rxPin, INPUT); pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); - uartEnableInterrupt(uart, NULL); // No interrupt handler function by default + uartEnableInterrupt(uart, NULL, NULL, NULL); // No interrupt handler function by default } -void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) +void uartAttachTx(uart_t *uart, uint8_t txPin, bool inverted) { - if(uart == NULL || txPin > 39) { + 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) +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 > 2) { + if (uart_nr > 2) + { return NULL; } - if(rxPin == -1 && txPin == -1) { + if (rxPin == -1 && txPin == -1) + { return NULL; } - uart_t* uart = &_uart_bus_array[uart_nr]; + uart_t *uart = &_uart_bus_array[uart_nr]; #if !CONFIG_DISABLE_HAL_LOCKS - if(uart->lock == NULL) { + if (uart->lock == NULL) + { uart->lock = xSemaphoreCreateMutex(); - if(uart->lock == NULL) { + if (uart->lock == NULL) + { return NULL; } } #endif - if(queueLen && uart->queue == NULL) { + if (queueLen && uart->queue == NULL) + { uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue - if(uart->queue == NULL) { + if (uart->queue == NULL) + { return NULL; } } - if(uart_nr == 1){ + 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); - } else if(uart_nr == 2){ + } + 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); - } else { + } + 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); } @@ -204,40 +255,45 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx uartSetBaudRate(uart, baudrate); UART_MUTEX_LOCK(); uart->dev->conf0.val = config; - #define TWO_STOP_BITS_CONF 0x3 - #define ONE_STOP_BITS_CONF 0x1 +#define TWO_STOP_BITS_CONF 0x3 +#define ONE_STOP_BITS_CONF 0x1 - if ( uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) { + 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->dev->idle_conf.tx_idle_num = 0; // UART_MUTEX_UNLOCK(); - if(rxPin != -1) { + if (rxPin != -1) + { uartAttachRx(uart, rxPin, inverted); } - if(txPin != -1) { + 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) +void uartEnd(uart_t *uart, uint8_t txPin, uint8_t rxPin) { - if(uart == NULL) { + if (uart == NULL) + { return; } removeApbChangeCallback(uart, uart_on_apb_change); UART_MUTEX_LOCK(); - if(uart->queue != NULL) { + if (uart->queue != NULL) + { vQueueDelete(uart->queue); uart->queue = NULL; } @@ -250,16 +306,20 @@ void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin) uartDetachTx(uart, txPin); } -size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { - if(uart == NULL) { +size_t uartResizeRxBuffer(uart_t *uart, size_t new_size) +{ + if (uart == NULL) + { return 0; } UART_MUTEX_LOCK(); - if(uart->queue != NULL) { + if (uart->queue != NULL) + { vQueueDelete(uart->queue); uart->queue = xQueueCreate(new_size, sizeof(uint8_t)); - if(uart->queue == NULL) { + if (uart->queue == NULL) + { UART_MUTEX_UNLOCK(); return NULL; } @@ -269,179 +329,202 @@ size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { return new_size; } -void uartSetRxInvert(uart_t* uart, bool invert) +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) +uint32_t uartAvailable(uart_t *uart) { - if(uart == NULL || uart->queue == NULL) { + if (uart == NULL || uart->queue == NULL) + { return 0; } - return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ; + return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt); } -uint32_t uartAvailableForWrite(uart_t* uart) +uint32_t uartAvailableForWrite(uart_t *uart) { - if(uart == NULL) { + if (uart == NULL) + { return 0; } return 0x7f - uart->dev->status.txfifo_cnt; } -void uartRxFifoToQueue(uart_t* uart) +void uartRxFifoToQueue(uart_t *uart) { - uint8_t c; + uint8_t c; UART_MUTEX_LOCK(); - //disable interrupts - uart->dev->int_ena.val = 0; - uart->dev->int_clr.val = 0xffffffff; - 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; - 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; + //disable interrupts + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; + 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; + 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) +uint8_t uartRead(uart_t *uart) { - if(uart == NULL || uart->queue == NULL) { + if (uart == NULL || uart->queue == NULL) + { return 0; } uint8_t c; if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { - uartRxFifoToQueue(uart); + uartRxFifoToQueue(uart); } - if(xQueueReceive(uart->queue, &c, 0)) { + if (xQueueReceive(uart->queue, &c, 0)) + { return c; } return 0; } -uint8_t uartPeek(uart_t* uart) +uint8_t uartPeek(uart_t *uart) { - if(uart == NULL || uart->queue == NULL) { + if (uart == NULL || uart->queue == NULL) + { return 0; } uint8_t c; if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { - uartRxFifoToQueue(uart); + uartRxFifoToQueue(uart); } - if(xQueuePeek(uart->queue, &c, 0)) { + if (xQueuePeek(uart->queue, &c, 0)) + { return c; } return 0; } -void uartWrite(uart_t* uart, uint8_t c) +void uartWrite(uart_t *uart, uint8_t c) { - if(uart == NULL) { + if (uart == NULL) + { return; } UART_MUTEX_LOCK(); - while(uart->dev->status.txfifo_cnt == 0x7F); + while (uart->dev->status.txfifo_cnt == 0x7F) + ; 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) { - if(uart == NULL) { + if (uart == NULL) + { return; } UART_MUTEX_LOCK(); - while(len) { - while(uart->dev->status.txfifo_cnt == 0x7F); + while (len) + { + while (uart->dev->status.txfifo_cnt == 0x7F) + ; uart->dev->fifo.rw_byte = *data++; len--; } UART_MUTEX_UNLOCK(); } -void uartFlush(uart_t* uart) +void uartFlush(uart_t *uart) { - uartFlushTxOnly(uart,true); + uartFlushTxOnly(uart, true); } -void uartFlushTxOnly(uart_t* uart, bool txOnly) +void uartFlushTxOnly(uart_t *uart, bool txOnly) { - if(uart == NULL) { + if (uart == NULL) + { return; } UART_MUTEX_LOCK(); - while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - - if( !txOnly ){ + 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)) { + 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); } - + UART_MUTEX_UNLOCK(); } -void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) +void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) { - if(uart == NULL) { + if (uart == NULL) + { return; } UART_MUTEX_LOCK(); - uint32_t clk_div = ((getApbFrequency()<<4)/baud_rate); - uart->dev->clk_div.div_int = clk_div>>4 ; + 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) +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_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; - while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { + // BaseType_t xHigherPriorityTaskWoken; + 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; - if(uart->queue != NULL ) { + if (uart->queue != NULL) + { xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); } } UART_MUTEX_UNLOCK(); - + // wait TX empty - while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - } else { + while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out) + ; + } + 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 ; + 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; @@ -452,49 +535,55 @@ static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old } } -uint32_t uartGetBaudRate(uart_t* uart) +uint32_t uartGetBaudRate(uart_t *uart) { - if(uart == NULL) { + 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) { + if (!clk_div) + { return 0; } - return ((getApbFrequency()<<4)/clk_div); + return ((getApbFrequency() << 4) / clk_div); } static void IRAM_ATTR uart0_write_char(char c) { - 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; } static void IRAM_ATTR uart1_write_char(char c) { - 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; } static void IRAM_ATTR uart2_write_char(char c) { - 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; } void uart_install_putc() { - switch(s_uart_debug_nr) { + switch (s_uart_debug_nr) + { case 0: - ets_install_putc1((void (*)(char)) &uart0_write_char); + ets_install_putc1((void (*)(char)) & uart0_write_char); break; case 1: - ets_install_putc1((void (*)(char)) &uart1_write_char); + ets_install_putc1((void (*)(char)) & uart1_write_char); break; case 2: - ets_install_putc1((void (*)(char)) &uart2_write_char); + ets_install_putc1((void (*)(char)) & uart2_write_char); break; default: ets_install_putc1(NULL); @@ -502,17 +591,20 @@ void uart_install_putc() } } -void uartSetDebug(uart_t* uart) +void uartSetDebug(uart_t *uart) { - if(uart == NULL || uart->num > 2) { + if (uart == NULL || uart->num > 2) + { s_uart_debug_nr = -1; //ets_install_putc1(NULL); //return; - } else - if(s_uart_debug_nr == uart->num) { + } + else if (s_uart_debug_nr == uart->num) + { return; - } else - s_uart_debug_nr = uart->num; + } + else + s_uart_debug_nr = uart->num; uart_install_putc(); } @@ -523,11 +615,12 @@ int uartGetDebug() int log_printf(const char *format, ...) { - if(s_uart_debug_nr < 0){ + if (s_uart_debug_nr < 0) + { return 0; } static char loc_buf[64]; - char * temp = loc_buf; + char *temp = loc_buf; int len; va_list arg; va_list copy; @@ -535,26 +628,32 @@ int log_printf(const char *format, ...) va_copy(copy, arg); len = vsnprintf(NULL, 0, format, arg); va_end(copy); - if(len >= sizeof(loc_buf)){ - temp = (char*)malloc(len+1); - if(temp == NULL) { + if (len >= sizeof(loc_buf)) + { + temp = (char *)malloc(len + 1); + if (temp == NULL) + { return 0; } } - vsnprintf(temp, len+1, format, arg); + vsnprintf(temp, len + 1, format, arg); #if !CONFIG_DISABLE_HAL_LOCKS - if(_uart_bus_array[s_uart_debug_nr].lock){ + if (_uart_bus_array[s_uart_debug_nr].lock) + { xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); ets_printf("%s", temp); xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); - } else { + } + else + { ets_printf("%s", temp); } #else ets_printf("%s", temp); #endif va_end(arg); - if(len >= sizeof(loc_buf)){ + if (len >= sizeof(loc_buf)) + { free(temp); } return len; @@ -566,8 +665,10 @@ int log_printf(const char *format, ...) */ 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; + while (uart->dev->rxd_cnt.edge_cnt < 30) + { // UART_PULSE_NUM(uart_num) + if (flg) + return 0; ets_delay_us(1000); } @@ -583,12 +684,14 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg) * 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; +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; + uart->dev->auto_baud.glitch_filt = 0x08; + uart->dev->auto_baud.en = 0; + uart->dev->auto_baud.en = 1; } unsigned long @@ -596,7 +699,8 @@ uartDetectBaudrate(uart_t *uart) { static bool uartStateDetectingBaudrate = false; - if(!uartStateDetectingBaudrate) { + if (!uartStateDetectingBaudrate) + { uart->dev->auto_baud.glitch_filt = 0x08; uart->dev->auto_baud.en = 0; uart->dev->auto_baud.en = 1; @@ -604,7 +708,8 @@ uartDetectBaudrate(uart_t *uart) } unsigned long divisor = uartBaudrateDetect(uart, true); - if (!divisor) { + if (!divisor) + { return 0; } @@ -616,11 +721,12 @@ uartDetectBaudrate(uart_t *uart) 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 + 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) { + if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) + { i--; } break; @@ -633,6 +739,7 @@ uartDetectBaudrate(uart_t *uart) /* * Returns the status of the RX state machine, if the value is non-zero the state machine is active. */ -bool uartRxActive(uart_t* uart) { +bool uartRxActive(uart_t *uart) +{ return uart->dev->status.st_urx_out != 0; } diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index 1f64d3d31bb..2e84c12c407 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -51,6 +51,9 @@ extern "C" { struct uart_struct_t; typedef struct uart_struct_t uart_t; +struct uart_interrupt_struct_t; +typedef struct uart_interrupt_struct_t uart_interrupt_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); @@ -81,7 +84,7 @@ unsigned long uartDetectBaudrate(uart_t *uart); bool uartRxActive(uart_t* uart); void uartDisableInterrupt(uart_t* uart); -void uartEnableInterrupt(uart_t* uart, void (*func)(char)); +void uartEnableInterrupt(uart_t *uart, uart_interrupt_t** arg, void (*func)(uint8_t, void*), void* user_arg); #ifdef __cplusplus } diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index 041bbc3c536..19c0a3b1b43 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,15 +1,18 @@ HardwareSerial hwSerial(0); HardwareSerial hwSerial2(2); -static void IRAM_ATTR onSerialRX(char c){ - hwSerial.print(c); +bool ok = true; + +static void IRAM_ATTR onSerialRX(char c, void* user_arg){ + if(*((bool*)user_arg)) + hwSerial.print(c); } void setup() { hwSerial.begin(115200); hwSerial2.begin(115200); - hwSerial2.setRXInterrupt(&onSerialRX); + hwSerial2.setRXInterrupt(onSerialRX, (void*)&ok); } From 054c1a9559a23e8d6da1452039b27a55597591a9 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Fri, 8 Jan 2021 14:18:47 +0100 Subject: [PATCH 13/44] Should fix compilation error --- libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index 19c0a3b1b43..803707a19ca 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -3,16 +3,16 @@ HardwareSerial hwSerial2(2); bool ok = true; -static void IRAM_ATTR onSerialRX(char c, void* user_arg){ - if(*((bool*)user_arg)) +static void IRAM_ATTR onSerialRX(uint8_t c, void* user_arg){ hwSerial.print(c); + ((HardwareSerial*)user_arg)->print(c); } void setup() { hwSerial.begin(115200); hwSerial2.begin(115200); - hwSerial2.setRXInterrupt(onSerialRX, (void*)&ok); + hwSerial2.setRXInterrupt(onSerialRX, (void*)&hwSerial2); } From c344425d3d2e2d9fdeebaf9b1c3d96a58a8dbd07 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Fri, 8 Jan 2021 16:32:55 +0100 Subject: [PATCH 14/44] Better use else if, or else the input get's duplicated whilest it is already handled --- cores/esp32/esp32-hal-uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index de87dcd06bb..83c5b5223b8 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -104,8 +104,7 @@ static void IRAM_ATTR _uart_isr() { // Fully optimized code would not create the queue anymore if an function has been specified as an argument. (*uart_interrupt->func)(c, uart_interrupt->user_arg); - } - if (uart->queue != NULL) + }else if (uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } From 1ba43fcc299cf8227b9a69bf7e153810478f649d Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 11:14:02 +0100 Subject: [PATCH 15/44] Updated code formatting and removed commented lines from ci test scripts --- .github/scripts/install-arduino-core-esp32.sh | 6 - .github/scripts/install-platformio-esp32.sh | 6 - cores/esp32/esp32-hal-uart.c | 312 +++++++----------- .../examples/Serial/Interrupt/Interrupt.ino | 3 +- 4 files changed, 120 insertions(+), 207 deletions(-) diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh index bd6f9d62858..aad48ba68ba 100755 --- a/.github/scripts/install-arduino-core-esp32.sh +++ b/.github/scripts/install-arduino-core-esp32.sh @@ -15,14 +15,8 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then pip install requests > /dev/null fi -# I don't get the code below, you'd want to test the source code in the current repository (forked or not), not in the espressif repo right? -#if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then echo "Linking Core..." ln -s $GITHUB_WORKSPACE "$ARDUINO_ESP32_PATH" -#else -# echo "Cloning Core Repository ..." -# git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 -#fi echo "Updating Submodules ..." cd esp32 diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh index 4b4ea314804..88f3497af67 100755 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio-esp32.sh @@ -14,14 +14,8 @@ python -m platformio platform install https://github.com/platformio/platform-esp echo "Replacing the framework version ..." python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif32']['version'] = '*'; del data['packages']['framework-arduinoespressif32']['owner']; fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()" -# I don't get the code below, you'd want to test the source code in the current repository (forked or not), not in the espressif repo right? -#if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then echo "Linking Core..." ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" -#else -# echo "Cloning Core Repository ..." -# git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 -#fi echo "PlatformIO for ESP32 has been installed" echo "" diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 83c5b5223b8..57ba96cecbe 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -30,15 +30,14 @@ #include "soc/rtc.h" #include "esp_intr_alloc.h" -#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))) +#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))) static int s_uart_debug_nr = 0; -struct uart_struct_t -{ +struct uart_struct_t { uart_dev_t *dev; #if !CONFIG_DISABLE_HAL_LOCKS xSemaphoreHandle lock; @@ -62,50 +61,44 @@ struct uart_interrupt_struct_t static uart_t _uart_bus_array[3] = { {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL}}; + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} +}; #else -#define UART_MUTEX_LOCK() \ - do \ - { \ - } while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) -#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) +#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[3] = { {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL}}; + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} +}; #endif -static uart_interrupt_t *_uart_interrupt_array[3] = {NULL, NULL, NULL}; +static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); -static void uart_on_apb_change(void *arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); +static uart_interrupt_t *_uart_interrupt_array[3] = {NULL, NULL, NULL}; static void IRAM_ATTR _uart_isr() { uint8_t i, c; BaseType_t xHigherPriorityTaskWoken; - uart_t *uart; + uart_t* uart; uart_interrupt_t *uart_interrupt; - for (i = 0; i < 3; i++) - { + for (i=0;i<3;i++) { uart = &_uart_bus_array[i]; uart_interrupt = _uart_interrupt_array[i]; - if (uart->intr_handle == NULL) - { + if (uart->intr_handle == NULL) { continue; } - while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) - { + 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; - if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) - { + if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) { // Fully optimized code would not create the queue anymore if an function has been specified as an argument. (*uart_interrupt->func)(c, uart_interrupt->user_arg); - }else if (uart->queue != NULL) - { + }else if (uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } } @@ -116,13 +109,12 @@ static void IRAM_ATTR _uart_isr() uart->dev->int_clr.rxfifo_tout = 1; } - if (xHigherPriorityTaskWoken) - { + if (xHigherPriorityTaskWoken) { portYIELD_FROM_ISR(); } } -void uartEnableInterrupt(uart_t *uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) +void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) { UART_MUTEX_LOCK(); uart->dev->conf1.rxfifo_full_thrhd = 112; @@ -133,8 +125,7 @@ void uartEnableInterrupt(uart_t *uart, uart_interrupt_t **arg, void (*func)(uint uart->dev->int_ena.rxfifo_tout = 1; uart->dev->int_clr.val = 0xffffffff; - if (arg != NULL) - { + if (arg != NULL) { (*arg) = malloc(sizeof(uart_interrupt_t)); (*arg)->func = func; (*arg)->dev = uart; @@ -146,7 +137,7 @@ void uartEnableInterrupt(uart_t *uart, uart_interrupt_t **arg, void (*func)(uint UART_MUTEX_UNLOCK(); } -void uartDisableInterrupt(uart_t *uart) +void uartDisableInterrupt(uart_t* uart) { UART_MUTEX_LOCK(); uart->dev->conf1.val = 0; @@ -162,29 +153,26 @@ void uartDisableInterrupt(uart_t *uart) UART_MUTEX_UNLOCK(); } -void uartDetachRx(uart_t *uart, uint8_t rxPin) +void uartDetachRx(uart_t* uart, uint8_t rxPin) { - if (uart == NULL) - { + if (uart == NULL) { return; } pinMatrixInDetach(rxPin, false, false); uartDisableInterrupt(uart); } -void uartDetachTx(uart_t *uart, uint8_t txPin) +void uartDetachTx(uart_t* uart, uint8_t txPin) { - if (uart == NULL) - { + if (uart == NULL) { return; } pinMatrixOutDetach(txPin, false, false); } -void uartAttachRx(uart_t *uart, uint8_t rxPin, bool inverted) +void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) { - if (uart == NULL || rxPin > 39) - { + if (uart == NULL || rxPin > 39) { return; } pinMode(rxPin, INPUT); @@ -192,61 +180,51 @@ void uartAttachRx(uart_t *uart, uint8_t rxPin, bool inverted) uartEnableInterrupt(uart, NULL, NULL, NULL); // No interrupt handler function by default } -void uartAttachTx(uart_t *uart, uint8_t txPin, bool inverted) +void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) { - if (uart == NULL || txPin > 39) - { + 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) +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 > 2) - { + if (uart_nr > 2) { return NULL; } - if (rxPin == -1 && txPin == -1) - { + if (rxPin == -1 && txPin == -1) { return NULL; } - uart_t *uart = &_uart_bus_array[uart_nr]; + uart_t* uart = &_uart_bus_array[uart_nr]; #if !CONFIG_DISABLE_HAL_LOCKS - if (uart->lock == NULL) - { + if (uart->lock == NULL) { uart->lock = xSemaphoreCreateMutex(); - if (uart->lock == NULL) - { + if (uart->lock == NULL) { return NULL; } } #endif - if (queueLen && uart->queue == NULL) - { + if (queueLen && uart->queue == NULL) { uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue - if (uart->queue == NULL) - { + if (uart->queue == NULL) { return NULL; } } - if (uart_nr == 1) - { + 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); } - else if (uart_nr == 2) - { + 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); } - else - { + 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); } @@ -257,8 +235,7 @@ uart_t *uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx #define TWO_STOP_BITS_CONF 0x3 #define ONE_STOP_BITS_CONF 0x1 - if (uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) - { + 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; } @@ -269,30 +246,26 @@ uart_t *uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx UART_MUTEX_UNLOCK(); - if (rxPin != -1) - { + if (rxPin != -1) { uartAttachRx(uart, rxPin, inverted); } - if (txPin != -1) - { + 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) +void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin) { - if (uart == NULL) - { + if (uart == NULL) { return; } removeApbChangeCallback(uart, uart_on_apb_change); UART_MUTEX_LOCK(); - if (uart->queue != NULL) - { + if (uart->queue != NULL) { vQueueDelete(uart->queue); uart->queue = NULL; } @@ -305,16 +278,14 @@ void uartEnd(uart_t *uart, uint8_t txPin, uint8_t rxPin) uartDetachTx(uart, txPin); } -size_t uartResizeRxBuffer(uart_t *uart, size_t new_size) +size_t uartResizeRxBuffer(uart_t* uart, size_t new_size) { - if (uart == NULL) - { + if (uart == NULL) { return 0; } UART_MUTEX_LOCK(); - if (uart->queue != NULL) - { + if (uart->queue != NULL) { vQueueDelete(uart->queue); uart->queue = xQueueCreate(new_size, sizeof(uint8_t)); if (uart->queue == NULL) @@ -328,7 +299,7 @@ size_t uartResizeRxBuffer(uart_t *uart, size_t new_size) return new_size; } -void uartSetRxInvert(uart_t *uart, bool invert) +void uartSetRxInvert(uart_t* uart, bool invert) { if (uart == NULL) return; @@ -339,33 +310,30 @@ void uartSetRxInvert(uart_t *uart, bool invert) uart->dev->conf0.rxd_inv = 0; } -uint32_t uartAvailable(uart_t *uart) +uint32_t uartAvailable(uart_t* uart) { - if (uart == NULL || uart->queue == NULL) - { + if (uart == NULL || uart->queue == NULL) { return 0; } return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt); } -uint32_t uartAvailableForWrite(uart_t *uart) +uint32_t uartAvailableForWrite(uart_t* uart) { - if (uart == NULL) - { + if (uart == NULL) { return 0; } return 0x7f - uart->dev->status.txfifo_cnt; } -void uartRxFifoToQueue(uart_t *uart) +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; - while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) - { + 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; xQueueSend(uart->queue, &c, 0); } @@ -377,96 +345,81 @@ void uartRxFifoToQueue(uart_t *uart) UART_MUTEX_UNLOCK(); } -uint8_t uartRead(uart_t *uart) +uint8_t uartRead(uart_t* uart) { - if (uart == NULL || uart->queue == NULL) - { + if (uart == NULL || uart->queue == NULL) { return 0; } uint8_t c; - if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) - { + if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { uartRxFifoToQueue(uart); } - if (xQueueReceive(uart->queue, &c, 0)) - { + if (xQueueReceive(uart->queue, &c, 0)) { return c; } return 0; } -uint8_t uartPeek(uart_t *uart) +uint8_t uartPeek(uart_t* uart) { - if (uart == NULL || uart->queue == NULL) - { + if (uart == NULL || uart->queue == NULL) { return 0; } uint8_t c; - if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) - { + if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { uartRxFifoToQueue(uart); } - if (xQueuePeek(uart->queue, &c, 0)) - { + if (xQueuePeek(uart->queue, &c, 0)) { return c; } return 0; } -void uartWrite(uart_t *uart, uint8_t c) +void uartWrite(uart_t* uart, uint8_t c) { - if (uart == NULL) - { + if (uart == NULL) { return; } UART_MUTEX_LOCK(); - while (uart->dev->status.txfifo_cnt == 0x7F) - ; + while (uart->dev->status.txfifo_cnt == 0x7F); 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) { - if (uart == NULL) - { + if (uart == NULL) { return; } UART_MUTEX_LOCK(); - while (len) - { - while (uart->dev->status.txfifo_cnt == 0x7F) - ; + while (len) { + while (uart->dev->status.txfifo_cnt == 0x7F); uart->dev->fifo.rw_byte = *data++; len--; } UART_MUTEX_UNLOCK(); } -void uartFlush(uart_t *uart) +void uartFlush(uart_t* uart) { uartFlushTxOnly(uart, true); } -void uartFlushTxOnly(uart_t *uart, bool txOnly) +void uartFlushTxOnly(uart_t* uart, bool txOnly) { - if (uart == NULL) - { + if (uart == NULL) { return; } UART_MUTEX_LOCK(); - while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out) - ; + while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - if (!txOnly) - { + 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)) - { + 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)); } @@ -476,10 +429,9 @@ void uartFlushTxOnly(uart_t *uart, bool txOnly) UART_MUTEX_UNLOCK(); } -void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) +void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) { - if (uart == NULL) - { + if (uart == NULL) { return; } UART_MUTEX_LOCK(); @@ -489,11 +441,10 @@ void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) 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) +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_t* uart = (uart_t *)arg; + if (ev_type == APB_BEFORE_CHANGE) { UART_MUTEX_LOCK(); //disabple interrupt uart->dev->int_ena.val = 0; @@ -501,22 +452,17 @@ static void uart_on_apb_change(void *arg, apb_change_ev_t ev_type, uint32_t old_ // read RX fifo uint8_t c; // BaseType_t xHigherPriorityTaskWoken; - while (uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) - { + 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; - if (uart->queue != NULL) - { + if (uart->queue != NULL) { xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); } } UART_MUTEX_UNLOCK(); // wait TX empty - while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out) - ; - } - else - { + while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); + } else { //todo: // set baudrate UART_MUTEX_LOCK(); @@ -534,16 +480,14 @@ static void uart_on_apb_change(void *arg, apb_change_ev_t ev_type, uint32_t old_ } } -uint32_t uartGetBaudRate(uart_t *uart) +uint32_t uartGetBaudRate(uart_t* uart) { - if (uart == NULL) - { + 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) - { + if (!clk_div) { return 0; } @@ -552,37 +496,33 @@ uint32_t uartGetBaudRate(uart_t *uart) static void IRAM_ATTR uart0_write_char(char c) { - 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; } static void IRAM_ATTR uart1_write_char(char c) { - 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; } static void IRAM_ATTR uart2_write_char(char c) { - 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; } void uart_install_putc() { - switch (s_uart_debug_nr) - { + switch (s_uart_debug_nr){ case 0: - ets_install_putc1((void (*)(char)) & uart0_write_char); + ets_install_putc1((void (*)(char)) &uart0_write_char); break; case 1: - ets_install_putc1((void (*)(char)) & uart1_write_char); + ets_install_putc1((void (*)(char)) &uart1_write_char); break; case 2: - ets_install_putc1((void (*)(char)) & uart2_write_char); + ets_install_putc1((void (*)(char)) &uart2_write_char); break; default: ets_install_putc1(NULL); @@ -590,20 +530,17 @@ void uart_install_putc() } } -void uartSetDebug(uart_t *uart) +void uartSetDebug(uart_t* uart) { - if (uart == NULL || uart->num > 2) - { + if (uart == NULL || uart->num > 2) { s_uart_debug_nr = -1; //ets_install_putc1(NULL); //return; - } - else if (s_uart_debug_nr == uart->num) - { + } else if (s_uart_debug_nr == uart->num) { return; - } - else + } else { s_uart_debug_nr = uart->num; + } uart_install_putc(); } @@ -612,10 +549,9 @@ int uartGetDebug() return s_uart_debug_nr; } -int log_printf(const char *format, ...) +int log_printf(const char* format, ...) { - if (s_uart_debug_nr < 0) - { + if (s_uart_debug_nr < 0) { return 0; } static char loc_buf[64]; @@ -627,32 +563,26 @@ int log_printf(const char *format, ...) va_copy(copy, arg); len = vsnprintf(NULL, 0, format, arg); va_end(copy); - if (len >= sizeof(loc_buf)) - { + if (len >= sizeof(loc_buf)) { temp = (char *)malloc(len + 1); - if (temp == NULL) - { + if (temp == NULL) { return 0; } } vsnprintf(temp, len + 1, format, arg); #if !CONFIG_DISABLE_HAL_LOCKS - if (_uart_bus_array[s_uart_debug_nr].lock) - { + if (_uart_bus_array[s_uart_debug_nr].lock) { xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); ets_printf("%s", temp); xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); - } - else - { + } else { ets_printf("%s", temp); } #else ets_printf("%s", temp); #endif va_end(arg); - if (len >= sizeof(loc_buf)) - { + if (len >= sizeof(loc_buf)) { free(temp); } return len; @@ -662,12 +592,10 @@ int log_printf(const char *format, ...) * 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) +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; + while(uart->dev->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num) + if(flg) return 0; ets_delay_us(1000); } @@ -683,7 +611,7 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg) * 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) +void uartStartDetectBaudrate(uart_t* uart) { if (!uart) return; @@ -694,12 +622,11 @@ void uartStartDetectBaudrate(uart_t *uart) } unsigned long -uartDetectBaudrate(uart_t *uart) +uartDetectBaudrate(uart_t* uart) { static bool uartStateDetectingBaudrate = false; - if (!uartStateDetectingBaudrate) - { + if (!uartStateDetectingBaudrate) { uart->dev->auto_baud.glitch_filt = 0x08; uart->dev->auto_baud.en = 0; uart->dev->auto_baud.en = 1; @@ -707,8 +634,7 @@ uartDetectBaudrate(uart_t *uart) } unsigned long divisor = uartBaudrateDetect(uart, true); - if (!divisor) - { + if (!divisor) { return 0; } @@ -720,7 +646,7 @@ uartDetectBaudrate(uart_t *uart) 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 + for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate { if (baudrate <= default_rates[i]) { @@ -738,7 +664,7 @@ uartDetectBaudrate(uart_t *uart) /* * Returns the status of the RX state machine, if the value is non-zero the state machine is active. */ -bool uartRxActive(uart_t *uart) +bool uartRxActive(uart_t* uart) { return uart->dev->status.st_urx_out != 0; } diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index 803707a19ca..f3596077d7d 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -12,8 +12,7 @@ void setup() { hwSerial.begin(115200); hwSerial2.begin(115200); - hwSerial2.setRXInterrupt(onSerialRX, (void*)&hwSerial2); - + hwSerial2.setRXInterrupt(onSerialRX, (void*)&hwSerial2); } void loop() From cadb74d9cc92f80107650af4d2becbfddeffdeed Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 11:17:28 +0100 Subject: [PATCH 16/44] Updated code formatting once again --- cores/esp32/esp32-hal-uart.c | 242 ++++++++++++++++------------------- 1 file changed, 113 insertions(+), 129 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 57ba96cecbe..251bbea0945 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -38,7 +38,7 @@ static int s_uart_debug_nr = 0; struct uart_struct_t { - uart_dev_t *dev; + uart_dev_t* dev; #if !CONFIG_DISABLE_HAL_LOCKS xSemaphoreHandle lock; #endif @@ -85,7 +85,7 @@ static void IRAM_ATTR _uart_isr() uart_t* uart; uart_interrupt_t *uart_interrupt; - for (i=0;i<3;i++) { + for(i=0;i<3;i++){ uart = &_uart_bus_array[i]; uart_interrupt = _uart_interrupt_array[i]; @@ -125,7 +125,7 @@ void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint uart->dev->int_ena.rxfifo_tout = 1; uart->dev->int_clr.val = 0xffffffff; - if (arg != NULL) { + if(arg != NULL){ (*arg) = malloc(sizeof(uart_interrupt_t)); (*arg)->func = func; (*arg)->dev = uart; @@ -155,7 +155,7 @@ void uartDisableInterrupt(uart_t* uart) void uartDetachRx(uart_t* uart, uint8_t rxPin) { - if (uart == NULL) { + if(uart == NULL){ return; } pinMatrixInDetach(rxPin, false, false); @@ -164,25 +164,15 @@ void uartDetachRx(uart_t* uart, uint8_t rxPin) void uartDetachTx(uart_t* uart, uint8_t txPin) { - if (uart == NULL) { + if(uart == NULL){ return; } pinMatrixOutDetach(txPin, 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, NULL, NULL, NULL); // No interrupt handler function by default -} - void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) { - if (uart == NULL || txPin > 39) { + if(uart == NULL || txPin > 39) { return; } pinMode(txPin, OUTPUT); @@ -191,40 +181,38 @@ void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) 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 > 2) { + if(uart_nr > 2) { return NULL; } - if (rxPin == -1 && txPin == -1) { + if(rxPin == -1 && txPin == -1) { return NULL; } uart_t* uart = &_uart_bus_array[uart_nr]; #if !CONFIG_DISABLE_HAL_LOCKS - if (uart->lock == NULL) { + if(uart->lock == NULL) { uart->lock = xSemaphoreCreateMutex(); - if (uart->lock == NULL) { + if(uart->lock == NULL) { return NULL; } } #endif - if (queueLen && uart->queue == NULL) { + if(queueLen && uart->queue == NULL) { uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue - if (uart->queue == NULL) { + if(uart->queue == NULL) { return NULL; } } - if (uart_nr == 1) { + 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); - } - else if (uart_nr == 2) { + } 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); - } - else { + } 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); } @@ -232,25 +220,25 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx uartSetBaudRate(uart, baudrate); UART_MUTEX_LOCK(); uart->dev->conf0.val = config; -#define TWO_STOP_BITS_CONF 0x3 -#define ONE_STOP_BITS_CONF 0x1 + #define TWO_STOP_BITS_CONF 0x3 + #define ONE_STOP_BITS_CONF 0x1 - if (uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) { + 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->dev->idle_conf.tx_idle_num = 0; // UART_MUTEX_UNLOCK(); - if (rxPin != -1) { + if(rxPin != -1) { uartAttachRx(uart, rxPin, inverted); } - if (txPin != -1) { + if(txPin != -1) { uartAttachTx(uart, txPin, inverted); } addApbChangeCallback(uart, uart_on_apb_change); @@ -259,13 +247,13 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin) { - if (uart == NULL) { + if(uart == NULL) { return; } removeApbChangeCallback(uart, uart_on_apb_change); UART_MUTEX_LOCK(); - if (uart->queue != NULL) { + if(uart->queue != NULL) { vQueueDelete(uart->queue); uart->queue = NULL; } @@ -278,18 +266,16 @@ void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin) uartDetachTx(uart, txPin); } -size_t uartResizeRxBuffer(uart_t* uart, size_t new_size) -{ - if (uart == NULL) { +size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { + if(uart == NULL) { return 0; } UART_MUTEX_LOCK(); - if (uart->queue != NULL) { + if(uart->queue != NULL) { vQueueDelete(uart->queue); uart->queue = xQueueCreate(new_size, sizeof(uint8_t)); - if (uart->queue == NULL) - { + if(uart->queue == NULL) { UART_MUTEX_UNLOCK(); return NULL; } @@ -303,7 +289,7 @@ void uartSetRxInvert(uart_t* uart, bool invert) { if (uart == NULL) return; - + if (invert) uart->dev->conf0.rxd_inv = 1; else @@ -312,15 +298,15 @@ void uartSetRxInvert(uart_t* uart, bool invert) uint32_t uartAvailable(uart_t* uart) { - if (uart == NULL || uart->queue == NULL) { + if(uart == NULL || uart->queue == NULL) { return 0; } - return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt); + return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ; } uint32_t uartAvailableForWrite(uart_t* uart) { - if (uart == NULL) { + if(uart == NULL) { return 0; } return 0x7f - uart->dev->status.txfifo_cnt; @@ -328,33 +314,34 @@ uint32_t uartAvailableForWrite(uart_t* uart) void uartRxFifoToQueue(uart_t* uart) { - uint8_t c; + uint8_t c; UART_MUTEX_LOCK(); - //disable interrupts - uart->dev->int_ena.val = 0; - uart->dev->int_clr.val = 0xffffffff; - 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; - 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; + //disable interrupts + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; + 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; + 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) { + 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 ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) + { + uartRxFifoToQueue(uart); } - if (xQueueReceive(uart->queue, &c, 0)) { + if(xQueueReceive(uart->queue, &c, 0)) { return c; } return 0; @@ -362,14 +349,15 @@ uint8_t uartRead(uart_t* uart) uint8_t uartPeek(uart_t* uart) { - if (uart == NULL || uart->queue == NULL) { + 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 ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) + { + uartRxFifoToQueue(uart); } - if (xQueuePeek(uart->queue, &c, 0)) { + if(xQueuePeek(uart->queue, &c, 0)) { return c; } return 0; @@ -377,23 +365,23 @@ uint8_t uartPeek(uart_t* uart) void uartWrite(uart_t* uart, uint8_t c) { - if (uart == NULL) { + if(uart == NULL) { return; } UART_MUTEX_LOCK(); - while (uart->dev->status.txfifo_cnt == 0x7F); + while(uart->dev->status.txfifo_cnt == 0x7F); 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) { - if (uart == NULL) { + if(uart == NULL) { return; } UART_MUTEX_LOCK(); - while (len) { - while (uart->dev->status.txfifo_cnt == 0x7F); + while(len) { + while(uart->dev->status.txfifo_cnt == 0x7F); uart->dev->fifo.rw_byte = *data++; len--; } @@ -402,74 +390,74 @@ void uartWriteBuf(uart_t* uart, const uint8_t* data, size_t len) void uartFlush(uart_t* uart) { - uartFlushTxOnly(uart, true); + uartFlushTxOnly(uart,true); } void uartFlushTxOnly(uart_t* uart, bool txOnly) { - if (uart == NULL) { + if(uart == NULL) { return; } UART_MUTEX_LOCK(); - while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - - if (!txOnly) { + 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)) { + 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); } - + UART_MUTEX_UNLOCK(); } void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) { - if (uart == NULL) { + if(uart == NULL) { return; } UART_MUTEX_LOCK(); - uint32_t clk_div = ((getApbFrequency() << 4) / baud_rate); - uart->dev->clk_div.div_int = clk_div >> 4; + 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) +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_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; - while (uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { + // BaseType_t xHigherPriorityTaskWoken; + 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; - if (uart->queue != NULL) { + if(uart->queue != NULL ) { xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); } } UART_MUTEX_UNLOCK(); - + // wait TX empty - while (uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); + while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); } 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; + 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; @@ -482,39 +470,39 @@ static void uart_on_apb_change(void* arg, apb_change_ev_t ev_type, uint32_t old_ uint32_t uartGetBaudRate(uart_t* uart) { - if (uart == NULL) { + 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) { + if(!clk_div) { return 0; } - return ((getApbFrequency() << 4) / clk_div); + return ((getApbFrequency()<<4)/clk_div); } static void IRAM_ATTR uart0_write_char(char c) { - 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; } static void IRAM_ATTR uart1_write_char(char c) { - 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; } static void IRAM_ATTR uart2_write_char(char c) { - 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; } void uart_install_putc() { - switch (s_uart_debug_nr){ + switch(s_uart_debug_nr) { case 0: ets_install_putc1((void (*)(char)) &uart0_write_char); break; @@ -532,15 +520,15 @@ void uart_install_putc() void uartSetDebug(uart_t* uart) { - if (uart == NULL || uart->num > 2) { + if(uart == NULL || uart->num > 2) { s_uart_debug_nr = -1; //ets_install_putc1(NULL); //return; - } else if (s_uart_debug_nr == uart->num) { + } else + if(s_uart_debug_nr == uart->num) { return; - } else { - s_uart_debug_nr = uart->num; - } + } else + s_uart_debug_nr = uart->num; uart_install_putc(); } @@ -549,13 +537,13 @@ int uartGetDebug() return s_uart_debug_nr; } -int log_printf(const char* format, ...) +int log_printf(const char *format, ...) { - if (s_uart_debug_nr < 0) { + if(s_uart_debug_nr < 0){ return 0; } static char loc_buf[64]; - char *temp = loc_buf; + char * temp = loc_buf; int len; va_list arg; va_list copy; @@ -563,15 +551,15 @@ int log_printf(const char* format, ...) va_copy(copy, arg); len = vsnprintf(NULL, 0, format, arg); va_end(copy); - if (len >= sizeof(loc_buf)) { - temp = (char *)malloc(len + 1); - if (temp == NULL) { + if(len >= sizeof(loc_buf)){ + temp = (char*)malloc(len+1); + if(temp == NULL) { return 0; } } - vsnprintf(temp, len + 1, format, arg); + vsnprintf(temp, len+1, format, arg); #if !CONFIG_DISABLE_HAL_LOCKS - if (_uart_bus_array[s_uart_debug_nr].lock) { + if(_uart_bus_array[s_uart_debug_nr].lock){ xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); ets_printf("%s", temp); xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); @@ -582,7 +570,7 @@ int log_printf(const char* format, ...) ets_printf("%s", temp); #endif va_end(arg); - if (len >= sizeof(loc_buf)) { + if(len >= sizeof(loc_buf)){ free(temp); } return len; @@ -592,7 +580,7 @@ int log_printf(const char* format, ...) * 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) +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; @@ -611,22 +599,20 @@ unsigned long uartBaudrateDetect(uart_t* uart, bool flg) * 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; +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; + 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) +uartDetectBaudrate(uart_t *uart) { static bool uartStateDetectingBaudrate = false; - if (!uartStateDetectingBaudrate) { + if(!uartStateDetectingBaudrate) { uart->dev->auto_baud.glitch_filt = 0x08; uart->dev->auto_baud.en = 0; uart->dev->auto_baud.en = 1; @@ -650,8 +636,7 @@ uartDetectBaudrate(uart_t* uart) { if (baudrate <= default_rates[i]) { - if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) - { + if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) { i--; } break; @@ -664,7 +649,6 @@ uartDetectBaudrate(uart_t* uart) /* * Returns the status of the RX state machine, if the value is non-zero the state machine is active. */ -bool uartRxActive(uart_t* uart) -{ +bool uartRxActive(uart_t* uart) { return uart->dev->status.st_urx_out != 0; -} +} \ No newline at end of file From 02b29fda4fb5a0768d636fabeff88ef3b37766d2 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 11:19:17 +0100 Subject: [PATCH 17/44] Last code formatting fix --- cores/esp32/esp32-hal-uart.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 251bbea0945..b55abe76507 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -155,7 +155,7 @@ void uartDisableInterrupt(uart_t* uart) void uartDetachRx(uart_t* uart, uint8_t rxPin) { - if(uart == NULL){ + if(uart == NULL) { return; } pinMatrixInDetach(rxPin, false, false); @@ -164,12 +164,22 @@ void uartDetachRx(uart_t* uart, uint8_t rxPin) void uartDetachTx(uart_t* uart, uint8_t txPin) { - if(uart == NULL){ + if(uart == NULL) { return; } pinMatrixOutDetach(txPin, 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); +} + void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) { if(uart == NULL || txPin > 39) { @@ -651,4 +661,4 @@ uartDetectBaudrate(uart_t *uart) */ bool uartRxActive(uart_t* uart) { return uart->dev->status.st_urx_out != 0; -} \ No newline at end of file +} From d63d896ac52a66996b1b8433b1a62b1ee470ac1b Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 11:23:02 +0100 Subject: [PATCH 18/44] Accidentally removed some args whilest formatting the code --- cores/esp32/esp32-hal-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index b55abe76507..7bbefa3d2fc 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -177,7 +177,7 @@ void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) } pinMode(rxPin, INPUT); pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); - uartEnableInterrupt(uart); + uartEnableInterrupt(uart, NULL, NULL, NULL); } void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) From 7bea5a4d11df9362ec05e642c9a7517e686dc949 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 14:32:10 +0100 Subject: [PATCH 19/44] Free the interupt from the array on enable/disable of the interrupt, added doxygen documentation to the functoins --- cores/esp32/esp32-hal-uart.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 7bbefa3d2fc..7d5383072e8 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -114,6 +114,19 @@ static void IRAM_ATTR _uart_isr() } } +/** + * @brief Enables the UART RX interrupt on the specified UART device. + * + * This function will register the interrupt user function with arguments, to be called when an RX interupt occurs. + * The pointer to the uart_interrupt_t will be deleted when the interrupt is disabled, or another interrupt function is being registered. + * Please check for NULL on the uart_interrupt_t pointer before using it. + + * @param[in] uart The uart device to register the function for. + * @param[out] arg The uart_interrupt description data that is returned when this function succeeds. + * @param[in] func The function to be called when the RX interrupt is fired. (void rx_int(uint8_t c, void* user_arg)) + * @param[in] user_arg The user argument that will be passed to the user interrupt handler. + * + */ void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) { UART_MUTEX_LOCK(); @@ -130,6 +143,10 @@ void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint (*arg)->func = func; (*arg)->dev = uart; (*arg)->user_arg = user_arg; + + if(_uart_interrupt_array[uart->num]) + free(_uart_interrupt_array[uart->num]); + _uart_interrupt_array[uart->num] = (*arg); } @@ -137,6 +154,17 @@ void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint UART_MUTEX_UNLOCK(); } +/** + * @brief Disables the UART RX interrupt on the specified UART device. + * + * This function disables the RX interrupt for the specified UART device. + * This function will delete the uart_interrupt_t* that uartEnableInterrupt() creates. + * The pointer to the uart_interrupt_t will be deleted when the interrupt is disabled, or another interrupt function is being registered. + * Please check for NULL on the uart_interrupt_t pointer before using it. + + * @param[in] uart The uart device to register the function for. + * + */ void uartDisableInterrupt(uart_t* uart) { UART_MUTEX_LOCK(); @@ -145,6 +173,8 @@ void uartDisableInterrupt(uart_t* uart) uart->dev->int_clr.val = 0xffffffff; // Free uart rx interrupt + if(_uart_interrupt_array[uart->num]) + free(_uart_interrupt_array[uart->num]); _uart_interrupt_array[uart->num] = NULL; esp_intr_free(uart->intr_handle); From def8f9c8ed144b5e14c9fba107cc13a6eec1e61e Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 14:36:08 +0100 Subject: [PATCH 20/44] Renamed the interrupt management functions --- cores/esp32/HardwareSerial.cpp | 4 ++-- cores/esp32/HardwareSerial.h | 2 +- cores/esp32/esp32-hal-uart.c | 10 +++++----- cores/esp32/esp32-hal-uart.h | 4 ++-- .../ESP32/examples/Serial/Interrupt/Interrupt.ino | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 23dfa7bb11c..eabc35f7a3c 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -84,7 +84,7 @@ void HardwareSerial::updateBaudRate(unsigned long baud) } // Make sure that the function that the function pointer is pointing to is inside IRAM -void HardwareSerial::setRXInterrupt(void (*arg)(uint8_t, void*), void* user_arg){ +void HardwareSerial::setRxInterrupt(void (*arg)(uint8_t, void*), void* user_arg){ // Make sure that the previous interrupt_info is not used anymore uartDisableInterrupt(_uart); @@ -92,7 +92,7 @@ void HardwareSerial::setRXInterrupt(void (*arg)(uint8_t, void*), void* user_arg) if(interrupt_info) delete(interrupt_info); - uartEnableInterrupt(_uart, &interrupt_info, arg, user_arg); + uartEnableRxInterrupt(_uart, &interrupt_info, arg, user_arg); } void HardwareSerial::end() diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 3bc37b79900..0fad21ff574 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -59,7 +59,7 @@ class HardwareSerial: public Stream 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); - void setRXInterrupt(void (*arg)(uint8_t, void*), void* user_arg); + void setRxInterrupt(void (*arg)(uint8_t, void*), void* user_arg); int available(void); int availableForWrite(void); int peek(void); diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 7d5383072e8..2276e90ff40 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -127,7 +127,7 @@ static void IRAM_ATTR _uart_isr() * @param[in] user_arg The user argument that will be passed to the user interrupt handler. * */ -void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) +void uartEnableRxInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) { UART_MUTEX_LOCK(); uart->dev->conf1.rxfifo_full_thrhd = 112; @@ -158,14 +158,14 @@ void uartEnableInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint * @brief Disables the UART RX interrupt on the specified UART device. * * This function disables the RX interrupt for the specified UART device. - * This function will delete the uart_interrupt_t* that uartEnableInterrupt() creates. + * This function will delete the uart_interrupt_t* that uartEnableRxInterrupt() creates. * The pointer to the uart_interrupt_t will be deleted when the interrupt is disabled, or another interrupt function is being registered. * Please check for NULL on the uart_interrupt_t pointer before using it. * @param[in] uart The uart device to register the function for. * */ -void uartDisableInterrupt(uart_t* uart) +void uartDisableRxInterrupt(uart_t* uart) { UART_MUTEX_LOCK(); uart->dev->conf1.val = 0; @@ -189,7 +189,7 @@ void uartDetachRx(uart_t* uart, uint8_t rxPin) return; } pinMatrixInDetach(rxPin, false, false); - uartDisableInterrupt(uart); + uartDisableRxInterrupt(uart); } void uartDetachTx(uart_t* uart, uint8_t txPin) @@ -207,7 +207,7 @@ void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) } pinMode(rxPin, INPUT); pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); - uartEnableInterrupt(uart, NULL, NULL, NULL); + uartEnableRxInterrupt(uart, NULL, NULL, NULL); } void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index 2e84c12c407..ecaade4c372 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -83,8 +83,8 @@ unsigned long uartDetectBaudrate(uart_t *uart); bool uartRxActive(uart_t* uart); -void uartDisableInterrupt(uart_t* uart); -void uartEnableInterrupt(uart_t *uart, uart_interrupt_t** arg, void (*func)(uint8_t, void*), void* user_arg); +void uartDisableRxInterrupt(uart_t* uart); +void uartEnableRxInterrupt(uart_t *uart, uart_interrupt_t** arg, void (*func)(uint8_t, void*), void* user_arg); #ifdef __cplusplus } diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index f3596077d7d..e577bf9c90f 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -12,7 +12,7 @@ void setup() { hwSerial.begin(115200); hwSerial2.begin(115200); - hwSerial2.setRXInterrupt(onSerialRX, (void*)&hwSerial2); + hwSerial2.setRxInterrupt(onSerialRX, (void*)&hwSerial2); } void loop() From 21043d5e08c5930bc35e98cf925a11ababf98648 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 14:40:26 +0100 Subject: [PATCH 21/44] Removed tests from Windows and Mac --- .github/scripts/on-push.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index d9c32e02e1a..71304447041 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -42,18 +42,15 @@ if [ "$BUILD_PIO" -eq 0 ]; then build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" + elif [ "$OS_IS_MACOS" == "1" ]; then build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ - build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" + build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" else # CMake Test if [ "$CHUNK_INDEX" -eq 0 ]; then From 55ae3be944ae9d5414a234345e81e0a863d15659 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 14:42:07 +0100 Subject: [PATCH 22/44] Fixed setRxInterrupt in HardwareSerial.cpp and fixed double deletion of the interrupt_info struct --- cores/esp32/HardwareSerial.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index eabc35f7a3c..ea824fb82b5 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -87,11 +87,7 @@ void HardwareSerial::updateBaudRate(unsigned long baud) void HardwareSerial::setRxInterrupt(void (*arg)(uint8_t, void*), void* user_arg){ // Make sure that the previous interrupt_info is not used anymore - uartDisableInterrupt(_uart); - - if(interrupt_info) - delete(interrupt_info); - + uartDisableRxInterrupt(_uart); uartEnableRxInterrupt(_uart, &interrupt_info, arg, user_arg); } From be5000b8c44abd82f266625cff6c91fff22967bc Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 14:57:09 +0100 Subject: [PATCH 23/44] Resolved the if statements --- cores/esp32/esp32-hal-uart.c | 821 ++++++++++++++++++----------------- 1 file changed, 412 insertions(+), 409 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 2276e90ff40..a7f9425c99e 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -4,7 +4,7 @@ // 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 +// 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, @@ -30,28 +30,28 @@ #include "soc/rtc.h" #include "esp_intr_alloc.h" -#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_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))) static int s_uart_debug_nr = 0; struct uart_struct_t { - uart_dev_t* dev; + uart_dev_t* dev; #if !CONFIG_DISABLE_HAL_LOCKS - xSemaphoreHandle lock; + xSemaphoreHandle lock; #endif - uint8_t num; - xQueueHandle queue; - intr_handle_t intr_handle; + uint8_t num; + xQueueHandle queue; + intr_handle_t intr_handle; }; struct uart_interrupt_struct_t { - void (*func)(uint8_t, void*); - void *user_arg; - uart_t *dev; + void (*func)(uint8_t, void*); + void *user_arg; + uart_t *dev; }; #if CONFIG_DISABLE_HAL_LOCKS @@ -59,18 +59,18 @@ struct uart_interrupt_struct_t #define UART_MUTEX_UNLOCK() static uart_t _uart_bus_array[3] = { - {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} + {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} }; #else -#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) -#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) +#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[3] = { - {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} + {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} }; #endif @@ -80,38 +80,38 @@ static uart_interrupt_t *_uart_interrupt_array[3] = {NULL, NULL, NULL}; static void IRAM_ATTR _uart_isr() { - uint8_t i, c; - BaseType_t xHigherPriorityTaskWoken; - uart_t* uart; - uart_interrupt_t *uart_interrupt; - - for(i=0;i<3;i++){ - uart = &_uart_bus_array[i]; - uart_interrupt = _uart_interrupt_array[i]; - - if (uart->intr_handle == NULL) { - continue; - } - - 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; - if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) { - // Fully optimized code would not create the queue anymore if an function has been specified as an argument. - (*uart_interrupt->func)(c, uart_interrupt->user_arg); - }else if (uart->queue != NULL) { - xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); - } - } - - // Clear the interrupts after everything was read - uart->dev->int_clr.rxfifo_full = 1; - uart->dev->int_clr.frm_err = 1; - uart->dev->int_clr.rxfifo_tout = 1; - } + uint8_t i, c; + BaseType_t xHigherPriorityTaskWoken; + uart_t* uart; + uart_interrupt_t *uart_interrupt; + + for(i=0;i<3;i++){ + uart = &_uart_bus_array[i]; + uart_interrupt = _uart_interrupt_array[i]; + + if (uart->intr_handle == NULL) { + continue; + } + + 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; + if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) { + // Fully optimized code would not create the queue anymore if an function has been specified as an argument. + (*uart_interrupt->func)(c, uart_interrupt->user_arg); + }else if (uart->queue != NULL) { + xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); + } + } + + // Clear the interrupts after everything was read + uart->dev->int_clr.rxfifo_full = 1; + uart->dev->int_clr.frm_err = 1; + uart->dev->int_clr.rxfifo_tout = 1; + } - if (xHigherPriorityTaskWoken) { - portYIELD_FROM_ISR(); - } + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } } /** @@ -129,29 +129,30 @@ static void IRAM_ATTR _uart_isr() */ void uartEnableRxInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) { - UART_MUTEX_LOCK(); - 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; - - if(arg != NULL){ - (*arg) = malloc(sizeof(uart_interrupt_t)); - (*arg)->func = func; - (*arg)->dev = uart; - (*arg)->user_arg = user_arg; + UART_MUTEX_LOCK(); + 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; + + if(arg != NULL){ + (*arg) = malloc(sizeof(uart_interrupt_t)); + (*arg)->func = func; + (*arg)->dev = uart; + (*arg)->user_arg = user_arg; - if(_uart_interrupt_array[uart->num]) + if(_uart_interrupt_array[uart->num]){ free(_uart_interrupt_array[uart->num]); - - _uart_interrupt_array[uart->num] = (*arg); - } + } + + _uart_interrupt_array[uart->num] = (*arg); + } - esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); - UART_MUTEX_UNLOCK(); + esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); + UART_MUTEX_UNLOCK(); } /** @@ -167,195 +168,197 @@ void uartEnableRxInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(ui */ void uartDisableRxInterrupt(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_LOCK(); + uart->dev->conf1.val = 0; + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; - // Free uart rx interrupt - if(_uart_interrupt_array[uart->num]) + // Free uart rx interrupt + if(_uart_interrupt_array[uart->num]){ free(_uart_interrupt_array[uart->num]); - _uart_interrupt_array[uart->num] = NULL; + } + + _uart_interrupt_array[uart->num] = NULL; - esp_intr_free(uart->intr_handle); - uart->intr_handle = NULL; + esp_intr_free(uart->intr_handle); + uart->intr_handle = NULL; - UART_MUTEX_UNLOCK(); + UART_MUTEX_UNLOCK(); } void uartDetachRx(uart_t* uart, uint8_t rxPin) { - if(uart == NULL) { - return; - } - pinMatrixInDetach(rxPin, false, false); - uartDisableRxInterrupt(uart); + if(uart == NULL) { + return; + } + pinMatrixInDetach(rxPin, false, false); + uartDisableRxInterrupt(uart); } void uartDetachTx(uart_t* uart, uint8_t txPin) { - if(uart == NULL) { - return; - } - pinMatrixOutDetach(txPin, false, false); + if(uart == NULL) { + return; + } + pinMatrixOutDetach(txPin, 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); - uartEnableRxInterrupt(uart, NULL, NULL, NULL); + if(uart == NULL || rxPin > 39) { + return; + } + pinMode(rxPin, INPUT); + pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); + uartEnableRxInterrupt(uart, NULL, NULL, NULL); } 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); + 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) { - if(uart_nr > 2) { - return NULL; - } + if(uart_nr > 2) { + return NULL; + } - if(rxPin == -1 && txPin == -1) { - return NULL; - } + if(rxPin == -1 && txPin == -1) { + return NULL; + } - uart_t* uart = &_uart_bus_array[uart_nr]; + 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; - } - } + 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); - } 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); - } 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; + 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); + } 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); + } 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); + if(uart == NULL) { + return; + } + removeApbChangeCallback(uart, uart_on_apb_change); - UART_MUTEX_LOCK(); - if(uart->queue != NULL) { - vQueueDelete(uart->queue); - uart->queue = NULL; - } + UART_MUTEX_LOCK(); + if(uart->queue != NULL) { + vQueueDelete(uart->queue); + uart->queue = NULL; + } - uart->dev->conf0.val = 0; + uart->dev->conf0.val = 0; - UART_MUTEX_UNLOCK(); + UART_MUTEX_UNLOCK(); - uartDetachRx(uart, rxPin); - uartDetachTx(uart, txPin); + uartDetachRx(uart, rxPin); + uartDetachTx(uart, txPin); } size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { - if(uart == NULL) { - return 0; - } + 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 NULL; - } - } - UART_MUTEX_UNLOCK(); + 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 NULL; + } + } + UART_MUTEX_UNLOCK(); - return new_size; + 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; + 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) ; + 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; + if(uart == NULL) { + return 0; + } + return 0x7f - uart->dev->status.txfifo_cnt; } void uartRxFifoToQueue(uart_t* uart) { uint8_t c; - UART_MUTEX_LOCK(); + UART_MUTEX_LOCK(); //disable interrupts uart->dev->int_ena.val = 0; uart->dev->int_clr.val = 0xffffffff; @@ -368,252 +371,252 @@ void uartRxFifoToQueue(uart_t* uart) uart->dev->int_ena.frm_err = 1; uart->dev->int_ena.rxfifo_tout = 1; uart->dev->int_clr.val = 0xffffffff; - UART_MUTEX_UNLOCK(); + 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; + 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; + 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); - uart->dev->fifo.rw_byte = c; - UART_MUTEX_UNLOCK(); + if(uart == NULL) { + return; + } + UART_MUTEX_LOCK(); + while(uart->dev->status.txfifo_cnt == 0x7F); + uart->dev->fifo.rw_byte = c; + UART_MUTEX_UNLOCK(); } void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) { - if(uart == NULL) { - return; - } - UART_MUTEX_LOCK(); - while(len) { - while(uart->dev->status.txfifo_cnt == 0x7F); - uart->dev->fifo.rw_byte = *data++; - len--; - } - UART_MUTEX_UNLOCK(); + if(uart == NULL) { + return; + } + UART_MUTEX_LOCK(); + while(len) { + while(uart->dev->status.txfifo_cnt == 0x7F); + uart->dev->fifo.rw_byte = *data++; + len--; + } + UART_MUTEX_UNLOCK(); } void uartFlush(uart_t* uart) { - uartFlushTxOnly(uart,true); + uartFlushTxOnly(uart,true); } void uartFlushTxOnly(uart_t* uart, bool txOnly) { - if(uart == NULL) { - return; - } + if(uart == NULL) { + return; + } - UART_MUTEX_LOCK(); - 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. + UART_MUTEX_LOCK(); + 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)); - } + // 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); - } - - UART_MUTEX_UNLOCK(); + xQueueReset(uart->queue); + } + + 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(); + 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; - 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; - if(uart->queue != NULL ) { - xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); - } - } - UART_MUTEX_UNLOCK(); + 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; + 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; + if(uart->queue != NULL ) { + xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); + } + } + UART_MUTEX_UNLOCK(); - // wait TX empty - while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - } 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(); - } + // wait TX empty + while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); + } 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; - } + 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; - } + 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); + return ((getApbFrequency()<<4)/clk_div); } static void IRAM_ATTR uart0_write_char(char c) { - while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); - ESP_REG(DR_REG_UART_BASE) = c; + while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); + ESP_REG(DR_REG_UART_BASE) = c; } static void IRAM_ATTR uart1_write_char(char c) { - while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); - ESP_REG(DR_REG_UART1_BASE) = c; + while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); + ESP_REG(DR_REG_UART1_BASE) = c; } static void IRAM_ATTR uart2_write_char(char c) { - while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); - ESP_REG(DR_REG_UART2_BASE) = c; + while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); + ESP_REG(DR_REG_UART2_BASE) = c; } void uart_install_putc() { - switch(s_uart_debug_nr) { - case 0: - ets_install_putc1((void (*)(char)) &uart0_write_char); - break; - case 1: - ets_install_putc1((void (*)(char)) &uart1_write_char); - break; - case 2: - ets_install_putc1((void (*)(char)) &uart2_write_char); - break; - default: - ets_install_putc1(NULL); - break; - } + switch(s_uart_debug_nr) { + case 0: + ets_install_putc1((void (*)(char)) &uart0_write_char); + break; + case 1: + ets_install_putc1((void (*)(char)) &uart1_write_char); + break; + case 2: + ets_install_putc1((void (*)(char)) &uart2_write_char); + break; + default: + ets_install_putc1(NULL); + break; + } } void uartSetDebug(uart_t* uart) { - if(uart == NULL || uart->num > 2) { - s_uart_debug_nr = -1; - //ets_install_putc1(NULL); - //return; - } else - if(s_uart_debug_nr == uart->num) { - return; - } else - s_uart_debug_nr = uart->num; - uart_install_putc(); + if(uart == NULL || uart->num > 2) { + s_uart_debug_nr = -1; + //ets_install_putc1(NULL); + //return; + } else + if(s_uart_debug_nr == uart->num) { + return; + } else + s_uart_debug_nr = uart->num; + uart_install_putc(); } int uartGetDebug() { - return s_uart_debug_nr; + return s_uart_debug_nr; } int log_printf(const char *format, ...) { - if(s_uart_debug_nr < 0){ - return 0; - } - static char loc_buf[64]; - char * temp = loc_buf; - int len; - va_list arg; - va_list copy; - va_start(arg, format); - va_copy(copy, arg); - len = vsnprintf(NULL, 0, format, arg); - va_end(copy); - if(len >= sizeof(loc_buf)){ - temp = (char*)malloc(len+1); - if(temp == NULL) { - return 0; - } - } - vsnprintf(temp, len+1, format, arg); + if(s_uart_debug_nr < 0){ + return 0; + } + static char loc_buf[64]; + char * temp = loc_buf; + int len; + va_list arg; + va_list copy; + va_start(arg, format); + va_copy(copy, arg); + len = vsnprintf(NULL, 0, format, arg); + va_end(copy); + if(len >= sizeof(loc_buf)){ + temp = (char*)malloc(len+1); + if(temp == NULL) { + return 0; + } + } + vsnprintf(temp, len+1, format, arg); #if !CONFIG_DISABLE_HAL_LOCKS - if(_uart_bus_array[s_uart_debug_nr].lock){ - xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); - ets_printf("%s", temp); - xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); - } else { - ets_printf("%s", temp); - } + if(_uart_bus_array[s_uart_debug_nr].lock){ + xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); + ets_printf("%s", temp); + xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); + } else { + ets_printf("%s", temp); + } #else - ets_printf("%s", temp); + ets_printf("%s", temp); #endif - va_end(arg); - if(len >= sizeof(loc_buf)){ - free(temp); - } - return len; + va_end(arg); + if(len >= sizeof(loc_buf)){ + free(temp); + } + return len; } /* @@ -622,16 +625,16 @@ int log_printf(const char *format, ...) */ 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); - } + 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(); + UART_MUTEX_LOCK(); + unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12; + UART_MUTEX_UNLOCK(); - return ret; + return ret; } /* @@ -650,45 +653,45 @@ void uartStartDetectBaudrate(uart_t *uart) { unsigned long uartDetectBaudrate(uart_t *uart) { - static bool uartStateDetectingBaudrate = false; + 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; - } + 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; - } + unsigned long divisor = uartBaudrateDetect(uart, true); + if (!divisor) { + return 0; + } - uart->dev->auto_baud.en = 0; - uartStateDetectingBaudrate = false; // Initialize for the next round + uart->dev->auto_baud.en = 0; + uartStateDetectingBaudrate = false; // Initialize for the next round - unsigned long baudrate = getApbFrequency() / divisor; + 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}; + 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; - } - } + 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]; + 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) { - return uart->dev->status.st_urx_out != 0; + return uart->dev->status.st_urx_out != 0; } From 6d7e8ebbd439922424c8fb7514d5439753824a3d Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 14:59:37 +0100 Subject: [PATCH 24/44] Cleaned up and commented the Interrupt example --- .../ESP32/examples/Serial/Interrupt/Interrupt.ino | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index e577bf9c90f..dbae06d3aa5 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,17 +1,21 @@ HardwareSerial hwSerial(0); HardwareSerial hwSerial2(2); -bool ok = true; - static void IRAM_ATTR onSerialRX(uint8_t c, void* user_arg){ hwSerial.print(c); - ((HardwareSerial*)user_arg)->print(c); + + // Cast the user_arg containing a void* to the Serial device, to HardwareSerial* to be used + HardwareSerial* serial = (HardwareSerial*)user_arg; + serial->print(c); } void setup() { hwSerial.begin(115200); hwSerial2.begin(115200); + + // The user_arg is expected to be a void pointer (void*), + // so take the reference of hwSerial2, and cast the HardwareSerial* to a void* hwSerial2.setRxInterrupt(onSerialRX, (void*)&hwSerial2); } From e3298eae2d518f28ab4bb5258f2f1a3a8408ac57 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 15:01:15 +0100 Subject: [PATCH 25/44] Changed serials to Serial and Serial2 --- .../ESP32/examples/Serial/Interrupt/Interrupt.ino | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index dbae06d3aa5..6010d080d63 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,8 +1,7 @@ -HardwareSerial hwSerial(0); -HardwareSerial hwSerial2(2); +// Serial, Serial1 and Serial2 are all of the type HardwareSerial. static void IRAM_ATTR onSerialRX(uint8_t c, void* user_arg){ - hwSerial.print(c); + Serial.print(c); // Cast the user_arg containing a void* to the Serial device, to HardwareSerial* to be used HardwareSerial* serial = (HardwareSerial*)user_arg; @@ -11,12 +10,12 @@ static void IRAM_ATTR onSerialRX(uint8_t c, void* user_arg){ void setup() { - hwSerial.begin(115200); - hwSerial2.begin(115200); + Serial.begin(115200); + Serial2.begin(115200); // The user_arg is expected to be a void pointer (void*), - // so take the reference of hwSerial2, and cast the HardwareSerial* to a void* - hwSerial2.setRxInterrupt(onSerialRX, (void*)&hwSerial2); + // so take the reference of Serial2, and cast the HardwareSerial* to a void* + Serial2.setRxInterrupt(onSerialRX, (void*)&Serial2); } void loop() From 3bfadf8e3134f9fffd766301b3c9be1979c18154 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 17:01:35 +0100 Subject: [PATCH 26/44] Changed example to buffer --- cores/esp32/esp32-hal-uart.c | 2 +- .../examples/Serial/Interrupt/Interrupt.ino | 38 ++++++++++++++----- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index a7f9425c99e..2f44b205ae6 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index 6010d080d63..d03c820d5ab 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,11 +1,18 @@ -// Serial, Serial1 and Serial2 are all of the type HardwareSerial. +#define BUFFER_SIZE 8 -static void IRAM_ATTR onSerialRX(uint8_t c, void* user_arg){ - Serial.print(c); +static volatile char inputBuffer[BUFFER_SIZE]; +static volatile size_t inputBufferLength = 0; + +// Please keep in mind, since the ESP32 is dual core, +// the interrupt will be running on the same core as the setRxInterrupt function was called on. +static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ + + // Cast the user_arg back to a array + char[] buffer = (char*)user_arg; - // Cast the user_arg containing a void* to the Serial device, to HardwareSerial* to be used - HardwareSerial* serial = (HardwareSerial*)user_arg; - serial->print(c); + if(inputBufferLength < BUFFER_SIZE){ + buffer[inputBufferLength++] = (char)character; + } } void setup() @@ -14,11 +21,22 @@ void setup() Serial2.begin(115200); // The user_arg is expected to be a void pointer (void*), - // so take the reference of Serial2, and cast the HardwareSerial* to a void* - Serial2.setRxInterrupt(onSerialRX, (void*)&Serial2); + // so take the reference of the variable, and it to a void* + Serial2.setRxInterrupt(onSerialRX, (void*)&inputBuffer); } void loop() -{ - delay(1); +{ + if(inputBufferLength == (BUFFER_SIZE - 1)){ + for(size_t i = 0; i < inputBufferLength; i++){ + Serial.write(inputBuffer[i]); + + // Clear the buffer + inputBuffer[i] = '\0'; + } + // Clear the bufferLength + inputBufferLength = 0; + } + + delay(1000); // Wait for one second } From 8cda769b9e21db5f12bc417bc49f446cc94a2a2f Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 17:13:55 +0100 Subject: [PATCH 27/44] Fixed compilation error --- libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index d03c820d5ab..c4af5af1cfb 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -8,7 +8,7 @@ static volatile size_t inputBufferLength = 0; static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ // Cast the user_arg back to a array - char[] buffer = (char*)user_arg; + char buffer[] = (char*)user_arg; if(inputBufferLength < BUFFER_SIZE){ buffer[inputBufferLength++] = (char)character; From 36ebb83d55f7319c5d590a4bf9bf995b3fe359de Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 17:21:41 +0100 Subject: [PATCH 28/44] Fixed compilation error --- libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index c4af5af1cfb..a74e7667626 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -8,7 +8,7 @@ static volatile size_t inputBufferLength = 0; static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ // Cast the user_arg back to a array - char buffer[] = (char*)user_arg; + char buffer* = (char*)user_arg; if(inputBufferLength < BUFFER_SIZE){ buffer[inputBufferLength++] = (char)character; From cf9850498b3b66299211bf63f91c42aa31f86b66 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 17:28:16 +0100 Subject: [PATCH 29/44] Lost my focus a bit, I think --- libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index a74e7667626..53e547b7f42 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -8,7 +8,7 @@ static volatile size_t inputBufferLength = 0; static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ // Cast the user_arg back to a array - char buffer* = (char*)user_arg; + char* buffer = (char*)user_arg; if(inputBufferLength < BUFFER_SIZE){ buffer[inputBufferLength++] = (char)character; From 0b2ae4ec8c63ab515b4eaef1af06545f72077d7b Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 18:04:24 +0100 Subject: [PATCH 30/44] Updated uart hal code, with comments regarding the interrupt clearing ;-) --- cores/esp32/esp32-hal-uart.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 2f44b205ae6..402239c6101 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -85,28 +85,42 @@ static void IRAM_ATTR _uart_isr() uart_t* uart; uart_interrupt_t *uart_interrupt; + // Loop through all the uart devices for(i=0;i<3;i++){ + + // Get the current uart device uart = &_uart_bus_array[i]; + + // Get the interrupt description for this uart device uart_interrupt = _uart_interrupt_array[i]; + // If there is no interrupt handle, skip the rest of the for loop's body if (uart->intr_handle == NULL) { continue; } + + // There are cases where bytes might come in between the time you check and handle the bytes and the time you clear the interrupt. + // In that case you will not get an ISR for those bytes. + // We had that happen and scratched heads for quite some time. + // There was another case that I do not recall at this time as well. + // https://github.com/espressif/arduino-esp32/pull/4656#discussion_r555780523 + uart->dev->int_clr.rxfifo_full = 1; + uart->dev->int_clr.frm_err = 1; + uart->dev->int_clr.rxfifo_tout = 1; + // Read until fifo is empty 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; + + // Check if an user defined interrupt handling function is present if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) { // Fully optimized code would not create the queue anymore if an function has been specified as an argument. (*uart_interrupt->func)(c, uart_interrupt->user_arg); }else if (uart->queue != NULL) { + // No user function is present, handle as you normally would xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } - } - - // Clear the interrupts after everything was read - uart->dev->int_clr.rxfifo_full = 1; - uart->dev->int_clr.frm_err = 1; - uart->dev->int_clr.rxfifo_tout = 1; + } } if (xHigherPriorityTaskWoken) { From 715f39916651cda7208da1e2e9f64baf3296484f Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 18:05:28 +0100 Subject: [PATCH 31/44] Reverted scripts back to it's original form --- .github/scripts/install-arduino-core-esp32.sh | 9 +++++++-- .github/scripts/install-platformio-esp32.sh | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh index aad48ba68ba..cf1026d6a71 100755 --- a/.github/scripts/install-arduino-core-esp32.sh +++ b/.github/scripts/install-arduino-core-esp32.sh @@ -15,8 +15,13 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then pip install requests > /dev/null fi - echo "Linking Core..." - ln -s $GITHUB_WORKSPACE "$ARDUINO_ESP32_PATH" + if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then + echo "Linking Core..." + ln -s $GITHUB_WORKSPACE esp32 + else + echo "Cloning Core Repository..." + git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 + fi echo "Updating Submodules ..." cd esp32 diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh index 88f3497af67..c065b0a029c 100755 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio-esp32.sh @@ -14,8 +14,13 @@ python -m platformio platform install https://github.com/platformio/platform-esp echo "Replacing the framework version ..." python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif32']['version'] = '*'; del data['packages']['framework-arduinoespressif32']['owner']; fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()" -echo "Linking Core..." -ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" +if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then + echo "Linking Core..." + ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" +else + echo "Cloning Core Repository ..." + git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 +fi echo "PlatformIO for ESP32 has been installed" echo "" From 4f80e5796fd32063dc353b14b3629b72cc5a8c29 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 18:15:22 +0100 Subject: [PATCH 32/44] Reverted on-push to stock form --- .github/scripts/on-push.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 71304447041..4995fc01277 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -61,14 +61,12 @@ if [ "$BUILD_PIO" -eq 0 ]; then else # PlatformIO Test source ./.github/scripts/install-platformio-esp32.sh - BOARD="esp32dev" - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino" && \ + BOARD="esp32dev" build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" && \ - build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino" + build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" #build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries" fi From f33c3322f34c898b38b7924e92f27aeb80ac013b Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Tue, 12 Jan 2021 19:47:50 +0100 Subject: [PATCH 33/44] Fixed ISR concurrency problems in example --- .../examples/Serial/Interrupt/Interrupt.ino | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index 53e547b7f42..8e39311e903 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,5 +1,8 @@ #define BUFFER_SIZE 8 +// This semaphore is here to handle the interruption of the loop when the interrupt is running. +SemaphoreHandle_t bufferSemaphore; + static volatile char inputBuffer[BUFFER_SIZE]; static volatile size_t inputBufferLength = 0; @@ -10,13 +13,20 @@ static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ // Cast the user_arg back to a array char* buffer = (char*)user_arg; - if(inputBufferLength < BUFFER_SIZE){ - buffer[inputBufferLength++] = (char)character; + BaseType_t xHighPriorityTaskWoken; + + if(xSemaphoreTakeFromISR(bufferSemaphore, &xHighPriorityTaskWoken) == pdTRUE){ + if(inputBufferLength < BUFFER_SIZE){ + buffer[inputBufferLength++] = (char)character; + } + xSemaphoreGiveFromISR(bufferSemaphore, &xHighPriorityTaskWoken); } } void setup() { + bufferSemaphore = xSemaphoreCreateBinary(); + Serial.begin(115200); Serial2.begin(115200); @@ -27,7 +37,7 @@ void setup() void loop() { - if(inputBufferLength == (BUFFER_SIZE - 1)){ + if(xSemaphoreTake(bufferSemaphore, portMAX_DELAY) == pdTRUE && inputBufferLength == (BUFFER_SIZE - 1)){ for(size_t i = 0; i < inputBufferLength; i++){ Serial.write(inputBuffer[i]); @@ -36,6 +46,8 @@ void loop() } // Clear the bufferLength inputBufferLength = 0; + + xSemaphoreGive(bufferSemaphore); } delay(1000); // Wait for one second From 5beb727bff7e5450fa5bbb0fec46b6fe64f028d7 Mon Sep 17 00:00:00 2001 From: timkoers Date: Tue, 12 Jan 2021 20:41:52 +0100 Subject: [PATCH 34/44] Update on-push.sh --- .github/scripts/on-push.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 4995fc01277..af94a5b66f9 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -61,7 +61,7 @@ if [ "$BUILD_PIO" -eq 0 ]; then else # PlatformIO Test source ./.github/scripts/install-platformio-esp32.sh - BOARD="esp32dev" + BOARD="esp32dev" build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ From 52b8a4140e5bb2ca9faf6859d4e77968014e977c Mon Sep 17 00:00:00 2001 From: timkoers Date: Tue, 12 Jan 2021 20:42:10 +0100 Subject: [PATCH 35/44] Update on-push.sh --- .github/scripts/on-push.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index af94a5b66f9..e0e14ec2b26 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -43,7 +43,6 @@ if [ "$BUILD_PIO" -eq 0 ]; then build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" - elif [ "$OS_IS_MACOS" == "1" ]; then build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ From f948c7863dd1a8790f2f02c06143366601f28312 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 13 Jan 2021 12:14:00 +0100 Subject: [PATCH 36/44] Replaced tabs with spaces ;-) --- cores/esp32/esp32-hal-uart.c | 879 +++++++++++++++++------------------ 1 file changed, 439 insertions(+), 440 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 402239c6101..3e5e2a5106a 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -30,28 +30,27 @@ #include "soc/rtc.h" #include "esp_intr_alloc.h" -#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))) +#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))) static int s_uart_debug_nr = 0; struct uart_struct_t { - uart_dev_t* dev; + uart_dev_t* dev; #if !CONFIG_DISABLE_HAL_LOCKS - xSemaphoreHandle lock; + xSemaphoreHandle lock; #endif - uint8_t num; - xQueueHandle queue; - intr_handle_t intr_handle; + uint8_t num; + xQueueHandle queue; + intr_handle_t intr_handle; }; struct uart_interrupt_struct_t { - void (*func)(uint8_t, void*); - void *user_arg; - uart_t *dev; + void (*func)(uint8_t, void*); + void *user_arg; + uart_t *dev; }; #if CONFIG_DISABLE_HAL_LOCKS @@ -59,18 +58,18 @@ struct uart_interrupt_struct_t #define UART_MUTEX_UNLOCK() static uart_t _uart_bus_array[3] = { - {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} + {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} }; #else -#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS) -#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) +#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[3] = { - {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, - {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} + {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, + {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} }; #endif @@ -80,52 +79,52 @@ static uart_interrupt_t *_uart_interrupt_array[3] = {NULL, NULL, NULL}; static void IRAM_ATTR _uart_isr() { - uint8_t i, c; - BaseType_t xHigherPriorityTaskWoken; - uart_t* uart; - uart_interrupt_t *uart_interrupt; - - // Loop through all the uart devices - for(i=0;i<3;i++){ - - // Get the current uart device - uart = &_uart_bus_array[i]; - - // Get the interrupt description for this uart device - uart_interrupt = _uart_interrupt_array[i]; - - // If there is no interrupt handle, skip the rest of the for loop's body - if (uart->intr_handle == NULL) { - continue; - } - - // There are cases where bytes might come in between the time you check and handle the bytes and the time you clear the interrupt. - // In that case you will not get an ISR for those bytes. - // We had that happen and scratched heads for quite some time. - // There was another case that I do not recall at this time as well. - // https://github.com/espressif/arduino-esp32/pull/4656#discussion_r555780523 - uart->dev->int_clr.rxfifo_full = 1; - uart->dev->int_clr.frm_err = 1; - uart->dev->int_clr.rxfifo_tout = 1; - - // Read until fifo is empty - 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; - - // Check if an user defined interrupt handling function is present - if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) { - // Fully optimized code would not create the queue anymore if an function has been specified as an argument. - (*uart_interrupt->func)(c, uart_interrupt->user_arg); - }else if (uart->queue != NULL) { - // No user function is present, handle as you normally would - xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); - } - } - } - - if (xHigherPriorityTaskWoken) { - portYIELD_FROM_ISR(); - } + uint8_t i, c; + BaseType_t xHigherPriorityTaskWoken; + uart_t* uart; + uart_interrupt_t *uart_interrupt; + + // Loop through all the uart devices + for(i=0;i<3;i++){ + + // Get the current uart device + uart = &_uart_bus_array[i]; + + // Get the interrupt description for this uart device + uart_interrupt = _uart_interrupt_array[i]; + + // If there is no interrupt handle, skip the rest of the for loop's body + if (uart->intr_handle == NULL) { + continue; + } + + // There are cases where bytes might come in between the time you check and handle the bytes and the time you clear the interrupt. + // In that case you will not get an ISR for those bytes. + // We had that happen and scratched heads for quite some time. + // There was another case that I do not recall at this time as well. + // https://github.com/espressif/arduino-esp32/pull/4656#discussion_r555780523 + uart->dev->int_clr.rxfifo_full = 1; + uart->dev->int_clr.frm_err = 1; + uart->dev->int_clr.rxfifo_tout = 1; + + // Read until fifo is empty + 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; + + // Check if an user defined interrupt handling function is present + if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) { + // Fully optimized code would not create the queue anymore if an function has been specified as an argument. + (*uart_interrupt->func)(c, uart_interrupt->user_arg); + }else if (uart->queue != NULL) { + // No user function is present, handle as you normally would + xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); + } + } + } + + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } } /** @@ -143,30 +142,30 @@ static void IRAM_ATTR _uart_isr() */ void uartEnableRxInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(uint8_t, void*), void* user_arg) { - UART_MUTEX_LOCK(); - 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; + UART_MUTEX_LOCK(); + 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; - if(arg != NULL){ - (*arg) = malloc(sizeof(uart_interrupt_t)); - (*arg)->func = func; - (*arg)->dev = uart; - (*arg)->user_arg = user_arg; - - if(_uart_interrupt_array[uart->num]){ - free(_uart_interrupt_array[uart->num]); - } + if(arg != NULL){ + (*arg) = malloc(sizeof(uart_interrupt_t)); + (*arg)->func = func; + (*arg)->dev = uart; + (*arg)->user_arg = user_arg; + + if(_uart_interrupt_array[uart->num]){ + free(_uart_interrupt_array[uart->num]); + } - _uart_interrupt_array[uart->num] = (*arg); - } + _uart_interrupt_array[uart->num] = (*arg); + } - esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); - UART_MUTEX_UNLOCK(); + esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); + UART_MUTEX_UNLOCK(); } /** @@ -182,455 +181,455 @@ void uartEnableRxInterrupt(uart_t* uart, uart_interrupt_t **arg, void (*func)(ui */ void uartDisableRxInterrupt(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_LOCK(); + uart->dev->conf1.val = 0; + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; - // Free uart rx interrupt - if(_uart_interrupt_array[uart->num]){ - free(_uart_interrupt_array[uart->num]); - } + // Free uart rx interrupt + if(_uart_interrupt_array[uart->num]){ + free(_uart_interrupt_array[uart->num]); + } - _uart_interrupt_array[uart->num] = NULL; + _uart_interrupt_array[uart->num] = NULL; - esp_intr_free(uart->intr_handle); - uart->intr_handle = NULL; + esp_intr_free(uart->intr_handle); + uart->intr_handle = NULL; - UART_MUTEX_UNLOCK(); + UART_MUTEX_UNLOCK(); } void uartDetachRx(uart_t* uart, uint8_t rxPin) { - if(uart == NULL) { - return; - } - pinMatrixInDetach(rxPin, false, false); - uartDisableRxInterrupt(uart); + if(uart == NULL) { + return; + } + pinMatrixInDetach(rxPin, false, false); + uartDisableRxInterrupt(uart); } void uartDetachTx(uart_t* uart, uint8_t txPin) { - if(uart == NULL) { - return; - } - pinMatrixOutDetach(txPin, false, false); + if(uart == NULL) { + return; + } + pinMatrixOutDetach(txPin, 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); - uartEnableRxInterrupt(uart, NULL, NULL, NULL); + if(uart == NULL || rxPin > 39) { + return; + } + pinMode(rxPin, INPUT); + pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); + uartEnableRxInterrupt(uart, NULL, NULL, NULL); } 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); + 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) { - if(uart_nr > 2) { - return NULL; - } + if(uart_nr > 2) { + return NULL; + } - if(rxPin == -1 && txPin == -1) { - return NULL; - } + if(rxPin == -1 && txPin == -1) { + return NULL; + } - uart_t* uart = &_uart_bus_array[uart_nr]; + 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; - } - } + 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); - } 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); - } 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; + 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); + } 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); + } 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); + if(uart == NULL) { + return; + } + removeApbChangeCallback(uart, uart_on_apb_change); - UART_MUTEX_LOCK(); - if(uart->queue != NULL) { - vQueueDelete(uart->queue); - uart->queue = NULL; - } + UART_MUTEX_LOCK(); + if(uart->queue != NULL) { + vQueueDelete(uart->queue); + uart->queue = NULL; + } - uart->dev->conf0.val = 0; + uart->dev->conf0.val = 0; - UART_MUTEX_UNLOCK(); + UART_MUTEX_UNLOCK(); - uartDetachRx(uart, rxPin); - uartDetachTx(uart, txPin); + uartDetachRx(uart, rxPin); + uartDetachTx(uart, txPin); } size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { - if(uart == NULL) { - return 0; - } + 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 NULL; - } - } - UART_MUTEX_UNLOCK(); + 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 NULL; + } + } + UART_MUTEX_UNLOCK(); - return new_size; + 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; + 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) ; + 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; + 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; - 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; - 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 c; + UART_MUTEX_LOCK(); + //disable interrupts + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; + 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; + 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; + 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; + 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); - uart->dev->fifo.rw_byte = c; - UART_MUTEX_UNLOCK(); + if(uart == NULL) { + return; + } + UART_MUTEX_LOCK(); + while(uart->dev->status.txfifo_cnt == 0x7F); + uart->dev->fifo.rw_byte = c; + UART_MUTEX_UNLOCK(); } void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) { - if(uart == NULL) { - return; - } - UART_MUTEX_LOCK(); - while(len) { - while(uart->dev->status.txfifo_cnt == 0x7F); - uart->dev->fifo.rw_byte = *data++; - len--; - } - UART_MUTEX_UNLOCK(); + if(uart == NULL) { + return; + } + UART_MUTEX_LOCK(); + while(len) { + while(uart->dev->status.txfifo_cnt == 0x7F); + uart->dev->fifo.rw_byte = *data++; + len--; + } + UART_MUTEX_UNLOCK(); } void uartFlush(uart_t* uart) { - uartFlushTxOnly(uart,true); + uartFlushTxOnly(uart,true); } void uartFlushTxOnly(uart_t* uart, bool txOnly) { - if(uart == NULL) { - return; - } + if(uart == NULL) { + return; + } - UART_MUTEX_LOCK(); - 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. + UART_MUTEX_LOCK(); + 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)); - } + // 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); - } - - UART_MUTEX_UNLOCK(); + xQueueReset(uart->queue); + } + + 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(); + 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; - 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; - if(uart->queue != NULL ) { - xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); - } - } - UART_MUTEX_UNLOCK(); + 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; + 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; + if(uart->queue != NULL ) { + xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken); + } + } + UART_MUTEX_UNLOCK(); - // wait TX empty - while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); - } 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(); - } + // wait TX empty + while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); + } 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; - } + 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; - } + 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); + return ((getApbFrequency()<<4)/clk_div); } static void IRAM_ATTR uart0_write_char(char c) { - while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); - ESP_REG(DR_REG_UART_BASE) = c; + while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); + ESP_REG(DR_REG_UART_BASE) = c; } static void IRAM_ATTR uart1_write_char(char c) { - while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); - ESP_REG(DR_REG_UART1_BASE) = c; + while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); + ESP_REG(DR_REG_UART1_BASE) = c; } static void IRAM_ATTR uart2_write_char(char c) { - while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); - ESP_REG(DR_REG_UART2_BASE) = c; + while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); + ESP_REG(DR_REG_UART2_BASE) = c; } void uart_install_putc() { - switch(s_uart_debug_nr) { - case 0: - ets_install_putc1((void (*)(char)) &uart0_write_char); - break; - case 1: - ets_install_putc1((void (*)(char)) &uart1_write_char); - break; - case 2: - ets_install_putc1((void (*)(char)) &uart2_write_char); - break; - default: - ets_install_putc1(NULL); - break; - } + switch(s_uart_debug_nr) { + case 0: + ets_install_putc1((void (*)(char)) &uart0_write_char); + break; + case 1: + ets_install_putc1((void (*)(char)) &uart1_write_char); + break; + case 2: + ets_install_putc1((void (*)(char)) &uart2_write_char); + break; + default: + ets_install_putc1(NULL); + break; + } } void uartSetDebug(uart_t* uart) { - if(uart == NULL || uart->num > 2) { - s_uart_debug_nr = -1; - //ets_install_putc1(NULL); - //return; - } else - if(s_uart_debug_nr == uart->num) { - return; - } else - s_uart_debug_nr = uart->num; - uart_install_putc(); + if(uart == NULL || uart->num > 2) { + s_uart_debug_nr = -1; + //ets_install_putc1(NULL); + //return; + } else + if(s_uart_debug_nr == uart->num) { + return; + } else + s_uart_debug_nr = uart->num; + uart_install_putc(); } int uartGetDebug() { - return s_uart_debug_nr; + return s_uart_debug_nr; } int log_printf(const char *format, ...) { - if(s_uart_debug_nr < 0){ - return 0; - } - static char loc_buf[64]; - char * temp = loc_buf; - int len; - va_list arg; - va_list copy; - va_start(arg, format); - va_copy(copy, arg); - len = vsnprintf(NULL, 0, format, arg); - va_end(copy); - if(len >= sizeof(loc_buf)){ - temp = (char*)malloc(len+1); - if(temp == NULL) { - return 0; - } - } - vsnprintf(temp, len+1, format, arg); + if(s_uart_debug_nr < 0){ + return 0; + } + static char loc_buf[64]; + char * temp = loc_buf; + int len; + va_list arg; + va_list copy; + va_start(arg, format); + va_copy(copy, arg); + len = vsnprintf(NULL, 0, format, arg); + va_end(copy); + if(len >= sizeof(loc_buf)){ + temp = (char*)malloc(len+1); + if(temp == NULL) { + return 0; + } + } + vsnprintf(temp, len+1, format, arg); #if !CONFIG_DISABLE_HAL_LOCKS - if(_uart_bus_array[s_uart_debug_nr].lock){ - xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); - ets_printf("%s", temp); - xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); - } else { - ets_printf("%s", temp); - } + if(_uart_bus_array[s_uart_debug_nr].lock){ + xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); + ets_printf("%s", temp); + xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); + } else { + ets_printf("%s", temp); + } #else - ets_printf("%s", temp); + ets_printf("%s", temp); #endif - va_end(arg); - if(len >= sizeof(loc_buf)){ - free(temp); - } - return len; + va_end(arg); + if(len >= sizeof(loc_buf)){ + free(temp); + } + return len; } /* @@ -639,16 +638,16 @@ int log_printf(const char *format, ...) */ 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); - } + 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(); + UART_MUTEX_LOCK(); + unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12; + UART_MUTEX_UNLOCK(); - return ret; + return ret; } /* @@ -667,45 +666,45 @@ void uartStartDetectBaudrate(uart_t *uart) { unsigned long uartDetectBaudrate(uart_t *uart) { - static bool uartStateDetectingBaudrate = false; + 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; - } + 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; - } + unsigned long divisor = uartBaudrateDetect(uart, true); + if (!divisor) { + return 0; + } - uart->dev->auto_baud.en = 0; - uartStateDetectingBaudrate = false; // Initialize for the next round + uart->dev->auto_baud.en = 0; + uartStateDetectingBaudrate = false; // Initialize for the next round - unsigned long baudrate = getApbFrequency() / divisor; + 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}; + 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; - } - } + 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]; + 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) { - return uart->dev->status.st_urx_out != 0; + return uart->dev->status.st_urx_out != 0; } From 44411904e75836e99f6797f5b8f8f62e2c275e43 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 13 Jan 2021 12:46:05 +0100 Subject: [PATCH 37/44] And fixed the remaining things --- cores/esp32/esp32-hal-uart.c | 37 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 3e5e2a5106a..35ec5715481 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -369,22 +369,21 @@ uint32_t uartAvailableForWrite(uart_t* uart) } 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; - 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; - 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 c; + UART_MUTEX_LOCK(); + //disable interrupts + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; + 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; + 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; } uint8_t uartRead(uart_t* uart) @@ -395,7 +394,7 @@ uint8_t uartRead(uart_t* uart) uint8_t c; if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { - uartRxFifoToQueue(uart); + uartRxFifoToQueue(uart); } if(xQueueReceive(uart->queue, &c, 0)) { return c; @@ -411,7 +410,7 @@ uint8_t uartPeek(uart_t* uart) uint8_t c; if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { - uartRxFifoToQueue(uart); + uartRxFifoToQueue(uart); } if(xQueuePeek(uart->queue, &c, 0)) { return c; @@ -688,7 +687,7 @@ uartDetectBaudrate(uart_t *uart) 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 + for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate { if (baudrate <= default_rates[i]) { From ce3952dbc06a60e7403fa42de0cd24d25936bc9f Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Wed, 13 Jan 2021 12:50:46 +0100 Subject: [PATCH 38/44] Fixed whitespace refactoring and compilation error --- cores/esp32/esp32-hal-uart.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 35ec5715481..9e7a77fbd82 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -33,11 +33,12 @@ #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))) static int s_uart_debug_nr = 0; struct uart_struct_t { - uart_dev_t* dev; + uart_dev_t *dev; #if !CONFIG_DISABLE_HAL_LOCKS xSemaphoreHandle lock; #endif @@ -119,7 +120,7 @@ static void IRAM_ATTR _uart_isr() // No user function is present, handle as you normally would xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } - } + } } if (xHigherPriorityTaskWoken) { @@ -369,9 +370,9 @@ uint32_t uartAvailableForWrite(uart_t* uart) } void uartRxFifoToQueue(uart_t* uart) -{ +{ uint8_t c; - UART_MUTEX_LOCK(); + UART_MUTEX_LOCK(); //disable interrupts uart->dev->int_ena.val = 0; uart->dev->int_clr.val = 0xffffffff; @@ -384,6 +385,7 @@ void uartRxFifoToQueue(uart_t* uart) 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) @@ -394,7 +396,7 @@ uint8_t uartRead(uart_t* uart) uint8_t c; if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { - uartRxFifoToQueue(uart); + uartRxFifoToQueue(uart); } if(xQueueReceive(uart->queue, &c, 0)) { return c; @@ -410,7 +412,7 @@ uint8_t uartPeek(uart_t* uart) uint8_t c; if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) { - uartRxFifoToQueue(uart); + uartRxFifoToQueue(uart); } if(xQueuePeek(uart->queue, &c, 0)) { return c; From d8f54eeed6fe24d66b45cedd2098207e507b39b3 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Sun, 17 Jan 2021 12:26:41 +0100 Subject: [PATCH 39/44] Added documentation to the examples and added another Interrupt handling example --- cores/esp32/esp32-hal-uart.c | 2 +- .../examples/Serial/Interrupt/Interrupt.ino | 25 ++++++++++++++++++- .../Serial/NoInterrupt/NoInterrupt.ino | 24 ++++++++++++++---- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 9e7a77fbd82..570da33b6f2 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -78,7 +78,7 @@ static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old static uart_interrupt_t *_uart_interrupt_array[3] = {NULL, NULL, NULL}; -static void IRAM_ATTR _uart_isr() +static void IRAM_ATTR _uart_isr(void *arg) { uint8_t i, c; BaseType_t xHigherPriorityTaskWoken; diff --git a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino index 8e39311e903..6a46cd511e8 100644 --- a/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino +++ b/libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino @@ -1,3 +1,12 @@ +/** Tim Koers - 2021 + * + * This sketch shows the usage of a semaphore to receive Serial data. + * You can safely use this in a FreeRTOS environment and use the semaphore from different tasks on different CPU cores. + * However, the InterruptQueue example is much more efficient, since it uses less code. + * This sketch assumes that when Hi is sent, the device returns an 8 byte message. + * + */ + #define BUFFER_SIZE 8 // This semaphore is here to handle the interruption of the loop when the interrupt is running. @@ -6,6 +15,8 @@ SemaphoreHandle_t bufferSemaphore; static volatile char inputBuffer[BUFFER_SIZE]; static volatile size_t inputBufferLength = 0; +bool messageSent = false; + // Please keep in mind, since the ESP32 is dual core, // the interrupt will be running on the same core as the setRxInterrupt function was called on. static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ @@ -37,6 +48,14 @@ void setup() void loop() { + if(!messageSent){ + Serial.println("Hi"); + messageSent = true; + } + + // Check if the semaphore can be taken and if the inputBuffer length is long enough. + // Please keep in mind, since the variable inputBufferLength is also accessed inside the IRQ handler, + // the semaphore needs to be taken BEFORE you can access that variable. if(xSemaphoreTake(bufferSemaphore, portMAX_DELAY) == pdTRUE && inputBufferLength == (BUFFER_SIZE - 1)){ for(size_t i = 0; i < inputBufferLength; i++){ Serial.write(inputBuffer[i]); @@ -47,8 +66,12 @@ void loop() // Clear the bufferLength inputBufferLength = 0; + // Give back the semaphore xSemaphoreGive(bufferSemaphore); + + // Allow the system to request another data set + messageSent = false; } - delay(1000); // Wait for one second + delay(10); // Wait for 10ms to allow some data to come in } diff --git a/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino b/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino index ae3d51ab0b5..267d6e656e6 100644 --- a/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino +++ b/libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino @@ -1,13 +1,27 @@ -HardwareSerial hwSerial(0); -HardwareSerial hwSerial2(2); +/** Tim Koers - 2021 + * + * This sketch shows the 'regular' way of receiving Serial data and using it. + * In Arduino Libraries that communicate with a UART peripheral/device, it is seen many times that a delay is + * added after each sent message in order to wait for the answer of the device. That is very inefficient since, + * if not done properly, it might block the CPU (-core) and the function will take x milliseconds/seconds to return. + * This sketch assumes that when Hi is sent, the device returns an 8 byte message. + * + */ void setup() { - hwSerial.begin(115200); - hwSerial2.begin(115200); + Serial.begin(115200); + Serial2.begin(115200); } void loop() { - hwSerial.print(hwSerial2.read()); + Serial.println("Hi"); + // Now wait for the response to arrive + delay(1000); + + // The response MIGHT have arrived, not sure though + if(Serial.available() == 8){ + Serial.print(Serial2.read()); + } } From b3511e5de285523486f45e737868a54a21ab92c9 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Sun, 17 Jan 2021 12:27:07 +0100 Subject: [PATCH 40/44] Don't forget to actually add the example ;-) --- .../Serial/InterruptQueue/InterruptQueue.ino | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino diff --git a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino new file mode 100644 index 00000000000..8d2d0a10227 --- /dev/null +++ b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino @@ -0,0 +1,59 @@ +/** Tim Koers - 2021 + * + * This sketch shows the usage of an queue, to store and read the characters that are sent to the interrupt. + * You can safely use this in a FreeRTOS environment and use the queue from different tasks on different CPU cores. + * This sketch assumes that when Hi is sent, the device returns an 8 byte message. + * + */ + +#define BUFFER_SIZE 8 + +// This queue is here to handle the interruption of the loop when the interrupt is running. +Queue_t bufferQueue; + +bool messageSent = false; + +// Please keep in mind, since the ESP32 is dual core, +// the interrupt will be running on the same core as the setRxInterrupt function was called on. +static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ + + BaseType_t xHighPriorityTaskWoken; + + if(!xQueueSendFromISR(bufferQueue, &character, &xHighPriorityTaskWoken) == pdTRUE){ + log_e("IRQ", "Failed to put character onto the queue\n"); + } +} + +void setup() +{ + bufferQueue = xQueueCreate(BUFFER_SIZE * 4, sizeof(char)); // Create a queue that can hold 4 messages of 8-bytes each. + + assert(bufferQueue != NULL); + + Serial.begin(115200); + Serial2.begin(115200); + + Serial2.setRxInterrupt(onSerialRX, NULL); +} + +void loop() +{ + if(!messageSent){ + Serial.println("Hi"); + messageSent = true; + } + + // Check if data in the queue and check if there is a complete message (8-bytes) in the queue + if(!(uxQueueMessagesWaiting(bufferQueue) % RESPONSE_SIZE)){ + char c; + // Check if the queue is not empty, 0 % 8 returns 0 instead, so does 24 % 8 + while(uxQueueMessagesWaiting(bufferQueue) > 0){ + // Get the character from the queue, but don't block if someone else is busy with the queue + if(xQueueReceive(bufferQueue, &c, 0) == pdTRUE) + Serial.write(c); + } + + // Allow the system to request another data set + messageSent = false; + } +} From 32a7446fb48644958ea5fb303154597d2c2891ab Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Sun, 17 Jan 2021 12:30:55 +0100 Subject: [PATCH 41/44] Fixed wrong define name --- .../ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino index 8d2d0a10227..03fe370408f 100644 --- a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino +++ b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino @@ -44,7 +44,7 @@ void loop() } // Check if data in the queue and check if there is a complete message (8-bytes) in the queue - if(!(uxQueueMessagesWaiting(bufferQueue) % RESPONSE_SIZE)){ + if(!(uxQueueMessagesWaiting(bufferQueue) % BUFFER_SIZE)){ char c; // Check if the queue is not empty, 0 % 8 returns 0 instead, so does 24 % 8 while(uxQueueMessagesWaiting(bufferQueue) > 0){ From f89b634529d160b21a740cd0c4d0a28e33de8bcb Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Sun, 17 Jan 2021 12:35:10 +0100 Subject: [PATCH 42/44] Added include for queue.h --- .../ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino index 03fe370408f..25e99342e66 100644 --- a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino +++ b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino @@ -6,6 +6,7 @@ * */ +#include #define BUFFER_SIZE 8 // This queue is here to handle the interruption of the loop when the interrupt is running. From 41a869a83345ce048d97c83ad03d689dfad059b0 Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Sun, 17 Jan 2021 12:39:34 +0100 Subject: [PATCH 43/44] Not sure how I got confused with Queue_t, but fixed --- .../ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino index 25e99342e66..1490fd91b13 100644 --- a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino +++ b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino @@ -6,11 +6,10 @@ * */ -#include #define BUFFER_SIZE 8 // This queue is here to handle the interruption of the loop when the interrupt is running. -Queue_t bufferQueue; +QueueHandle_t bufferQueue; bool messageSent = false; From 12b872527d33ddb0b6c75df052f725091c131d8f Mon Sep 17 00:00:00 2001 From: Tim Koers Date: Sun, 17 Jan 2021 12:42:27 +0100 Subject: [PATCH 44/44] Fixed --- .../ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino index 1490fd91b13..945eaebb7ac 100644 --- a/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino +++ b/libraries/ESP32/examples/Serial/InterruptQueue/InterruptQueue.ino @@ -19,7 +19,7 @@ static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ BaseType_t xHighPriorityTaskWoken; - if(!xQueueSendFromISR(bufferQueue, &character, &xHighPriorityTaskWoken) == pdTRUE){ + if(xQueueSendFromISR(bufferQueue, &character, &xHighPriorityTaskWoken) != pdTRUE){ log_e("IRQ", "Failed to put character onto the queue\n"); } }