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

Using the LIS2DH12 driver of the SDK v15.0.0 to configure the LIS2DH12 sensor

Hi everyone,

I'm trying to get the LIS2DH12 driver (SDK v15.0.0) to configure a LIS2DH12 sensor connected to my nRF52 Dev Kit.

I've wired the chip up as follows (using the I2C interface)

nRF52 -> chip
P0.26 -> SDA
P0.27 -> SCL

GND -> GND

VDD -> VDD, VDD_IO, CS, SDO

I've managed to read out the WHO_AM_I register using the driver and poll some samples. The samples do change when I drop my hand on the table on which the sensor is placed.

Now I'm trying to configure the FIFO and an interrupt (for now FIFO watermark) using this function:

#define TWI_INSTANCE_ID             0

#define MAX_PENDING_TRANSACTIONS    33

#define LIS2DH12_MIN_QUEUE_SIZE     32

NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);

NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);

LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);

...

/**
 * initialize and configure LIS2DH12 sensor
 */
void acc_init()
{
	ret_code_t err_code;

	nrf_drv_twi_config_t const config = {
		.scl                = 27,
		.sda                = 26,
		.frequency          = NRF_DRV_TWI_FREQ_100K,
		.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
		.clear_bus_init     = false
	};

	err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
	APP_ERROR_CHECK(err_code);

	err_code = nrf_twi_sensor_init(&m_nrf_twi_sensor);
	APP_ERROR_CHECK(err_code);

	// FIFO configuration
	LIS2DH12_FIFO_CFG(m_lis2dh12, true, LIS2DH12_FIFO, false, 16);

	// data acquisition configuration
	LIS2DH12_DATA_CFG(m_lis2dh12, LIS2DH12_ODR_1HZ, false, true, true, true, LIS2DH12_SCALE_2G, false);

	// interrupt configuration
	LIS2DH12_INT1_PIN_CFG(m_lis2dh12, false, true, false, false, false, true, false, false);

	err_code = lis2dh12_init(&m_lis2dh12);
	APP_ERROR_CHECK(err_code);

	err_code = lis2dh12_who_am_i_read(&m_lis2dh12, print_register, &m_data);
	APP_ERROR_CHECK(err_code);

	//LIS2DH12_INT1_CFG(m_lis2dh12, 100, 1, false, true, false, false, false, false, false, false, false);
	//err_code = lis2dh12_cfg_commit(&m_lis2dh12);
	//APP_ERROR_CHECK(err_code);
}



However I didn't manage to detect any interrupt (even with a oscilloscope) so far and the FIFO seems to be stuck at 32 available values while polling does not change the corresponding register value.

I am at a loss here - from what I've read in the LIS2DH12 data sheet and driver code, the driver seems to do the interfacing with the chip right. I'm suspecting a wrong order in my configuration function or wrong configuration parameters.

Any pointers on what I am doing wrong?

Parents
  • Hi everyone,

    I managed to figure it out on my own!

    Configuration:

    NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);
    
    NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);
    
    LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);
    
    void acc_init()
    {
    	ret_code_t err_code;
    
    	nrf_drv_twi_config_t const config = {
    		.scl                = 27,
    		.sda                = 26,
    		.frequency          = NRF_DRV_TWI_FREQ_100K,
    		.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
    		.clear_bus_init     = false
    	};
    
    	err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = nrf_twi_sensor_init(&m_nrf_twi_sensor);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = lis2dh12_init(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// data acquisition configuration: 10HZ sample rate, low power mode, x axis, y axis, z axis, values in range -2g <-> +2g, disable high resolution mode (in this case step size is 256)
    	LIS2DH12_DATA_CFG(m_lis2dh12, LIS2DH12_ODR_10HZ, true, true, true, true, LIS2DH12_SCALE_2G, 0);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// FIFO configuration: enable FIFO, streaming mode, int1 pin used, 32 values watermark
    	LIS2DH12_FIFO_CFG(m_lis2dh12, 1, LIS2DH12_STREAM, 0, LIS2DH12_MIN_QUEUE_SIZE);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// interrupt configurataion: disable everything except the FIFO watermark interrupt
    	LIS2DH12_INT1_PIN_CFG(m_lis2dh12, 0, 0, 0, 0, 1, 0, 1, 0);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    }


    Interrupt (using P004 and a LED to indicate that an interrupt has happend):

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    	nrf_drv_gpiote_out_toggle(PIN_OUT);
    	data_available = 1;
    }
    
    static void gpio_init(void)
    {
    	ret_code_t err_code;
    
    	err_code = nrf_drv_gpiote_init();
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
    	err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
    
    	err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }
    


    And finally: retrieving and printing the values:

    void acc_print_data()
    {
    	ret_code_t err_code;
    
    	err_code = lis2dh12_data_read(&m_lis2dh12, 0x00, m_sample, LIS2DH12_MIN_QUEUE_SIZE);
    	APP_ERROR_CHECK(err_code);
    
    	for (uint8_t i = 0; i < LIS2DH12_MIN_QUEUE_SIZE; i++)
    		NRF_LOG_INFO("%d %d %d", m_sample[i].x, m_sample[i].y, m_sample[i].z);
    
    }
    
    [...]
    
    	while (true) {
    		// avoid accessing the registers to fast, value arbitrarily chosen
    		nrf_delay_ms(200);
    		// debug: check FIFO_SRC register to see the FSS value rise
    		err_code = lis2dh12_fifo_src_read(&m_lis2dh12, 0x00, &m_data);
    		APP_ERROR_CHECK(err_code);
    		NRF_LOG_INFO("WTM: %d OVN: %d EMPTY: %d FSS: %2d ", (m_data & 0b10000000), (m_data & 0b01000000), (m_data & 0b00100000), (m_data & 0b0001111));
    
    		// do not try to access FIFO values if watermark was not reached yet
    		if (!data_available)
    			continue;
    
    		// collect and print the data
    		acc_print_data();
    		// "reset" interrupt
    		data_available = 0;
    		nrf_drv_gpiote_out_toggle(PIN_OUT);
    
    		NRF_LOG_FLUSH();
    	}


    I've encountered following "issues":
    * fatal system error on the nRF52 side if the watermark was not reached but data is read
    * accessing the sensor's registers to fast

    I don't know whether or not I'm still doing something wrong which then leads to the issues ...

Reply
  • Hi everyone,

    I managed to figure it out on my own!

    Configuration:

    NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);
    
    NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);
    
    LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);
    
    void acc_init()
    {
    	ret_code_t err_code;
    
    	nrf_drv_twi_config_t const config = {
    		.scl                = 27,
    		.sda                = 26,
    		.frequency          = NRF_DRV_TWI_FREQ_100K,
    		.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
    		.clear_bus_init     = false
    	};
    
    	err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = nrf_twi_sensor_init(&m_nrf_twi_sensor);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = lis2dh12_init(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// data acquisition configuration: 10HZ sample rate, low power mode, x axis, y axis, z axis, values in range -2g <-> +2g, disable high resolution mode (in this case step size is 256)
    	LIS2DH12_DATA_CFG(m_lis2dh12, LIS2DH12_ODR_10HZ, true, true, true, true, LIS2DH12_SCALE_2G, 0);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// FIFO configuration: enable FIFO, streaming mode, int1 pin used, 32 values watermark
    	LIS2DH12_FIFO_CFG(m_lis2dh12, 1, LIS2DH12_STREAM, 0, LIS2DH12_MIN_QUEUE_SIZE);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    
    	// interrupt configurataion: disable everything except the FIFO watermark interrupt
    	LIS2DH12_INT1_PIN_CFG(m_lis2dh12, 0, 0, 0, 0, 1, 0, 1, 0);
    	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
    	APP_ERROR_CHECK(err_code);
    }


    Interrupt (using P004 and a LED to indicate that an interrupt has happend):

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    	nrf_drv_gpiote_out_toggle(PIN_OUT);
    	data_available = 1;
    }
    
    static void gpio_init(void)
    {
    	ret_code_t err_code;
    
    	err_code = nrf_drv_gpiote_init();
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
    	err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
    
    	err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }
    


    And finally: retrieving and printing the values:

    void acc_print_data()
    {
    	ret_code_t err_code;
    
    	err_code = lis2dh12_data_read(&m_lis2dh12, 0x00, m_sample, LIS2DH12_MIN_QUEUE_SIZE);
    	APP_ERROR_CHECK(err_code);
    
    	for (uint8_t i = 0; i < LIS2DH12_MIN_QUEUE_SIZE; i++)
    		NRF_LOG_INFO("%d %d %d", m_sample[i].x, m_sample[i].y, m_sample[i].z);
    
    }
    
    [...]
    
    	while (true) {
    		// avoid accessing the registers to fast, value arbitrarily chosen
    		nrf_delay_ms(200);
    		// debug: check FIFO_SRC register to see the FSS value rise
    		err_code = lis2dh12_fifo_src_read(&m_lis2dh12, 0x00, &m_data);
    		APP_ERROR_CHECK(err_code);
    		NRF_LOG_INFO("WTM: %d OVN: %d EMPTY: %d FSS: %2d ", (m_data & 0b10000000), (m_data & 0b01000000), (m_data & 0b00100000), (m_data & 0b0001111));
    
    		// do not try to access FIFO values if watermark was not reached yet
    		if (!data_available)
    			continue;
    
    		// collect and print the data
    		acc_print_data();
    		// "reset" interrupt
    		data_available = 0;
    		nrf_drv_gpiote_out_toggle(PIN_OUT);
    
    		NRF_LOG_FLUSH();
    	}


    I've encountered following "issues":
    * fatal system error on the nRF52 side if the watermark was not reached but data is read
    * accessing the sensor's registers to fast

    I don't know whether or not I'm still doing something wrong which then leads to the issues ...

Children
No Data
Related