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

nRF52832 i2c communication with LIS3DH accelerometer

Hi guys.

I'm working with a nRF52832 custom board.

In my case my board communicates with the LIS3DH through i2c protocol. In the other hand based on LIS3DH datasheet the maximum frequency of its FIFO updating is around 5KHz.

I am trying to read the LIS3DH data in the maximum frequency, but I checked how many cpu cycles was used to read the i2c register.

For read any register from LIS3DH I spend around 10500 CPU cycles. But I need to read 2 registers, OUT_X_L and OUT_X_H. In this case I spend around 21000 cpu cycles.

Analysing the time needed is 215000*1/64000000 = 0,0003359375 seconds.

In frequency terms I have the maximum 3 KHz, this math is just for one axis, there are other two axis: Y and Z.

So, I don't known why my i2c read is too slowly. Does anyone have this problem ? Could anyone help me to improve my i2c read ?

uint8_t i2c_read(uint8_t twi_addr, uint8_t reg, uint8_t * data, uint16_t len)
{
    uint32_t err_code;
    uint32_t timeout = TWI_TIMEOUT;

    twi_tx_done = false;
    err_code = nrf_drv_twi_tx(&m_twi_instance, twi_addr, &reg, 1, false);
    if(err_code != NRF_SUCCESS)
    {
      twi_tx_done = false;
      return err_code;
    }

    while((!twi_tx_done) && --timeout);
    if(!timeout) 
    {
      return NRF_ERROR_TIMEOUT;
    }
		
    twi_rx_done = false;
    err_code = nrf_drv_twi_rx(&m_twi_instance, twi_addr, data, len);
    if(err_code != NRF_SUCCESS)
    {
      twi_rx_done = false;
      return err_code;
    }

    timeout = TWI_TIMEOUT;
    while((!twi_rx_done) && --timeout);
    
    if(!timeout) 
    {
      return NRF_ERROR_TIMEOUT;
    }
    twi_rx_done = false;
		
    return err_code;
}

Parents Reply
  • I had success at reading with this function. I read two registers of OUT_X, but I still spent 13500 CPU cycles to receive those 2 registers data.

    With 13500 cpu cycles, the maximum frequency is 4.7KHz.

    I don't know why my function is too slow. Do you have any suggest ?

    Thanks for reply.

    uint8_t dado[] = {0x0, 0x0};
    uint32_t c_start = DWT->CYCCNT;
    i2c_read(0x19,LIS3DH_OUT_X_L|0x80,dado,2);
    uint32_t c_stop = DWT->CYCCNT;

Children
Related