What is the correct way to enable the FIFO interrupt in LIS2DH12?

Hi there,
I’m facing an issue in enabling the FIFO interrupt functionality in LIS2DH12. Here’s the details.

First, I forked the Ruuvitag firmware repository (here) and I’ve added a new function in app_sensor.c to enable the FIFO interrupt (similarly to this one)

At this point, I defined a handler function for FIFO interrupts:

At the moment, the fifo_task function prints a log with a timestamp (ms) followed by a string (“FIFO called”)

Then, I edited app_main.c in order to call the app_sensor_acc_fifo_set function from above.

I’ve also set APP_SENSOR_LIS2DH12_SAMPLERATE to 50Hz, increased the advertising frequency (i.e APP_BLE_INTERVAL_MS) to 3 seconds and set APP_NUM_REPEATS to 1. In this way, the Ruuvitag should send a BLE advertisement packet every 3 seconds (since APP_NUM_REPEATS is set to 1).

Additionally, I’ve enabled logging (RI_LOG_ENABLED) and set the log level (APP_LOG_LEVEL) to “INFO” (RI_LOG_LEVEL_INFO).

Finally, I erased the chip and flashed the firmware using SEGGER Embedded Studio (project “ruuvitag_b”) and the Ruuvitag development kit. The application mode was set to “Release”.

Here’s a screenshot:

In general, it seems that FIFO interrupts are triggered approximately every 3 seconds. For instance, the third “FIFO called” log (6491: FIFO called) is printed after (6491 - 3482)/1000=3.009 seconds from the second one (“3482: FIFO called”).

From my understading, FIFO interrupts should be fired roughly every 32/APP_SENSOR_LIS2DH12_SAMPLERATE since the LIS2DH12 FIFO buffer can hold up to 32 samples. Given that APP_SENSOR_LIS2DH12_SAMPLERATE is 50, we should expect the “FIFO interrupt” log to be printed every 32/50=0.64 seconds. However, it seems that interrupts are triggered every APP_HEARTBEAT_INTERVAL_MS*1000 seconds.

Indeed, by printing additional logs, I found out that FIFO interrupts are triggered almost every time the app_sensor_get function in app_sensor.c is called, that is, every APP_HEARTBEAT_INTERVAL_MS milliseconds:

Perhaps, FIFO interrupts are triggered when the ri_lis2dh12_data_get function in ruuvi_interface_lis2dh12.c gets called from app_sensor_get.

I’ve also tried setting APP_SENSOR_LIS2DH12_SAMPLERATE to a different value (100Hz), but FIFO interrupts are still fired every 3 seconds.

Given that I’m a beginner, it is very likely that I didn’t properly enabled the FIFO functionality at all.

Any hints on what I should do to enable FIFO interrupts would be greatly appreciated.


Perhaps, FIFO interrupts are triggered when the ri_lis2dh12_data_get function in ruuvi_interface_lis2dh12.c gets called from app_sensor_get.

On a quick look, it seems to me that this is the case. Do you read the FIFO completely when the interrupt is triggered? If not, here’s what would happen:

  1. FIFO gets full → interrupt
  2. data_get is called → 1 element is read → FIFO has space for new element
  3. FIFO gets full → interrupt
  4. Back to 2.

This would explain the behavior you’re seeing. As a fix, you should read the FIFO when the FIFO interrupt comes. Please also note that nRF52 is configured to use port-level GPIO interrupts to save power. This means that if you’re using both threshold and FIFO interrupt at the same time, one interrupt will be missed when threshold and FIFO full interrupt fire on same accelerometer sample.

I hope this helps, driver/integration_tests folder also has test for FIFO interrupts which provides a sample on how the FIFO can be read.

1 Like

Hi @otso ,
sorry for the late response and thanks for your reply.

Yes, I was just logging instead of reading the FIFO buffer, and your explanation makes perfect sense. I should’ve tried to read the FIFO buffer before asking you this question about FIFO interrupts.

By the way, I followed your advice and edited my code according to this and, indeed, by reading the FIFO buffer every time an interrupt occurs, the buffer is cleared and this, in turn, let the interrupt timings to be the expected one.

Thanks again for your response :slight_smile: