This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

RS485 transmit enable

We're running a multi-drop single duplex RS485 bus, so it's important to stop driving the bus as soon as a transmit is complete so the next device can transmit without two drivers driving the bus at once.  Is there a way to set up hardware control of the RS485 bus driver enable pin?

  • There is no hardware control I know of, but you can use APP_UART_TX_EMPTY, which indicates "All Sent" similar to other devices. This could be linked to the driver control pin via PPI, but here is the interrupt version:

      // Set up RS485 Driver Enable output pin
      nrf_gpio_pin_clear(PIN_RS485_DE);
      nrf_gpio_cfg_output(PIN_RS485_DE);

    This is the serial port interrupt

    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint16_t index = 0;
        uint32_t ret_val;
    
        switch (p_event->evt_type)
        {
            case APP_UART_DATA_READY:          // Event UART data received. The data is available in the FIFO and can be fetched using @ref app_uart_get
                // blah-blah
                break;
    
            case APP_UART_COMMUNICATION_ERROR: // Error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field
                NRF_LOG_ERROR("Communication error occurred while handling UART.");
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;
    
            case APP_UART_FIFO_ERROR:          // Error in FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field
                NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            case APP_UART_TX_EMPTY:            // Event UART has completed transmission of all available data in the TX FIFO
                // Disable RS485 differential driver
                nrf_gpio_pin_clear(PIN_RS485_DE);
                break;
    
            case APP_UART_DATA:                // Event UART data has been received, and data is present in data field. This event is only used when no FIFO is configured
            default:
                break;
        }
    }

    Assuming packets are sent from a single function, here is the transmit enable:

    void SendViaHardwareUart(char * InfoPacket)
    {
        uint32_t err_code;
        uint32_t txIndex;
    
        // Hardware uart can be disabled to save power and extend battery life
        if (HardwareUartEnabled)
        {
            // Enable RS485 differential driver
            nrf_gpio_pin_set(PIN_RS485_DE);
            // blah-blah
        }
    }

Related