Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds UART RX IRQ Callback with onReceive() #6134

Merged
merged 3 commits into from Jan 17, 2022

Conversation

SuGlider
Copy link
Collaborator

@SuGlider SuGlider commented Jan 13, 2022

Summary

This PR adds a new feature to UART / Arduino Serial API.

Users have requested a feature related to UART ISR that allow a callback function to be executed as soon as data arrives to UART port. This PR adds Serial.onReceive() functionality to Arduino Hardware Serial.

Example:

void UART_RX_IRQ() {
  uint16_t size = Serial.available();
  Serial.printf("Got %d bytes on Serial to read\n", size);
  while(Serial.available())  {
    Serial.write(Serial.read());
  }
  Serial.printf("\nSerial data processed!\n");
}

void setup() {
  Serial.begin(115200);
  Serial.onReceive(UART_RX_IRQ);
  Serial.println("Send data to UART0 in order to activate the RX callback");
}

void loop() {
  Serial.println("Sleeping for 10 seconds...");
  delay(10000);
}

Output of the example in the ESP32-C3 (Hello World! sent to default Serial port using Arduino Serial Monitor):

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd6100,len:0x420
load:0x403ce000,len:0x90c
load:0x403d0000,len:0x236c
SHA-256 comparison failed:
Calculated: ccb0d00bac7e84e1d90a12e4f75f4ab6c5f7e71bb209afd5819c4c9557a6db71
Expected: c9cf160580940ec7801c73b16423824e72ad12055c732e83ce66332240af42a7
Attempting to boot anyway...
entry 0x403ce000
Send data to UART0 in order to activate the RX callback
Sleeping for 10 seconds...
Sleeping for 10 seconds...
Got 13 bytes on Serial to read
Hello World!

Serial data processed!
Sleeping for 10 seconds...

Impact

It includes a new feature to Arduino Hardware Serial.
It needs to be documented (@pedrominatel)

Related links

Initial PR requesting the feature
PR #4656
PR #3376

Related Issues
Fixes #5678
Fixes #5620
Fixes #5472
Fixes #6102

@SuGlider SuGlider added this to the 2.0.3 milestone Jan 13, 2022
@SuGlider SuGlider self-assigned this Jan 13, 2022
@me-no-dev
Copy link
Member

I like it :) let's discuss my single comment and we can merge it.

@SuGlider
Copy link
Collaborator Author

Adds LOCKs to UART Event Callback Task.

Copy link
Collaborator Author

@SuGlider SuGlider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for merging.

cores/esp32/esp32-hal-uart.c Show resolved Hide resolved
@FredGlaum
Copy link

Hi I recently also experienced buffer overrun errors on high baudrates - I am glad to see there is solution in the works. When can we expect to use the onReceive() event callback for the Arduino/PlatformIO ESP32 development.

I tried the latest dev and stable core releases and its not there.

@SuGlider SuGlider mentioned this pull request Jan 24, 2022
1 task
@SuGlider
Copy link
Collaborator Author

Hi I recently also experienced buffer overrun errors on high baudrates - I am glad to see there is solution in the works. When can we expect to use the onReceive() event callback for the Arduino/PlatformIO ESP32 development.

I tried the latest dev and stable core releases and its not there.

PlaformIO ESP32 still uses old Arduino Core version 1.0.6.
This patch depends on IDF and it will be available in Arduino Core version 2.0.3+.
You can try to manually setup your PlatformIO to use the latest master version to use this feature.

Maybe this link may help you:
https://community.platformio.org/t/use-different-version-of-arduino-framework-on-espressif-platform/23669

@gemu2015
Copy link

@SuGlider
could you please verify this pr since it seems to break UART receive in some users of Tasmota.
under some circumstances receive stops and only reverts after a restart. this is fixed after reverting this pr.
since this option is only needed in rare cases i would also prefer to not enable it by default since it creates an extra queue and task wasting memory and cpu cycles.
probably only create queue and task when uartOnReceive is actually called ?

@SuGlider
Copy link
Collaborator Author

@gemu2015
This PR has an issue fixed and merged to master in PR #6201
This shall fix the issue you report as "break UART receive".

@SuGlider
Copy link
Collaborator Author

probably only create queue and task when uartOnReceive is actually called ?

This is not possible because of IDF UART driver setup.
IDF is the base for all HAL layer of ESP32 Arduino in Arduino Core Version 2.0.0+.

@gemu2015
Copy link

@gemu2015
This PR has an issue fixed and merged to master in PR #6201
This shall fix the issue you report as "break UART receive".

however we do not use HardwareSerial::onReceive() at all and get locks too ??

@SuGlider
Copy link
Collaborator Author

SuGlider commented Feb 17, 2022

however we do not use HardwareSerial::onReceive() at all and get locks too ??

As said it is fixed. You are talking about WIP - the final version 2.0.3 is not released yet.
The decision of merging isolated PRs to other projects is beyond our control.

The lock issue will only occur if the sketch actually calls onReceive( fucntion ), otherwise it will never lock.
Anyway, it has been fixed in #6201
Master branch is free of issues with UART at this time, as the final release of 2.0.3 will be when the time arrives.

@Jason2866
Copy link
Collaborator

For completness tested with applying #6201 too. Still issues. Maybe it is related to #6326

@SuGlider
Copy link
Collaborator Author

SuGlider commented Mar 1, 2022

@Jason2866 - Please check #6364 because it shall be the final version of HardwareSerial and esp32-hal-uart for the next Arduino Core Version 2.0.3.

I fixed a number of issues related to HardwareSerial overflows, locking issues, onReceive() and others.

@SuGlider
Copy link
Collaborator Author

SuGlider commented Mar 1, 2022

@SuGlider could you please verify this pr since it seems to break UART receive in some users of Tasmota. under some circumstances receive stops and only reverts after a restart. this is fixed after reverting this pr. since this option is only needed in rare cases i would also prefer to not enable it by default since it creates an extra queue and task wasting memory and cpu cycles. probably only create queue and task when uartOnReceive is actually called ?

@gemu2015
#6364 does what you requested - task is only created when Serial.onReceive() is actually used, otherwise the task is never created. The queue is created as part of UART IDF initialization, thus it is created always. The queue is only checked in the task, thus it won't waste CPU cycles anymore. This queue is very small and waste less than 64 bytes - no harm. More memory is really allocated for the task that will only be created when the user really wants to use onReveive().

Locking issue is fixed as well.

@Jason2866
Copy link
Collaborator

@SuGlider thx, will do a build with. @gemu2015 when it is compiled i will drop you a note.

Jason2866 added a commit to Jason2866/arduino-esp32 that referenced this pull request Mar 16, 2022
* Fix wdt OTA update

* Fix ESP32-Solo WDT on HTTP OTA update

Co-authored-by: Theo Arends <11044339+arendst@users.noreply.github.com>

* Fix ESP32-Solo WDT on HTTP OTA update

* Fix ESP32-Solo WDT on HTTP OTA update

Co-authored-by: Theo Arends <11044339+arendst@users.noreply.github.com>

* IDF master c69f0ec32

* Fix WDT only for solo core

* IDF master 58022f859

* IDF master 606557b48

* IDF master 8131d6f46

* IDF master 59aa60d52

* IDF master 83956ebba

* IDF master 83956ebbae

* IDF master b1c3ee71c5

* IDF master 2c49af9e75

* IDF master eb1a66e7c9

* IDF master a20df743f1

* Fix build compilation due to changes in the HW_TIMER's structs

* Fix compilation warnings and errors with USB

* Update USBCDC.cpp

* Update CMakeLists.txt

* IDF master b63ec47238

* Update libarduino_tinyusb.a

* Update HWCDC.cpp

* IDF master 5f38b766a8

* IDF master b1f851b8f8

* IDF master 61299f879e

* Delete tools/sdk/esp32/include/coap directory

* Delete tools/sdk/esp32c3/include/coap directory

* Delete tools/sdk/esp32s2/include/coap directory

* solve conflicts

* force Dynamic Buffer instead of Static ones

* Remove debug if

* Resolve conflicts

* Revert espressif#5861

* add GPIO defines for C3

* Edit sd_diskio to check card status

* Update CMakeLists.txt

* Delete libraries/RainMaker directory

* Update README.md

* Update README.md

* Revert "RMT refactor"

* Fixes Lib Builder compiling errors

* Fixes Lib Builder compiling errors

* Revert "Revert "RMT refactor""

* Update esp32-hal-rmt.c

* Update esp32-hal-rmt.c

* Update esp32-hal-rmt.c

* Update esp32-hal-rmt.c

* Update esp32-hal-gpio.c

* Bugfix of ff_sd_status

* Fix I2C Slave Compile

I2C Slave currently doesn't compile for projects where Arduino is an IDF component.  This adds missing conditionals.

* add missing c3 define

when disable HAL lock is set

* add ESP32C3 `esp32_adc2gpio`

* Fixes UART MODBUS and Loopback issue

* Update esp32-hal-uart.c

* Revert "Fixing interrupts in LEDC (espressif#6160)"

This reverts commit a593206.

* Update esp32-hal.h

* use Tasmota github

* Use Tasmota platform for CI

* tasmota eaptool v3.2

* add missing c3 define

* enable SPI hal for S3

* revert enable spi for S3

* Update Esp.cpp

* Update Esp.cpp

* fix S3 uart gpios

* Update HardwareSerial.cpp

* Update Esp.cpp

* Update Esp.cpp

* Bootloader is at 0x0000 for S3

* Update esp32-hal-cpu.c

* Update esp32-hal-spi.c

* Update install-platformio-esp32.sh

* Fix replace() failing

* Update CMakeLists.txt

* remove Rainmaker

* Update CMakeLists.txt

* try to find lib builder fail

* Update CMakeLists.txt

* Update idf_component.yml

* Update esp32-hal-ledc.c

* Update esp32-hal-gpio.c

* Update esp32-hal-gpio.h

* Update boards.txt

* Update idf_component.yml

* Update esp32-hal-gpio.c

* Update esp32-hal-ledc.c

* Update idf_component.yml

* Add files via upload

* Update HTTPClient.cpp

* Update HTTPClient.h

* Fixes RMT examples and adds ESP32-S3 config

* Fixes RMT examples and adds ESP32-S3 config

* fix compile

* fix compile 2

* fix compile 3

* revert cookie changes

* revert cookie jar support

* cookie jar

* cookie jar

* Support mbedtls 2.28.x

* Update esp32c3.rom.ld

* GPIO refactoring

GPIO now using ESP-IDF API on all chips.
LEDC interrupt fix removed - no longer needed.
Edited pins_arduino.h in variants according to changes in gpio.

* Update esp32-hal-gpio.c

* Update esp32-hal-ledc.c

* Update HTTPClient.cpp

* Update ssl_client.cpp

* Update boards.txt

* Update esp32-hal-gpio.c

* Update esp32-hal-ledc.c

* Edited analog channels functions

* Update esp32-hal-gpio.c

* Update esp32-hal-gpio.h

* Update esp32-hal-ledc.c

* Fix CDC+JTAG is disabled when WiFi is used on ESP32-C3

Fixes: espressif#6264
Thanks @Spritetm

* ADC esp32s2 attenuation fix for DAC pins

* Revert "ADC esp32s2 attenuation fix for DAC pins"

* revert6134

espressif#6134

* revert2

* revert3

* revert

* Update HardwareSerial.cpp

* Update HardwareSerial.h

* Update esp32-hal-uart.c

* Update esp32-hal-uart.h

* S3

* Update esp32-hal-adc.c

* Fix ethenet

* align with arduino upstream

* Adds C++ std::function to Serial.onReceive() PR6364 upstream

* Update esp32-hal-uart.c

* Update HardwareSerial.cpp

* Update esp32-hal-uart.c

* Update boards.txt

* Update HardwareSerial.cpp

* Update HardwareSerial.h

* Update WiFiAP.cpp

* Update WiFiGeneric.cpp

* Update WiFiGeneric.h

* Update WiFiSTA.cpp

* Update WiFiSTA.h

* Update HardwareSerial.cpp

* Update HardwareSerial.h

* Delete libraries/RainMaker directory

* remove rainmaker

* Fixes USB CDC setRxBufferSize(), begin(), _onRX()

* Fixes SetRxBufferSize(0) with end()

* Fixes reset when 2x call to end()

* publish.yml: Limit the running scope of the publish Workflow. (espressif#6428)

1. Don't run the publish test result workflow on the master
branch.
2. Run only on Pull Requests to be able to publish the result as a PR comment.
3. Avoid running when the triggering workflow was skipped, this will
   cause a failure as no file will be uploaded.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>

* Add missing include in AsyncUDP.h (espressif#6412)

In my project I'm getting the error 
```
In file included from lib/Discovery/Discovery.cpp:2:
C:/Users/David/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src/AsyncUDP.h:47:1: error: expected class-name before '{' token
```

Adding a reference to Stream.h fixes it.

* Some board variant fixes (espressif#6411)

* make work with rev C pcb

* use #define for easy testing

* Added another overloaded WiFiSTAClass::begin() function that provides… (espressif#6398)

Summary

The examples demonstrate how to create a WPA2 Enterprise connection, but it requires using various direct esp_idf functions. This patch is intended to create another overloaded version of the WiFi.begin() function that allows a user to create a WPA2 Enterprise connection in much the same way as different kinds of connections.

My only question for the core maintainers is whether I should leave those #ifdef's in there. I added them so that it was easy to disable all the code I added via defines from my platformio.ini file, but they technically aren't necessary.

Impact

This should make it easier for novice users to create WPA2 Enterprise connections. For my university, I didn't need a root certificate or the client certificate or client key, so I haven't been able to debug those scenarios, but I built the begin functions to allow any one of those to be used, if needed.

I can confirm that eduroam-style WPA2 Enterprise networks that only require authentication with a username and password works as expected.

* Fix boot freeze when trying to init PSRAM on Pico D4

* Revert "Added another overloaded WiFiSTAClass::begin() function that provides… (espressif#6398)"

This reverts commit d977359.

* fix rainmaker merge

Co-authored-by: Theo Arends <11044339+arendst@users.noreply.github.com>
Co-authored-by: me-no-dev <me-no-dev@users.noreply.github.com>
Co-authored-by: me-no-dev <hristo@espressif.com>
Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: Jason2866 <jason2866@github.com>
Co-authored-by: Rodrigo Garcia <Rodrigo.Garcia@espressif.com>
Co-authored-by: mrengineer7777 <44048235+mrengineer7777@users.noreply.github.com>
Co-authored-by: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Co-authored-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Co-authored-by: Limor "Ladyada" Fried <limor@ladyada.net>
Co-authored-by: John P. Swensen <jpswensen@gmail.com>
Co-authored-by: Stephan Hadinger <stephan.hadinger@gmail.com>
@dagi0627
Copy link

dagi0627 commented Aug 3, 2023

My esp32 (device1) connected to another MCU (device2) over UART2. Device2 sends some data at every second then device1 recieveing it well and send back over UART0 for show on terminal. It is good working. But some in case device1 or esp32 send character "@" to device2 then device2 stop to send data at everysecond and send some information at once time . That is same following

2. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
3. when an unknown printer took a galley of type 
4. and scrambled it to make a type specimen book. 
5. It has survived not only five centuries, 
6. but also the leap into electronic typesetting, 
7. remaining essentially unchanged. 
8. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, 
9. and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.```  
But it is not show on terminal. After few minute Device2 send data at everysecond then i show above information. Why it is Buffered data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment