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

TWI Blocked waiting for event

Hello dear Nordic community,

We have developed a custom board that contains the nordic nrf52832, which is communicating via I2C bus with a 9-axis sensor (Bosch BMX055), composed by an accelerometer, gyroscope and magnetometer.

We have successfully programmed our first release of the software with all the communications efectively working, but now, from all of the sudden, we have no communication with the BMX055 while initializing it. I have seen similar issues, but so far, we couldn't unblock this. It seems that the I2C bus is stuck, but we don't find the way to recover things back to normal when flashing it again.

While debugging, we get an infinite loop, located in the nrfx_twim.c :

     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;
            }
        }

This is invoked by the inizialization function of the BMX055

BMA2x2_RETURN_FUNCTION_TYPE bma2x2_init(struct bma2x2_t *bma2x2) {
    /*  Variable used to return value of
	communication routine*/
    
    BMA2x2_RETURN_FUNCTION_TYPE com_rslt = ERROR;
    u8 data_u8 = BMA2x2_INIT_VALUE;
    u8 config_data_u8 = BMA2x2_INIT_VALUE;
    /* assign bma2x2_acc ptr */
    p_bma2x2 = bma2x2;
    if (p_bma2x2 == BMA2x2_NULL) {
        /* Check the struct p_bma2x2 is empty */
        com_rslt = E_BMA2x2_NULL_PTR;
    } else {
        /* read Chip Id */
        com_rslt = p_bma2x2->BMA2x2_BUS_READ_FUNC
        (p_bma2x2->dev_addr,
         BMA2x2_CHIP_ID_REG, &data_u8, BMA2x2_GEN_READ_WRITE_LENGTH);
        p_bma2x2->chip_id = data_u8;    /* get bit slice */
        /* read the fifo config register and update
		the value to the fifo_config*/
        com_rslt += bma2x2_read_reg(BMA2x2_FIFO_MODE_REG,
                                    &config_data_u8, BMA2x2_GEN_READ_WRITE_LENGTH);
        p_bma2x2->fifo_config = config_data_u8;
    }
    return com_rslt;
}

Concretely, it happens in the line that reads the Chip Id from the I2C bus.

We have tried to implement some timeouts in the loop, as suggested here. Doing that, the firmware runs, but with an unwanted result, being the accelerometer not initialized, and therefore, unusable.

Could you give me any recommendations? Don't hesitate to ask if you need more data

Update: the function for reading from the accelerometer is based on bosch drivers, which are here

s8 BMX_I2C_read(u8 dev_id, u8 *reg_addr, const u8 *reg_data, u8 len) {
    int8_t rslt = 0;


    nrf_gpio_pin_set(TWI0_ENB_PIN);
    //nrf_gpio_pin_set(0x11);
    NRF_LOG_INFO("m_twi 0x%x, dev_id 0x%x, reg_addr 0x%x",&m_twi,dev_id,reg_addr);
    rslt = nrf_drv_twi_tx(&m_twi, dev_id, reg_addr, 1, false);
    if (rslt == 0) {
        rslt = nrf_drv_twi_rx(&m_twi, dev_id, reg_data, len);
    }
    nrf_gpio_pin_clear(TWI0_ENB_PIN);
    return rslt;

}

Best regards

Related