I need to send data over ModBus-RTU (basically RS485) from an nRF52840. For this, I use uarte. The transceiver's transmit enable input is controlled through a GPIO pin, which in turn is controlled from the PPI (NRF_UARTE_EVENT_TXSTARTED and NRF_UARTE_EVENT_TXSTOP events). When I check on the scope, I see a varying time between the enable pin being raised and the start of the actual transfer. For example: in the below capture, the delay between TXD (in blue) and the enable pin (in red) is 23.67 usec, This delay varies from 0 up to one bittime (I've seen a 103 usec delay when transmitting on 9600 bps).

Can I remove these delays or otherwise at least stabilize them so that they always are the same?
This is my code for initialization:
void rs485_init ( void )
{
uint32_t task_addr;
uint32_t event_address;
static bool _init_done = false;
nrfx_uarte_config_t uarte_config = NRFX_UARTE_DEFAULT_CONFIG;
uarte_config.pseltxd = MODBUS_TX_PIN;
uarte_config.pselrxd = MODBUS_RX_PIN;
uarte_config.hwfc = NRF_UARTE_HWFC_DISABLED;
nrfx_gpiote_out_config_t nrfx_gpiote_out_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(0);
uarte_config.baudrate = NRF_UARTE_BAUDRATE_9600;
uarte_config.parity = NRF_UARTE_PARITY_INCLUDED;
if (_init_done) nrfx_uarte_uninit(&uarte);
APP_ERROR_CHECK(nrfx_uarte_init( &uarte, &uarte_config, uarte_event_handler)); // Init in non-blocking mode
if ( !nrfx_gpiote_is_init() )
{
nrfx_gpiote_init();
}
else
{
nrfx_gpiote_out_uninit( MODBUS_RTS_PIN );
}
// Initialize the RTS pin as output, to be driven from UART TX via PPI
APP_ERROR_CHECK(nrfx_gpiote_out_init( MODBUS_RTS_PIN, &nrfx_gpiote_out_config ));
nrfx_gpiote_out_task_enable( MODBUS_RTS_PIN );
// Setup PPI to set enable on start of transmission
APP_ERROR_CHECK( nrfx_ppi_channel_alloc( &_ppi_channel_start ) );
event_address = nrfx_uarte_event_address_get( &uarte, NRF_UARTE_EVENT_TXSTARTED );
task_addr = nrfx_gpiote_out_task_addr_get( MODBUS_RTS_PIN );
APP_ERROR_CHECK( nrfx_ppi_channel_assign( _ppi_channel_start, event_address, task_addr ) );
nrfx_ppi_channel_enable( _ppi_channel_start );
// Setup PPI to clear enable on end of transmission
APP_ERROR_CHECK( nrfx_ppi_channel_alloc( &_ppi_channel_stop ) );
event_address = nrfx_uarte_event_address_get( &uarte, NRF_UARTE_EVENT_TXSTOPPED );
task_addr = nrfx_gpiote_out_task_addr_get( MODBUS_RTS_PIN );
APP_ERROR_CHECK( nrfx_ppi_channel_assign( _ppi_channel_stop, event_address, task_addr ) );
nrfx_ppi_channel_enable( _ppi_channel_stop );
// Receiver initialization removed for brevity
_init_done = true;
NRF_LOG_INFO( "RS485 initialized" );
}
