UART Baud Timing Pattern Interrupt / J1708

brunohpg
Posts: 6
Joined: Tue May 28, 2019 5:37 pm

UART Baud Timing Pattern Interrupt / J1708

Postby brunohpg » Tue May 28, 2019 5:54 pm

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.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: UART Baud Timing Pattern Interrupt / J1708

Postby WiFive » Wed May 29, 2019 2:45 pm

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?

brunohpg
Posts: 6
Joined: Tue May 28, 2019 5:37 pm

Re: UART Baud Timing Pattern Interrupt / J1708

Postby brunohpg » Wed May 29, 2019 6:31 pm

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.

Adam123
Posts: 2
Joined: Mon Jun 13, 2022 4:52 am

Re: UART Baud Timing Pattern Interrupt / J1708

Postby Adam123 » Sat Sep 17, 2022 10:56 am

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.

ESP_alisitsyn
Posts: 211
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: UART Baud Timing Pattern Interrupt / J1708

Postby ESP_alisitsyn » Wed Nov 30, 2022 9:00 am

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.

Who is online

Users browsing this forum: Bing [Bot] and 95 guests