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