-
Notifications
You must be signed in to change notification settings - Fork 7.6k
More HardwareSerial UART interrupts #9922
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
Comments
Thanks @maciekish for the suggestion. I'll work on adding it. |
I had a look around for the event queue code to hack it myself and found uart.h but no uart.c. Is that proprietary? |
uart.c comes from ESP-IDF: https://github.com/espressif/esp-idf/blob/release/v5.1/components/driver/uart/uart.c |
Also interested in this feature. I could use the interrupts/events to manage bus timing though. |
See for reference the part of source code in my own project related to this: bool Port_ESPEasySerial_HardwareSerial_t::setRS485Mode(int8_t rtsPin, bool enableCollisionDetection)
{
#ifdef ESP32
if (_serial != nullptr) {
if (rtsPin >= 0) {
return _serial->setPins(-1, -1, -1, rtsPin) &&
_serial->setHwFlowCtrlMode(UART_HW_FLOWCTRL_RTS) &&
_serial->setMode(enableCollisionDetection ? UART_MODE_RS485_COLLISION_DETECT : UART_MODE_RS485_HALF_DUPLEX);
}
_serial->setMode(UART_MODE_UART);
}
#endif
return false;
} By setting For collision detection, you need |
Arduino HardwareSerial API relies on IDF UART API. Thus, I have no good news... There is no UART Event that matches this feature. /**
* @brief UART event types used in the ring buffer
*/
typedef enum {
UART_DATA, /*!< UART data event*/
UART_BREAK, /*!< UART break event*/
UART_BUFFER_FULL, /*!< UART RX buffer full event*/
UART_FIFO_OVF, /*!< UART FIFO overflow event*/
UART_FRAME_ERR, /*!< UART RX frame error event*/
UART_PARITY_ERR, /*!< UART RX parity event*/
UART_DATA_BREAK, /*!< UART TX data and break event*/
UART_PATTERN_DET, /*!< UART pattern detected */
#if SOC_UART_SUPPORT_WAKEUP_INT
UART_WAKEUP, /*!< UART wakeup event */
#endif
UART_EVENT_MAX, /*!< UART event max index*/
} uart_event_type_t; The only IDF API that could help is: There is no clear way to capture the IRQ UART_TX_DONE_INT or UART_TXFIFO_EMPTY_INT using the IDF API. |
Hacky workaround for |
Maybe another RTOS task could be started which only runs this call and when it is done, it could fire an event or execute a callback? Only disadvantage is that it takes a semaphore. So potentially there could be some deadlock. |
The issue here is that the Task should monitor if a UART write happens first... But it means using the CPU cycles in a sort of busy wait loop of a high priority Task... it can take ticks from other Tasks, such as That may reduce a lot the execution performance of the whole firmware. |
The best way to achieve it is by using the ISR... |
Nothing new in IDF 5.3... the only way to get this feature correctly done by software would be by writing a new UART driver for Arduino. Another way is the hack suggested by @bertmelis in #9922 (comment)
|
Another point here... Interrupt TX FIFO Empty / TX Done is not good enough. There are 2 possible situations: There is a TX Buffer or not.
In such case, because UART TX FIFO has just 127 bytes of space, many UART_TXFIFO_EMPTY_INT events can happen along a single call to
In this case, any call to In other words, if the sketch writes, for instance, 500 bytes using TX FIFO will be controlled by the IDF Driver with multiple FIFO Empty interrupts until all the data is placed in the TX FIFO. Therefore, I think that the best way to achieve what this Feature Request wants would be by creating a task that is a Writter Task, which sends the bytes and waits until all data is sent out using I hope that this can help you guys to understand how it works and to create the code that better fits your needs. With that said, I can say that there is no way to achieve the requested Feature of this issue. |
Hi, I have been using the library "esp32ModbusEsp32" in PlatformIO and I think I have the problem mentioned here. The communication RS485 fail rondomly because a CRC error, and maybe it's because the program does not wait until all the data is sent, causing a loss of data. What could i do for fix it or verify if is it the problem? The funcion that control the data send is this:
The communication is at 115200 baud, and the variable "_interval" is set to 1ms. If this is not the correct way to ask about it here, sorry, it is my first time here. |
@jax-gin Please see my previous comment to show how to use hardware RTS handling for RS485: #9922 (comment) |
It worked, thank you very much. I had to change the flag used in "setHwFlowCtrlMode" to disable it, so: setHwFlowCtrlMode(UART_HW_FLOWCTRL_DISABLE) Otherwise, it conflicts with "setMode". Now the communication is uninterrupted. |
Guys, I'll close it, given that this feature won't be implemented. |
Sorry I'm not very well versed with the lower level stuff but I'm trying to understand why it's impossible if the functions to register for the interrupt are available... Wouldn't something like this work in HardwareSerial.cpp? Can't test it right now as im traveling and don't have any hardware with me. But at least it compiles 🤷🏻♂️
|
The suggested code would replace the IDF ISR and the |
Related area
HardwareSerial UART Interrupts
Hardware specification
Any ESP32 with UARTs
Is your feature request related to a problem?
Hi, the current HardwareSerial has an onReceive() function (#5678) that uses interrupts to call a user function when data is received, but there is no equivalent for the UART_TX_DONE_INT or UART_TXFIFO_EMPTY_INT. I require these interrupts to implement an RS485 solution for ESP32.
Describe the solution you'd like
I would propose two new functions similar to the existing function
void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout)
The proposed functions are:
To be triggered on
UART_TX_DONE_INT
andUART_TXFIFO_EMPTY_INT
respectively. The second function should also take a threshold parameter and update theuart_intr_config_t.txfifo_empty_intr_thresh
value as requested by the user.Describe alternatives you've considered
No response
Additional context
No response
I have checked existing list of Feature requests and the Contribution Guide
The text was updated successfully, but these errors were encountered: