Page 1 of 1

UART hardware flow control

Posted: Sat Jul 25, 2020 9:40 pm
by zliudr
I'm trying to use hardware flow control. I'm expected to use DTR/DSR flow control but it seems ESP32 has RTS/CTS flow control. If I understand this correctly, say PC will assert RTS and waits for ESP to assert CTS before it sends data. This works like DTR/DSR, IF, ESP32 is acting like a DCE, or a device compared to a PC, which is DTE. What if I want ESP to be the DTE and only send data when the other party, say a lowly ATMEGA328, has time to read serial port? Thank you!

I didn't find the reference in the manual. Would be nice to know where to read. I'll read the technical reference manual again maybe I missed. The API reference doesn't seem to explain how hardware flow control works on ESP32.

Re: UART hardware flow control

Posted: Fri Jul 31, 2020 5:55 am
by zliudr
On ESP32 Technical Reference Manual V4.1, page 360, I see there are DTR, DSR, RTS, CTS. They are all read-only bits and referred to as internal. Does ESP32 hardware implement DTR DSR lines at all? Page 342 has a diagram. It only has RTS and CTS connected to HW_Flow_Ctrl block. I guess only these two lines are brought to GPIO pins, settable by uart_set_pin. I don't have to use DTR/DSR if I can use RTS and CTS for the same flow control, i.e. assert RTS when ESP32 is ready to receive data, send data only if CTS is asserted. Correct?

Re: UART hardware flow control

Posted: Fri Jul 31, 2020 10:35 pm
by zliudr
On ESP32 data sheet, GPIO_Matrix, there are U0DSR and U0DTR but not for U1 or U2. Also the uart_set_pins() doesn't take DSR or DTR pins. Is U0 different from U1 and U2? I read U2 has some simplifications.

Re: UART hardware flow control

Posted: Mon Aug 03, 2020 12:26 am
by PeterR
Hi,
Left field: Why do you think that you need such tight DTR/DSR? They are really old school signals for back in the day 8080 etc limited processing equipment & perhaps without hardware 8251 support. I have not needed either since the 80's.
The ESP should always be DTR (and I would bet large that any device which needs DTR will have a baud rate <19,200) and so I would imagine that you could just start transmission (1 byte at a time) when signaled. You will have <100uS latency between bytes when polling from an ISR. Perhaps you don't need to send immediately (remember old school, slow as ....). DTR is just a flag which says that its ok to send - (your unstated application requirements determine needed throughput so I cannot be sure).
So whilst the detailed answer depends on your throughput requirement i would very much suspect that a DTR/DSR solution is not throughput sensitive.
Boiling my understanding down then this might be a simple task which sends a byte when Ok to send?
PS I often get my DTE/DCE the wrong way around but basically hardware flow control has become a non issue as processing power and hardware USART support (with FIFO) have arrived (post 80's) & assuming low baud rates.
Please quote your throughput & bauds etc.

Re: UART hardware flow control

Posted: Mon Aug 03, 2020 3:34 am
by zliudr
Hi PeterR,

Thanks for your response! My project includes communicating with printers via the RS-232 port. THese printers have clearly marked DTR/DSR signals. From their pinouts, it seems that these printers consider themselves as DTEs instead of DCEs. The main reason they have hardware/software flow control is you could potentially fill up the buffer while the printer is busy printing. I've observed occasional DTR toggling but it's only very brief, like 1 byte. It's indeed old.

Anyway, I managed to use RTS/CTS on ESP32 as DTR/DSR. It seems to work. Stream of data stop coming in when I de-assert DTR on my PC. I didn't test the reverse direction but assume it's working.

Re: UART hardware flow control

Posted: Tue Aug 04, 2020 2:59 am
by zliudr
So I did some tests with my logic analyzer. You have to set .rx_flow_ctrl_thresh in uart_config, which I didn't see it explained except an example just sets it to 122 without any mention what and why. If I set it to 64, ESP32 de-asserts RTS exactly after 64 bytes. This is undesirable because I think ESP has 128 bytes of hardware buffer and pausing until my task loop reads the port wastes time. I then adjusted it to 110. Now 110 bytes and a shorter de-assertion period. This is already acceptable considering the alternative is probably setting .rx_flow_ctrl_thresh too high so it always fills hardware buffer that triggers interrupt/DMA. If the processor is stuck then host side will not know. Anyway, HW flow control is a neat feature. I also corrected my misconception that ESP32 somehow keeps removing bytes from hardware RX buffer into its uart driver's memory buffer. I guess only when hardware buffer is full, an interrupt is generated (there are so many of them compared with an atmega) and the entire hardware buffer is emptied.