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

Sequential calls to nrf_drv_twi_tx fails [SDK9]

When calling nrf_drv_twi_tx() once like in the snippet below it works, but when the function is called two or more times sequentially, it fails. However running a nrf_delay_ms() delay between the calls makes it work again.

Works

nrf_drv_twi_init(&twi, NULL, NULL); 
nrf_drv_twi_enable(&twi);
nrf_drv_twi_tx(&twi, addr, &(buf[0]), buf_size, false);

Fails

nrf_drv_twi_init(&twi, NULL, NULL); 
nrf_drv_twi_enable(&twi);
nrf_drv_twi_tx(&twi, addr, &(buf[0]), buf_size, false);
nrf_drv_twi_tx(&twi, addt, &(buf[0]), buf_size, false);

Works again

nrf_drv_twi_init(&twi, NULL, NULL); 
nrf_drv_twi_enable(&twi);
nrf_drv_twi_tx(&twi, addr, &(buf[0]), buf_size, false);
nrf_delay_ms(10);
nrf_drv_twi_tx(&twi, addt, &(buf[0]), buf_size, false);

It fails simply by running the app_error_handler. Which spits out some corrupted data over the serial interface.

Solved

The flash IC I'm using requires a 10ms wait between each write. Therefore the IC would NACK the second write if it hasn't been 10ms since the last write.

Parents
  • The nrf_drv_twi_tx() will always return immediately. The first call will likely return NRF_SUCCESS. Then should normally not make new call to nrf_drv_twi_tx() until you get a callback in the event handler nrf_drv_twi_init(). (As you have not supplied any event handler you will not get this event.)

    When you make the second call to nrf_drv_twi_tx() immediately after the first call, the transfer is not completed, and the second call will likely return NRF_ERROR_BUSY. You do not check the return value, so you are in the blind here as well.

    Your work around, waiting for some time, should work most of the time. However you do not know if you are waiting long enough or you may be waiting for far longer than you have to. Moreover there is no way to be confident that the transfer was successful as long as you do not check the callback events.

    So to fix this:

    • Implement the event handler and provide a pointer to it in your call to nrf_drv_twi_init()
    • Check the return value of calls to nrf_drv_twi_tx()
    • Do not make a new call to nrf_drv_twi_tx() until you have received an event reporting the result of the previous call

    See the TWI driver documentation for details.

  • nrf_drv_twi_tx() will not return immediately when run in blocking mode, which is is (as stated in nrf_drv_twi_init(&twi, NULL, NULL);).

    However I found the issue. The flash IC I am using requires a 10ms backoff between write cycles.

Reply Children
No Data
Related