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

TWI Clearing Bus with NRFX_TWI driver

Hello,

We are using the NRFX_TWI driver which we understand is a new and improved version of the legacy NRF_DRV_TWI driver.  However we are getting a number of apparent stuck-bus errors if our app breaks in the wrong place, and have to completely remove power from the system to get everything un-stuck (simply restarting the code does not help).

It appears this is a common problem and the solution given in https://devzone.nordicsemi.com/f/nordic-q-a/21508/twi-stuck-bus-recovery seems to be simple enough.  However I cannot find an analog for the NRFX_TWI driver, as this is not a valid parameter in the config_t struct:

static const nrfx_twi_config_t twi_config = {
.scl = TWI_SCL,
.sda = TWI_SDA,
.frequency = NRF_TWI_FREQ_400K,
//.clear_bus_init=true, //does not work
.interrupt_priority = TWI_DEFAULT_CONFIG_IRQ_PRIORITY};

Could you advise as to how to clear the bus?

Thanks!

--Allen

Parents
  • Hi Allen,

    As I understand it, NRFX drivers are not the replacement for nrf_drv.

    We want to use the same hal layer over different solutions we have so that the underlying hal layer is not implemented in different ways in different solutions.

    So the nrf_drv_twi API is still the same, the change is that now it uses nrfx_twi below it.

    And in SDK15 you still have the same API for nrf_twi and you still have the clear_bus_init option.

    Now assuming that you know all the above, if you say that the clear_bus_init option is not working. then I am little confused as this option just uses the gpio set clear option and it has not changed at all.

        if(p_config->clear_bus_init)
        {
            /* Send clocks (max 9) until slave device back from stuck mode */
            twi_clear_bus(p_config);
        }

  • Hi,

    I know that this answer come a little late.

    I had the same trouble with a "non-working clear_bus_init".

    In SDK15.3 -> SDK17 (I did not check earlier versions), there is a bug in "twi_clear_bus" if either SDA or SCL is on GPIO_PORT_1.

     

    static void twi_clear_bus(nrf_drv_twi_config_t const * p_config)
    {
        NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF;
        NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF;
    
        nrf_gpio_pin_set(p_config->scl);
        nrf_gpio_pin_set(p_config->sda);
    
        NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF_CLR;
        NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF_CLR;

    Unfortunately, NRF_GPIO is mapped to port 0.

     To fix this issue, it is better to use a call of nrf_gpio_cfg rather than writing directly in NRF_GPIO->PIN_CNF.

     

    static void twi_clear_bus(nrf_drv_twi_config_t const * p_config)
    {
        nrf_gpio_cfg(p_config->scl, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_CONNECT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE);
        nrf_gpio_cfg(p_config->sda, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_CONNECT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE);
    
        nrf_gpio_pin_set(p_config->scl);
        nrf_gpio_pin_set(p_config->sda);
    
        nrf_gpio_cfg(p_config->scl, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE);
        nrf_gpio_cfg(p_config->sda, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE);

     

    This seems to be fixed on new code (but I do not know how to navigate in "Zephir code":

     https://github.com/nrfconnect/sdk-hal_nordic/blob/v1.5.1/nrfx/drivers/src/nrfx_twi_twim.c#L45

  • That is a bug Jeremie, thanks for spelling it out.

Reply Children
Related