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

LSM6DSL problem to start via i2c

Hello!

I have a custom pcb with Lsm6dsl connect to nrf52832 via i2c.

I can write and read regs of Lsm6dsl well ( reg "who_am_I" return 0x6a as describe in datasheet ).

The problem appears when I try to write "ODR" (output data rate) bits in CTRL1_XL (10h) reg (for example 0x10). This bits must turn on an accelerometer. After the transaction, I can no longer access  Lsm6ds because it always return NRF_DRV_TWI_EVT_ADDRESS_NACK.. like there is no i2c slave on this address.

If I write other bits in CTRL1_XL (10h) reg that do not enable accelerometer (for example 0x0f) it work OK.

Can anybody help me, what it is the problem?

Here is programm code:

static const nrf_drv_twi_t m_twi_lsm6dsl = NRF_DRV_TWI_INSTANCE(0);

uint8_t address_acc = 0x6aU;
uint8_t reg_odr_sys_on[2] = {0x10U, 0x10U};
uint8_t who_am_i_buffer = 0;
uint8_t reg_who_am_i_buffer_read[1] = {0x0fU};

/**
* @brief TWI events handler.
*/
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{ 
    ret_code_t err_code;

    switch(p_event->type)
    {
         case NRF_DRV_TWI_EVT_DONE:
         break;
         case NRF_DRV_TWI_EVT_ADDRESS_NACK: 
         break;
         case NRF_DRV_TWI_EVT_DATA_NACK: 
         break;
         default:
         break; 
    }
}

/**
* @brief twi initialization.
*/
void twi_init (void)
{
    ret_code_t err_code;
    
    const nrf_drv_twi_config_t twi_lsm6dsl_config = {
    .scl = 06,
    .sda = 07,
    .frequency = NRF_TWI_FREQ_100K,
    .interrupt_priority = APP_IRQ_PRIORITY_LOW
    };

    err_code = nrf_drv_twi_init(&m_twi_lsm6dsl, &twi_lsm6dsl_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);
    
    nrf_drv_twi_enable(&m_twi_lsm6dsl);
}

int main(void)
{

    twi_init();

    ret_code_t err_code;
    
    err_code = nrf_drv_twi_tx(&m_twi_lsm6dsl, address_acc, reg_who_am_i_buffer_read, sizeof(reg_who_am_i_buffer_read), false); 
    APP_ERROR_CHECK(err_code); 
    nrf_delay_ms(100);
    
    err_code = nrf_drv_twi_rx(&m_twi_lsm6dsl, address_acc, &who_am_i_buffer, sizeof(who_am_i_buffer));
    APP_ERROR_CHECK(err_code); 
    nrf_delay_ms(100);
    
    err_code = nrf_drv_twi_tx(&m_twi_lsm6dsl, address_acc, reg_odr_sys_on, sizeof(reg_odr_sys_on), false); 
    APP_ERROR_CHECK(err_code); 
    nrf_delay_ms(100);


    while(true)
    {
    }
}

Parents
  • Do you have a logic analyzer that you can use to capture what goes on on the bus?

    What happens if you remove the code reading from the who am I registers? The LSM6DSL's datasheet states that you need a repeated start condition between TX and RX operations and you don't have that. I'm not sure it if it is related though, and it is i odd that a read operation would work, but not subsequent write operations. 

    To use repeated start, please use:

    nrf_drv_twi_tx(..., ..., ..., ..., true); 

    before

    nrf_drv_twi_rx(..., ..., ..., ...); 

  • Hi!

    Thanks for reply! 

    Today I discovered a problem. I have two different power supply net on nrf52832 and LSM6DSL (with common ground) on my custom board. After connecting to one common power supply net,  programm  code work good.

Reply Children
No Data
Related