Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Correct order of nrf_drv_twi commands

Hi, I try to read data from the ICM20948 IMU with I2C from my nRF 52840 DK.

Initialization of the device is correct, the IMU ID is sent to nRF correctly which means that the TWI protocol works fine  but when I initiate the process to read the accelerometer and gyroscope data from the IMU, the following error appears in the terminal emulator   app: ERROR 17 [NRF_ERROR_BUSY] at  ... ... ...  ICM20948.c:180.

The part of code that is pointed is line 12  in the following code snippet

void read_IMU(void){
   
       uint8_t pinax[] = {ICM20948_ACCEL_XOUT_H};
       int8_t rawData[12] = {0};
    
       err_code = nrf_drv_twi_tx(&m_twi, ICM20948_ADDRESS, pinax, sizeof(pinax), false); 
       while(nrf_drv_twi_is_busy(&m_twi));
       APP_ERROR_CHECK(err_code);
       
       err_code = nrf_drv_twi_rx(&m_twi, ICM20948_ADDRESS, &rawData[0], 12);      
       //while(nrf_drv_twi_is_busy(&m_twi));     
       APP_ERROR_CHECK(err_code); //   <<<===== ERROR 17 [NRF ERROR BUSY]
       
       accel_buffer[0] = (int16_t) ((rawData[0] << 8) | rawData[1]); // x axis raw data
       accel_buffer[1] = (int16_t) ((rawData[2] << 8) | rawData[3]); // y axis raw data
       accel_buffer[2] = (int16_t) ((rawData[4] << 8) | rawData[5]); // z axis raw data
    
       gyro_buffer[0] = (int16_t) ((rawData[6] << 8)  | rawData[7]);  // x axis raw data
       gyro_buffer[1] = (int16_t) ((rawData[8] << 8)  | rawData[9]);  // y axis raw data
       gyro_buffer[2] = (int16_t) ((rawData[10] << 8) | rawData[11]); // z axis raw data
}

Now, if I add this line of code ---> while(nrf_drv_twi_is_busy(&m_twi));  before the APP_ERROR_CHECK() in line 11, the problem disappears

but in the next command  where I want to fetch the IMU data ---> nrf_drv_twi_rx()  , the  SDA line stays low and no stop is produced from the nRF52840 TWI.

As a result I cannot get an RX event from the nRF.   What am I doing wrong here?

Also, I cannot understand if the way that I am using nrf_drv_twi_is_busy(&m_twi) is correct or if I should use it another way

Thank you for your time

Parents Reply
  • Hello masterLee,

    I am using nrf52840 with SDK 15.3. I see a lot of twi drivers and its confusing which one to use. I want to read the ICM 20948 sensor data in burst mode for my application. In the second step I want to use the tap detection in DMP, so i have to write the DMP firmware into the ICM. But my twi drivers seem to constantly return with err_code 0x11 or 0x03 errors. Please let me know which is the best twi drivers for ICM. Your help would be much appreciated. Thanks and regards.

Children
  • Use nrf_drv_twi.h . Basicaly what you need to do as a first step would be to read the device ID of ICM20948. The code for the ID is given in the sensor's datasheet.

    If you receive the same ID with the datasheet then your TWI  communication is working. If you receive garbage data, check the TWI handler function and the places you assign your twi_xfer_done flag to false. Also you should note that it is a good practice to reset the ICM20948 before performing anything else.

Related