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

TWIM: TX stuck waiting on NRF_TWIM_EVENT_STOPPED event

Hi,

I'm running into a problem where a TWIM TX call gets stuck internally waiting on the NRF_TWIM_EVENT_STOPPED event. It never breaks out of this while loop in the twim_xfer() function:

        while (!nrf_twim_event_check(p_twim, evt_to_wait))
        {
            if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
            {
                NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
                nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
                nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
                nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
                evt_to_wait = NRF_TWIM_EVENT_STOPPED;
            }
        }

I noticed that this problem is reliably reproduced whenever I call nrf_drv_twi_tx() after reinitializing the TWI driver state. However, upon reinitialization, I change the TWIM instance settings since the attached microcontroller (TI MSP430) has changed from its typical I2C protocol to its bootloader I2C protocol (BSL). The instance settings before the reinitialization are:

    nrf_drv_twi_config_t const config = {
       .scl                = SCL_PIN,
       .sda                = SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_400K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOW,
       .clear_bus_init     = false
    };
    err_code = nrf_drv_twi_init(&m_i2c_twi, &config, m_event_handler, NULL);
    APP_ERROR_CHECK(err_code);
    nrf_drv_twi_enable(&m_i2c_twi);
    nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_RX(I2C_ADDR, m_i2c_buffer, BUFFER_SIZE);
    err_code = nrf_drv_twi_xfer(&m_i2c_twi, &xfer, NRF_DRV_TWI_FLAG_REPEATED_XFER);
    APP_ERROR_CHECK(err_code);

    NRF_GPIOTE->CONFIG[CAPTOUCH_GPIOTE_CH] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
                                             INTERRUPT_PIN << GPIOTE_CONFIG_PSEL_Pos |
                                             GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;
    err_code = nrf_drv_ppi_channel_alloc(&interrupt_ppi_channel);
    APP_ERROR_CHECK(err_code);
    NRF_PPI->CH[interrupt_ppi_channel].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[CAPTOUCH_GPIOTE_CH];
    NRF_PPI->CH[interrupt_ppi_channel].TEP = (uint32_t)&NRF_TWIM0->TASKS_STARTRX;
    NRF_PPI->CHENSET = (1 << interrupt_ppi_channel);

The instance settings after reinitialization are:

    nrf_drv_twi_config_t const config = {
       .scl                = SCL_PIN,
       .sda                = SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_400K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOW,
       .clear_bus_init     = false //true
    };
    ret_code = nrf_drv_twi_init(&m_i2c_twi, &config, NULL, NULL);
    APP_ERROR_CHECK(ret_code);
    nrf_drv_twi_enable(&m_i2c_twi);

The tx call after reinitialization is:

    ret_code = nrf_drv_twi_tx(&m_i2c_twi, BSL_SLAVE_ADDR, writeBuffer, numOfWriteBytes, false);

Right before reinitializing, I call the following:

    NRF_PPI->CHENCLR = (1 << interrupt_ppi_channel);
    err_code = nrf_drv_ppi_channel_free(interrupt_ppi_channel);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_disable(&m_i2c_twi);
    nrf_drv_twi_uninit(&m_i2c_twi);

Are there any problems if I reinitialize the TWI driver? Does my reinitialization process look correct? What sets the STOPPED event?

I'm using nRF SDK 15.2.0

Parents Reply Children
No Data
Related