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.

  • Hi Einar! I am trying to implement your callback procedure for a sequential transaction purposes, I want to be able to send another read request as soon as the first transaction is done. First I tried the blocking mode but that is causing an internal error (Code 3). I put a time delay between transactions, and that keeps the data flowing for some time. Now, I am connecting the nRF52480 kit with the sensor board using wires (jumper wires). I know this is not the best practise but it's alright for prototyping purposes. I then tried the non-blocking mode, where a handler sets a flag to true once the Done event is received. I check for the flag in a while loop. However, more often than not, I get stuck in the while loop. The handler callback doesn't get called and the flag is not set. I think it's analogous to error code 3 I received in the blocking mode and therefore, the same cause (long wires and noise). But I just want to make sure it is what I think since I couldn't find or trace how the handler function is called back.

    Thanks,

    Siraj

  • Hi Siraj,

    Please create a new question as this is not directly related to the original thread.

Reply Children
Related