Skip to content

[2.0.0] Adds the setRXInterrupt #4656

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

Closed
wants to merge 46 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4d262c5
Merge pull request #1 from espressif/master
timkoers Dec 23, 2020
a4df65f
Added UART RX interrupt function
timkoers Dec 23, 2020
b20b3cd
Merge branch 'master' of github.com:timkoers/arduino-esp32
timkoers Dec 23, 2020
725ad11
Updated HardwareSerial class with the interrupt functions
timkoers Dec 23, 2020
e8272c7
Added Serial 'tests' for Interrupt and stock code
timkoers Dec 23, 2020
623796a
This should add the Serial interrupt and no interrupt ino's to the co…
timkoers Dec 23, 2020
000482e
Platform IO sketch sources are messing everything up
timkoers Dec 23, 2020
2e657a7
Platform IO install script fixed
timkoers Dec 23, 2020
38914ff
Arduino Core install script fixed
timkoers Dec 23, 2020
8a27284
Fixed HardwareSerial setRXInterrupt argument type
timkoers Dec 23, 2020
ba351a8
Whoopsie
timkoers Dec 23, 2020
8db7e7f
tested and verified to work
timkoers Dec 24, 2020
96fa55f
Should fix compilation error
timkoers Dec 29, 2020
7d84946
Rewrite of the interrupt handlers for the uart devs
timkoers Jan 8, 2021
054c1a9
Should fix compilation error
timkoers Jan 8, 2021
c344425
Better use else if, or else the input get's duplicated whilest it is …
timkoers Jan 8, 2021
1ba43fc
Updated code formatting and removed commented lines from ci test scripts
timkoers Jan 12, 2021
cadb74d
Updated code formatting once again
timkoers Jan 12, 2021
02b29fd
Last code formatting fix
timkoers Jan 12, 2021
d63d896
Accidentally removed some args whilest formatting the code
timkoers Jan 12, 2021
7bea5a4
Free the interupt from the array on enable/disable of the interrupt, …
timkoers Jan 12, 2021
def8f9c
Renamed the interrupt management functions
timkoers Jan 12, 2021
21043d5
Removed tests from Windows and Mac
timkoers Jan 12, 2021
55ae3be
Fixed setRxInterrupt in HardwareSerial.cpp and fixed double deletion …
timkoers Jan 12, 2021
be5000b
Resolved the if statements
timkoers Jan 12, 2021
6d7e8eb
Cleaned up and commented the Interrupt example
timkoers Jan 12, 2021
e3298ea
Changed serials to Serial and Serial2
timkoers Jan 12, 2021
3bfadf8
Changed example to buffer
timkoers Jan 12, 2021
8cda769
Fixed compilation error
timkoers Jan 12, 2021
36ebb83
Fixed compilation error
timkoers Jan 12, 2021
cf98504
Lost my focus a bit, I think
timkoers Jan 12, 2021
0b2ae4e
Updated uart hal code, with comments regarding the interrupt clearing…
timkoers Jan 12, 2021
715f399
Reverted scripts back to it's original form
timkoers Jan 12, 2021
4f80e57
Reverted on-push to stock form
timkoers Jan 12, 2021
f33c332
Fixed ISR concurrency problems in example
timkoers Jan 12, 2021
5beb727
Update on-push.sh
timkoers Jan 12, 2021
52b8a41
Update on-push.sh
timkoers Jan 12, 2021
f948c78
Replaced tabs with spaces ;-)
timkoers Jan 13, 2021
4441190
And fixed the remaining things
timkoers Jan 13, 2021
ce3952d
Fixed whitespace refactoring and compilation error
timkoers Jan 13, 2021
d8f54ee
Added documentation to the examples and added another Interrupt handl…
timkoers Jan 17, 2021
b3511e5
Don't forget to actually add the example ;-)
timkoers Jan 17, 2021
32a7446
Fixed wrong define name
timkoers Jan 17, 2021
f89b634
Added include for queue.h
timkoers Jan 17, 2021
41a869a
Not sure how I got confused with Queue_t, but fixed
timkoers Jan 17, 2021
12b8725
Fixed
timkoers Jan 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .github/scripts/install-arduino-core-esp32.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ 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
echo "Linking Core..."
ln -s $GITHUB_WORKSPACE "$ARDUINO_ESP32_PATH"

echo "Updating Submodules ..."
cd esp32
Expand Down
9 changes: 2 additions & 7 deletions .github/scripts/install-platformio-esp32.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +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()"

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 "Linking Core..."
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"

echo "PlatformIO for ESP32 has been installed"
echo ""
Expand Down
12 changes: 9 additions & 3 deletions .github/scripts/on-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -61,11 +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/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
12 changes: 12 additions & 0 deletions cores/esp32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ 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)(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);

uartEnableInterrupt(_uart, &interrupt_info, arg, user_arg);
}

void HardwareSerial::end()
{
if(uartGetDebug() == _uart_nr) {
Expand Down
3 changes: 3 additions & 0 deletions cores/esp32/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -58,6 +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);
int available(void);
int availableForWrite(void);
int peek(void);
Expand Down Expand Up @@ -108,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));
Expand Down
49 changes: 39 additions & 10 deletions cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -47,6 +47,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()
Expand All @@ -69,34 +76,45 @@ 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 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];
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(uart->queue != 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) {
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();
}
}

void uartEnableInterrupt(uart_t* uart)
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;
Expand All @@ -107,6 +125,14 @@ void uartEnableInterrupt(uart_t* uart)
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_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();
}
Expand All @@ -118,6 +144,9 @@ void uartDisableInterrupt(uart_t* uart)
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;

Expand Down Expand Up @@ -148,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)
Expand Down
6 changes: 6 additions & 0 deletions cores/esp32/esp32-hal-uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -80,6 +83,9 @@ 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);

#ifdef __cplusplus
}
#endif
Expand Down
21 changes: 21 additions & 0 deletions libraries/ESP32/examples/Serial/Interrupt/Interrupt.ino
Original file line number Diff line number Diff line change
@@ -0,0 +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);
}

void setup()
{
hwSerial.begin(115200);
hwSerial2.begin(115200);
hwSerial2.setRXInterrupt(onSerialRX, (void*)&hwSerial2);
}

void loop()
{
delay(1);
}
13 changes: 13 additions & 0 deletions libraries/ESP32/examples/Serial/NoInterrupt/NoInterrupt.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
HardwareSerial hwSerial(0);
HardwareSerial hwSerial2(2);

void setup()
{
hwSerial.begin(115200);
hwSerial2.begin(115200);
}

void loop()
{
hwSerial.print(hwSerial2.read());
}