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