Page 1 of 1

UART Baud Timing Pattern Interrupt / J1708

Posted: Tue May 28, 2019 5:54 pm
by brunohpg
Hi,

I want to implement J1708 with ESP32. J1708 is a modified version of RS485.
I am using RS485 UART with modified tranceiver and everything is going well for sending and receiving data.
But the J1708 has a standard of time to distinguish messages. It's simple:
After a message, consisting of a maximum of 21 bytes, an idle time is placed on the bus. The idle time is at least 10 times the bit time.
The network runs at 9600 kbps, so the bit time is 104.16us and 10 times the bit time is 1.041ms.

I wonder if there is any way in hardware to detect idle time.
- I've already tried setting the "AT CMD" pattern to 0 bytes and the post_idle and pre_idle, but it does not work.
- I also tried to get interrupt every 1 byte, recover the time in microseconds and do the analysis in software. That should work, but for some reason it did not work out too well. Perhaps in this case it is the sender that is delaying the bytes and ending the messages. On the oscilloscope I did not see this break.
- I also tried to set the RX_TOUT_TRESH to 1 byte. This is basically the same time I need. I got the interruptions back, but he still broke the messages in half.

Any idea?
Thank you.

Re: UART Baud Timing Pattern Interrupt / J1708

Posted: Wed May 29, 2019 2:45 pm
by WiFive
UART_TOUT_THRESH_DEFAULT is already 10 bits so it should work to give you interrupt at end of idle time. Are you trying to measure accurately the idle time for some reason?

Re: UART Baud Timing Pattern Interrupt / J1708

Posted: Wed May 29, 2019 6:31 pm
by brunohpg
For APB_CLK as source for UART, it's 10 baud cycles, i.e., 100 bits (without parity).
But I don't know what is the default source clock. I think it's APB_CLK.

From Reference Manual:
UART_RX_TOUT_THRHD This register is used to configure the UART receiver’s timeout value when receiving a byte. When using APB_CLK as the clock source, the register counts by UART baud cycle. When using REF_TICK as the clock source, the register counts by APB_CLK frequency (REF_TICK frequency)*8 . (R/W)
I don't know what unit of UART_RX_TOUT_THRHD is when use REF_TICK as UART source clock!
From the source, I suppose it's baud cycles.

Anyway, there's some mistake in uart.c:
In function uart_intr_config:

Code: Select all

        if(UART[uart_num]->conf0.tick_ref_always_on == 0) {
            UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh * UART_TOUT_REF_FACTOR_DEFAULT) & UART_RX_TOUT_THRHD_V);
        } else {
            UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V);
        }
The code:

Code: Select all

UART[uart_num]->conf0.tick_ref_always_on == 0
means REF_TICK as source clock.

Where:

Code: Select all

UART_TOUT_REF_FACTOR_DEFAULT = (UART_CLK_FREQ/(REF_CLK_FREQ<<UART_CLKDIV_FRAG_BIT_WIDTH))
APB_CLK_FREQ = ( 80*1000000 )
REF_CLK_FREQ = ( 1000000 )
Simplifying:

Code: Select all

UART_TOUT_REF_FACTOR_DEFAULT = 10
But in function uart_set_rx_timeout:

Code: Select all

UART[uart_num]->conf1.rx_tout_thrhd = (tout_thresh & UART_RX_TOUT_THRHD_V);
I think it should be same thing! For APB it's will work, but for REF_TICK not.
The code in function uart_intr_config should be correct way.

----------------------
Backing to my problem:
I set UART_RX_TOUT_THRHD as 2 and it work. When I set UART_RX_TOUT_THRHD as 1, the messages comes ended prematurely.
Maybe UART_RX_TOUT_THRHD consider last byte transmitted + idle time. I don't know.

But there is another problem, now with TX.
In my tests I use two UART: one for sending and one for receiving. It's work, but not for j1708.
I send data with precise timing using "NOP()" and microseconds. But the data is sent without idle time (I check in osciloscope).
But thinking now: the write bytes function put it in the TX_FIFO. My time is only sufficient for send a byte, I need message time + idle time. I'll test it now!

Anyway, I'm rewrinting uart driver for j1708. I need to handle first byte collision and precise time to put some message in the bus. I'll reimplement interrupt handler and some functions.

Re: UART Baud Timing Pattern Interrupt / J1708

Posted: Sat Sep 17, 2022 10:56 am
by Adam123
Hello,

Any luck finding the solution for the same.

If so can you please share the code? I am also trying to achieve the same.

Re: UART Baud Timing Pattern Interrupt / J1708

Posted: Wed Nov 30, 2022 9:00 am
by ESP_alisitsyn
Hello,

As about units for UART timeout. The units (counting rate) for UART TOUT feature (UART_RX_TOUT_THRHD value) depends on clock source:
when clk src is REF: the timeout counting rate is BAUD tick rate * 10.
when clk src is APB: the timeout counting rate is BAUD tick rate / 8.

for other chips UART_RX_TOUT_THRHD = 1, is the time equal to 1 bit time on current baudrate.

This function defines the tout in symbol time (number of symbols) https://github.com/espressif/esp-idf/bl ... rt.c#L1746 and the HAL realisation for this:
https://github.com/espressif/esp-idf/bl ... _ll.h#L829
This might help you to realize the timeout feature in your driver.

As about collision detection on ESP32 for J1708 interface:
The ESP32 hardware has some issues with collision detection in RS485 HALF DUPLEX mode (used by default in UART driver)
https://github.com/espressif/esp-idf/bl ... _ll.h#L635
but can work correctly in RS485 FULL DUPLEX mode
https://github.com/alisitsyn/modbus_sup ... tor.c#L158.
The code below can help you to realise the collision detection feature for J1708 interface using HAL layer and custom interrupts:
https://github.com/alisitsyn/modbus_sup ... _detector

Please ask if you have questions. Thanks.