RS-485 support

aaquilina
Posts: 43
Joined: Fri Jan 20, 2017 3:10 pm

Re: RS-485 support

Postby aaquilina » Fri Jun 02, 2017 1:10 pm

@hwmaier May I ask how you edited the TX_DONE interrupt? I have tried adding the gpio set level command to what I believe is that interrupt but see no effect on the pin.

Code: Select all

else if(uart_intr_status & UART_TX_DONE_INT_ST_M) {
            UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
            uart_reg->int_ena.tx_done = 0;
            uart_reg->int_clr.tx_done = 1;
			gpio_set_level(GPIO_NUM_2, 0);//Added to control RS485
			ESP_LOGI("Uart", "UART: Lowered GPIO");
            UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
            xSemaphoreGiveFromISR(p_uart_obj[uart_num]->tx_done_sem, &HPTaskAwoken);
            if(HPTaskAwoken == pdTRUE) {
                portYIELD_FROM_ISR() ;
            }
        }

hwmaier
Posts: 31
Joined: Sun May 28, 2017 7:30 am

Re: RS-485 support

Postby hwmaier » Fri Jun 02, 2017 1:53 pm

@aaquilina: Code location is correct for turning it off. Maybe your GPIO pin is not initialised?

aaquilina
Posts: 43
Joined: Fri Jan 20, 2017 3:10 pm

Re: RS-485 support

Postby aaquilina » Fri Jun 02, 2017 2:07 pm

@hwmaier The GPIO is initialised because it goes high without issue before writing the bytes. Is the TX_DONE interrupt enabled by default? I tried adding it to the driver install function but when I run the code, the panic handler gets invoked and reboots the ESP.


EDIT: To be clear, I also dont see the log output which indicates that the TX_DONE ISR is never being called.

Code: Select all

uart_intr_config_t uart_intr = {
        .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M
                            | UART_RXFIFO_TOUT_INT_ENA_M
                            | UART_FRM_ERR_INT_ENA_M
                            | UART_RXFIFO_OVF_INT_ENA_M
                            | UART_BRK_DET_INT_ENA_M
                            | UART_PARITY_ERR_INT_ENA_M
									| UART_TX_DONE_INT_ENA_M ,
        .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
        .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
        .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT
    };

hwmaier
Posts: 31
Joined: Sun May 28, 2017 7:30 am

Re: RS-485 support

Postby hwmaier » Sat Jun 03, 2017 12:57 am

@aaquilina: Of course it has to enabled as well. Before the FIFO is written to you have to set the GPIO and also enable the interrupt. There are two locations in uart.c where this needs to be done. Once in uart_fill_fifo and once in the ISR. I submitted a PR with my code, so you can check it out. Please note my code uses the RTS line to control the line-driver, so please configure your GPIO as RTS pin.

RS-485 half-duplex line driver control using the RTS line:

https://github.com/espressif/esp-idf/pull/667

aaquilina
Posts: 43
Joined: Fri Jan 20, 2017 3:10 pm

Re: RS-485 support

Postby aaquilina » Mon Jun 05, 2017 11:26 am

@hwmaier Excellent, that worked perfectly. I just had to switch the levels in the code because my TX is active high.

EndlessDelirium
Posts: 8
Joined: Wed May 10, 2017 1:12 pm

Re: RS-485 support

Postby EndlessDelirium » Thu Jun 08, 2017 6:08 am

I've got an answer from Espressif in the meantime: "The example for RS-485 is already in our development plan and it will be released later." Unfortunately they haven't provided any ETA.

@hwmaier: Thank you for the software based implementation.

@ESP_Sprite: I've now created such a feature request (https://github.com/espressif/esp-idf/issues/678)

aaquilina
Posts: 43
Joined: Fri Jan 20, 2017 3:10 pm

Re: RS-485 support

Postby aaquilina » Thu Jun 08, 2017 8:09 am

Is there any way to prevent the RX buffer being filled while rts is low? That is, in RS485 mode.

I've tried disabling the interrupt but of course the buffer is still being filled.I thought of changing the rx input to an output but my rx is on pin 36 which is input only. The reason I need to do this can be seen in the logic signals below.

When the TX_EN enable line goes high, the RX line goes low because the RS485 receive buffer is disabled (physically in the external IC- SN65HVD72). This is causing my UART to read an extra 0x00 at the start of my actual packet. I can either filter it in software but I'd much prefer to not receive it in the first place.

Image

hwmaier
Posts: 31
Joined: Sun May 28, 2017 7:30 am

Re: RS-485 support

Postby hwmaier » Thu Jun 08, 2017 8:27 am

@ aaquilina Are you using my PR? If yes, it has a small bug which I have not fixed yet in the PR which may cause this issue:

Try changing uart_set_rs485_hd_mode to

Code: Select all

esp_err_t uart_set_rs485_hd_mode(uart_port_t uart_num, bool enable)
{
    UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
    UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
    if(enable) {
        UART[uart_num]->rs485_conf.en = 1;
        UART[uart_num]->rs485_conf.tx_rx_en  = 1;  // This disables the RX loopback. Doc seems to be wrong, 1 disables it
        UART[uart_num]->rs485_conf.rx_busy_tx_en = 0; // 0 = Allow collision, 1 = avoid collision
    } else {
        UART[uart_num]->rs485_conf.en = 0;
    }
    UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
    return ESP_OK;
}

aaquilina
Posts: 43
Joined: Fri Jan 20, 2017 3:10 pm

Re: RS-485 support

Postby aaquilina » Thu Jun 08, 2017 8:52 am

@hwmaier I am working with your PR however the 0x00 byte is still coming in after applying your latest fix.

What does the RX loopback do?

aaquilina
Posts: 43
Joined: Fri Jan 20, 2017 3:10 pm

Re: RS-485 support

Postby aaquilina » Thu Jun 08, 2017 9:15 am

@hwmaier I have found a solution but its not the most elegant. I'm resetting the RX_FIFO before disabling my TX_EN in the driver
EDIT: This is an edit on your PR.
Image

Who is online

Users browsing this forum: Google [Bot], KMTsvetanov and 114 guests