Issue with NRF_TWIM_TASK_STOP and NRF_TWIM_EVENT_STOPPED on NRF52833 DK

Issue:

While trying to initialize and check the viability of an I2C interface using TWIM, my NRF_TWIM_TASK_STOP never triggers NRF_TWIM_EVENT_STOPPED.

Code:

nrf_twim_task_trigger(reg, NRF_TWIM_TASK_STOP);
while (nrf_twim_event_check(reg, NRF_TWIM_EVENT_STOPPED) == 0) {
    printf("IN WHILE WAITING FOR (NRF_TWIM_EVENT_STOPPED == 1)\n");
}

This causes the "IN WHILE" message to print indefinitely.

Wondering how I can verify that the trigger is being pushed to the correct address, and diagnose why the event is not getting fired.

Cheers!

  • Hi,

    I'm not sure if triggering the STOP task when the TWIM peripheral is not enabled/configured will generate any STOPPED event, as it is not in the proper state. From the TWIM peripheral documentation:

    "The TWI master is stopped by triggering the STOP task. This task must be triggered before the NACK bit is supposed to be transmitted. The STOP task can be triggered at any time during the reception of the last byte. It is recommended to use the shortcut between LASTRX and STOP to accomplish this.

    The TWI master cannot be stopped while suspended, so the STOP task must be issued after the TWI master has been resumed."

    You can also see from the transfer sequence diagrams in the documentation that the STOPPED event is first generated after the STOP condition have been generated on the TWI bus.

    Your application should be able to know if you have configured an TWI instance or not, is there any other way you can keep track of whether the instance is in use or not in your application? 

    Best regards,
    Jørgen

  • Hi Jorgen,

    Apologies for the missed diacritical in your name ;)

    The method I've been asked to work on probes a sequence of addresses and is meant to return any address that can perform all of the basic twim tasks.

    The sequence of method calls (in pseudo-code, minus params) are as follows:

    nrnf_twim_enable
    nrf_twim_address_set
    nrf_twim_tx_buffer_set(reg, NULL, 0) // blank the buffer
    
    nrf_twim_task_trigger-> NRF_TWIM_TASK_RESUME
    nrf_twim_task_trigger-> NRF_TWIM_TASK_STARTTX
    
    while NRF_TWIM_EVENT_TXSTARTED == 0 && NRF_TWIM_EVENT_ERROR == 0 print warning to console
    
    nrf_twim_event_clear -> NRF_TWIM_EVENT_TXSTARTED
    
    nrf_twim_task_trigger-> NRF_TWIM_TASK_STOP
    
    while for NRF_TWIM_EVENT_STOPPED == 0 print warning to console


    More code follows, but the method hangs on that last check - it never moves past the while.

    Curious if the calls are out of order here.

    Thanks so much!

    S.

  • Update:

    Having run some rather exhaustive tests, I have the following update

    1) Triggering the NRF_TWIM_TASK_STOP event using nrf_twim_task_trigger causes an NRFX_ERROR_INTERNAL error. I can get no further information.
    2) Calling nrfx_twi_bus_recover succeeds, and the bus is recovered.

    This allows my method to return a proper TWI interface using the discovered address.

    Questions:
    1) What kinds of issues would produce the aforementioned error code?
    2) Is there any way to get further/deeper information on the error?

    Best,


    S.

  • Hi,

    Where do you get the NRFX_ERROR_INTERNAL error from? As far as I can see, nrf_twim_task_trigger() should return void.

    Do you have one/some specific TWI slave devices connected to the bus? We added a fix to the nrfx_twim driver in nrfx v1.8.0, to resolve issues caused by TWI devices not behaving according to spec: https://github.com/NordicSemiconductor/nrfx/blob/master/CHANGELOG.md#fixed-7

    Best regards,
    Jørgen

  • The error is coming from debugging code I've added. e.g.

    if (nrf_twim_event_check(reg, NRF_TWIM_EVENT_ERROR)) {
        printf("nrf_twim_event_check(reg, NRF_TWIM_EVENT_ERROR) returned true\n");
    
        uint32_t err_src = nrf_twim_errorsrc_get_and_clear(reg);
        nrfx_err_t err_code = twi_process_error(err_src);
        printf("nrf_twim_errorsrc_get_and_clear(%d) returned %d \n", reg, err_code);
        nrf_twim_event_clear(reg, NRF_TWIM_EVENT_ERROR);
    }


    The number can then be checked against an nrfx_err_t to decode the error.

    I have two TWI slave devices, but only am only using one at a time.

    I'm currently using nrfx v2.0.

    Cheers,

    S.

Related