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

nrf52832 + LIS2DH12 : Issue using I2C : no address acknowledge (NACK) received

Hi !

I'm using the nrf52832 chip and I'm trying to communicate with a LIS2DH12 accelerometer using the I2C protocol.

But unfortunately I can't handle with it, it seems that the accelerometer doesn't respond at his adress...

So first here is my hardware connections : 

The pin are connected as follow to the nrf52832 : 

SDA - P0.14

SCL - P0.15

As said in the LIS2DH12 datasheet, the SD0 pin is connected to the supply voltage so the I2C address of the accelerometer is 0x19.

Here are the relevant firmware parts : 

1) Address of the LIS2DH12

/* TWI instance ID. */
#define TWI_INSTANCE_ID     0
/* Common addresses definition for temperature sensor. */
#define C_ACCELEROMETER_I2C_ADDR        0x19 

2) twi_handler() and twi_init()

/**
 * @brief TWI events handler.
 */
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                data_handler(m_sample);
            }
            m_xfer_done = true;
            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_lm75b_config = {
       .scl                = 15, 
       .sda                = 14,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

So as you can see, I've just followed the nordic example (twi_sensor).

But when I try to configure the accelerometer with this function : 

/**
 * @brief Function for LIS2DH accelerometer config.
 */
void fn_configure_LIS2DH_accelero(void)
{
    ret_code_t err_code;

    //lire  who i am
    
    m_xfer_done = false;    
    uint8_t reg2[2] = {C_WHO_AM_I, 0x00};      
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg2, 1, true);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */  
    err_code = nrf_drv_twi_rx(&m_twi, C_ACCELEROMETER_I2C_ADDR, m_sample_axis, 1); 
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
  
    
     /* Writing . */
    m_xfer_done = false;
    reg[0] = C_CTRL_REG1;
    reg[1] = 0x37;			//Oliver : X,Y,Z axis enabled ; Sampling Rate = 25Hz
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, true);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
     
    m_xfer_done = false;
    reg[0] = C_CTRL_REG2;
    reg[1] = 0x09;                      //High-pass filter enabled on interupt activity 1
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    reg[0] = C_CTRL_REG3;
    reg[1] = 0x40;                      //IA1 Interupt on pin INT1
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    reg[0] = C_CTRL_REG4;
    reg[1] = 0x10;                      //Olivier : full scale +/- 4g
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    reg[0] = C_CTRL_REG5;
    reg[1] = 0x08;                      //Interupt 1 pin latched
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    reg[0] = C_INT1_THS;
    reg[1] = 0x08;                      //INT1 threshold to 8 * 32mg = 256mg (32mg per LSB at Full Scale = +/-4g
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    reg[0] = C_INT1_DURATION;
    reg[1] = 0x02;                      //INT1 duration = 2/ODR so at 25Hz, duration = 80ms
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

    //dummy read of reference to force the HP to the current accelerometer value
    m_xfer_done = false;
    reg[0] = C_REFERENCE; 
    reg[1] = 0x00;
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 1, true);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
    m_xfer_done = false;
    err_code = nrf_drv_twi_rx(&m_twi, C_ACCELEROMETER_I2C_ADDR, &m_reference, 1); 
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    //end of read
    
    m_xfer_done = false;
    reg[0] = C_INT1_CFG;
    reg[1] = 0x02;                      // Enable XH interrupt generation
    err_code = nrf_drv_twi_tx(&m_twi, C_ACCELEROMETER_I2C_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    
}

The program get stuck in the first while loop : 

while (m_xfer_done == false);

And using a breakpoint, I can see that the twi_handler() is called because an NRF_DRV_TWI_EVT_ADDRESS_NACK event is rised.

So it seems that the lis2dh12 does not respond...

I tried to "scan" every adresses from 1 to 126 and for each I receive the same event : NRF_DRV_TWI_EVT_ADDRESS_NACK

Is there a configuration that I forgot ? Maybe the SDA and SCL pins needs to an internal pull-up ?

I don't understand, so if someone could help me, it would be great !

Thank you !!

Olivier

Parents Reply Children
No Data
Related