diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 545c9b05562..0553daacaa8 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -30,6 +30,13 @@ HardwareSerial Serial2(2); HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {} +void HardwareSerial::setInterrupt(void(*arg)() ) +{ + uartDisableInterrupt(_uart); + intr = arg; + uartEnableInterrupt(_uart,&intr); +} + void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms) { if(0 > _uart_nr || _uart_nr > 2) { diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 5f886650816..ce373686dcd 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -54,7 +54,7 @@ class HardwareSerial: public Stream { public: HardwareSerial(int uart_nr); - + void setInterrupt(void (*arg)() ); 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); @@ -93,16 +93,15 @@ class HardwareSerial: public Stream void setDebugOutput(bool); protected: + void (*intr)() ; int _uart_nr; uart_t* _uart; }; -extern void serialEventRun(void) __attribute__((weak)); - #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) extern HardwareSerial Serial; extern HardwareSerial Serial1; extern HardwareSerial Serial2; #endif -#endif // HardwareSerial_h +#endif diff --git a/cores/esp32/Stream.cpp b/cores/esp32/Stream.cpp index 5c090791968..5727ff6f896 100644 --- a/cores/esp32/Stream.cpp +++ b/cores/esp32/Stream.cpp @@ -85,7 +85,7 @@ void Stream::setTimeout(unsigned long timeout) // sets the maximum number of mi unsigned long Stream::getTimeout(void) { return _timeout; } - +/* // find returns true if the target string is found bool Stream::find(const char *target) { @@ -141,6 +141,114 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina return false; } +*/ + +// ******************** ALEXANDRE + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} + + + +// ********************************** + + + // returns the first valid (long) integer value from the current position. // initial characters that are not digits (or the minus sign) are skipped // function is terminated by the first character that is not a digit. diff --git a/cores/esp32/Stream.h b/cores/esp32/Stream.h index 4ce31955acd..e9d3b525ebf 100644 --- a/cores/esp32/Stream.h +++ b/cores/esp32/Stream.h @@ -60,6 +60,24 @@ class Stream: public Print void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second unsigned long getTimeout(void); + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool find(char target) { return find (&target, 1); } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + +/* bool find(const char *target); // reads data from the stream until the target string is found bool find(uint8_t *target) { @@ -90,7 +108,7 @@ class Stream: public Print { return findUntil((char *) target, targetLen, terminate, termLen); } - +*/ long parseInt(); // returns the first valid (long) integer value from the current position. // initial characters that are not digits (or the minus sign) are skipped // integer is terminated by the first character that is not a digit. @@ -123,6 +141,17 @@ class Stream: public Print // this allows format characters (typically commas) in values to be ignored float parseFloat(char skipChar); // as above but the given skipChar is ignored + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); + }; #endif diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 2dee63dc325..7520227a045 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -75,6 +75,10 @@ static void IRAM_ATTR _uart_isr(void *arg) BaseType_t xHigherPriorityTaskWoken; uart_t* uart; + if(arg != NULL) { + (*((void(**)())arg))(); + } + for(i=0;i<3;i++){ uart = &_uart_bus_array[i]; if(uart->intr_handle == NULL){ @@ -96,6 +100,22 @@ static void IRAM_ATTR _uart_isr(void *arg) } } +void uartEnableInterrupt(uart_t* uart,void * func) +{ + 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; + + esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, func, &uart->intr_handle); + UART_MUTEX_UNLOCK(); +} + +/* void uartEnableInterrupt(uart_t* uart) { UART_MUTEX_LOCK(); @@ -110,7 +130,7 @@ void uartEnableInterrupt(uart_t* uart) 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) { UART_MUTEX_LOCK(); @@ -148,9 +168,19 @@ 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); } +// 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) { diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index 821ca9c6ce0..cdf52e86689 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -81,4 +81,7 @@ bool uartRxActive(uart_t* uart); } #endif +void uartDisableInterrupt(uart_t* uart); +void uartEnableInterrupt(uart_t* uart,void * func ); + #endif /* MAIN_ESP32_HAL_UART_H_ */