0
\$\begingroup\$

I have a LSM6DS3 sensor connected to a MCU by SPI. My goal is to fill the FIFO buffer with the following sets of data: Gx, Gy, Gz, XLx, XLy, XLz, Ts, Pd. I am using a watermark to generate an interrupt once a specific FIFO level is reached.

Furthermore, I am using ST's LSM6DS3 drivers and I followed the application note AN4650 to enable the step counter and timestamp data in FIFO:

  1. Turn on the accelerometer;
  2. Enable the timestamp and pedometer (see Section 6.1 and Section 6.4);
  3. Choose the decimation factor for the 4th FIFO data set through the DEC_DS4_FIFO[2:0] bits of the FIFO_CTRL4 register;
  4. Set to 1 the TIMER_PEDO_FIFO_EN bit in the FIFO_CTRL2 register;
  5. Configure the bit TIMER_PEDO_FIFO_DRDY in the FIFO_CTRL2 register, in order to choose the method of storing data in the FIFO (internal trigger or every step detected);
  6. If an internal trigger is used, choose the FIFO ODR through the ODR_FIFO_[3:0] bits of the FIFO_CTRL5 register. If ‘step detected’ trigger is used, no need to set the ODR_FIFO_[3:0] bits;
  7. Configure the FIFO operating mode through the FIFO_MODE_[2:0] field of the FIFO_CTRL5 register.

I was able to verify that the accelerometer, the gyroscope, the timestamps and the pedometer are working properly (steps 1 and 2). I was also able to verify step 3 to step 7 by reading each register individually.

Here is my configuration code:

void LSM6DS3_FIFO_init(void){
  dev_ctx.write_reg = platform_write;
  dev_ctx.read_reg = platform_read;
  /*
    * Check device ID
    */
   lsm6ds3_device_id_get(&dev_ctx, &whoamI);
   if (whoamI != LSM6DS3_ID)
     while(1)
     {
       PRINTF("ERROR \n");
     }

   /*
    * Restore default configuration
    */
   lsm6ds3_reset_set(&dev_ctx, PROPERTY_ENABLE);
   do {
      lsm6ds3_reset_get(&dev_ctx, &rst);
   } while (rst);

   /*
    * Enable Block Data Update
    */
   lsm6ds3_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);

   /*
    * Set full scale
    */
   lsm6ds3_xl_full_scale_set(&dev_ctx, LSM6DS3_2g);
   lsm6ds3_gy_full_scale_set(&dev_ctx, LSM6DS3_250dps);

   /*
    * Set Output Data Rate for acc/gyro to 52 Hz
    */
   lsm6ds3_xl_data_rate_set(&dev_ctx, LSM6DS3_XL_ODR_52Hz);
   lsm6ds3_gy_data_rate_set(&dev_ctx, LSM6DS3_XL_ODR_52Hz);

   /*
    * Enable pedometer
    */
   lsm6ds3_pedo_sens_set(&dev_ctx, PROPERTY_ENABLE);

   /*
    * Set Low Resolution Timestamp 
    */
   lsm6ds3_timestamp_res_set(&dev_ctx, LSM6DS3_LSB_6ms4);

   /*
    * Enable timestamp in HW
    */
   lsm6ds3_timestamp_set(&dev_ctx, PROPERTY_ENABLE);

   /*
    * Reset Timestamp
    */
   lsm6ds3_timestamp_rst_set(&dev_ctx);

   /*
    * Set FIFO watermark to a multiple of a pattern
    * in this example we set watermark to 32 pattern
    * which means 32 sequence of:
    * (XL) = 6 bytes (3 word)
    */
   pattern_len = 3;
   pattern_numbers = 28;
   number_of_patterns = 3;
   lsm6ds3_fifo_watermark_set(&dev_ctx, pattern_numbers * pattern_len * number_of_patterns);
   lsm6ds3_fifo_stop_on_wtm_set(&dev_ctx, PROPERTY_ENABLE);

   /*
    * Set FIFO mode to Stream to FIFO
    */
   lsm6ds3_fifo_mode_set(&dev_ctx, LSM6DS3_STREAM_MODE);

   /*
    * Set FIFO sensor decimators
    */
   lsm6ds3_fifo_xl_batch_set(&dev_ctx, LSM6DS3_FIFO_XL_NO_DEC);
   lsm6ds3_fifo_gy_batch_set(&dev_ctx, LSM6DS3_FIFO_XL_NO_DEC);
   lsm6ds3_fifo_dataset_4_batch_set(&dev_ctx, LSM6DS3_FIFO_DS4_NO_DEC);

   /*
    * Enable PEDO/TIMESTAMP as 4th data set
    */

   lsm6ds3_fifo_pedo_batch_set(&dev_ctx, PROPERTY_ENABLE);

   /*
    * Set PEDO FIFO storing mode
    */
   lsm6ds3_fifo_write_trigger_set(&dev_ctx, LSM6DS3_TRG_XL_GY_DRDY);

   /*
    * Set ODR FIFO
    */
   lsm6ds3_fifo_data_rate_set(&dev_ctx, LSM6DS3_FIFO_52Hz);

   /*
    * Enable drdy 75 us pulse: uncomment if interrupt must be pulsed
    */
   lsm6ds3_int_notification_set(&dev_ctx, LSM6DS3_INT_PULSED);

   /*
    * Enable interrupt generation on DRDY INT1 pin
    */
   lsm6ds3_pin_int1_route_get(&dev_ctx, &int_1_reg);
   int_1_reg.int1_fth = PROPERTY_ENABLE;
   int_1_reg.drdy_on_int1 = PROPERTY_DISABLE;
   lsm6ds3_pin_int1_route_set(&dev_ctx, &int_1_reg);
}

The issue I am facing is that when I am trying to empty the FIFO and store the data in a buffer, I get incoherent timestamp and pedometer values. The code to empty the FIFO is the following:

void FIFO_Full_Read(void){
      static lsm6ds3_ctx_t dev_ctx;
      static struct DataSet_t FIFO_data[28];
      static uint8_t val=0;
      static uint8_t buffer[504];
      static int8_t tempReg[2]= {0, 0};
      static uint16_t level;
      dev_ctx.write_reg = platform_write;
      dev_ctx.read_reg = platform_read;
      lsm6ds3_fifo_data_level_get(&dev_ctx, &level); //gives the number of words (1 word=2 bytes)
      level/=9;
      PRINTF("The number of sets is %u \n", level);
      lsm6ds3_fifo_full_flag_get(&dev_ctx, &val);
      int i=0;
      while(val!=1){
          lsm6ds3_fifo_full_flag_get(&dev_ctx, &val);
          LSM6DS3_IO_Read(&tempReg[0], LSM6DS3_XG_MEMS_ADDRESS, LSM6DS3_XG_FIFO_DATA_OUT_L, 2);
          buffer[i]=tempReg[0];
          buffer[i+1]=tempReg[1];
          i+=2;
      }
      int j=0;
      for(int i=0; i<level; i++){
          FIFO_data[i].AXIS_X=(int16_t)buffer[j] | (int16_t)buffer[j+1]<<8;
          FIFO_data[i].AXIS_Y=(int16_t)buffer[j+2] | (int16_t)buffer[j+3]<<8;
          FIFO_data[i].AXIS_Z=(int16_t)buffer[j+4] | (int16_t)buffer[j+5]<<8;
          FIFO_data[i].AXIS_GX=(int16_t)buffer[j+6] | (int16_t)buffer[j+7]<<8;
          FIFO_data[i].AXIS_GY=(int16_t)buffer[j+8] | (int16_t)buffer[j+9]<<8;
          FIFO_data[i].AXIS_GZ=(int16_t)buffer[j+10] | (int16_t)buffer[j+11]<<8;
          FIFO_data[i].TIMESTAMP=(((uint32_t)buffer[j+12])<<8) | (((uint32_t)buffer[j+13])<<16) | ((uint32_t)buffer[j+15]);
          FIFO_data[i].PEDOMETER=(uint16_t)buffer[j+16] | (uint16_t)buffer[j+17]<<8;
          PRINTF("AXIS_X %i AXIS_Y %i AXIS_Z %i AXIS_GX %i AXIS_GY %i AXIS_GZ %i TIMESTAMP %lu PEDOMETER %u TROUBLESHOOTING BYTE 12 %u, BYTE 13 %u, BYTE 14 %u BYTE 15 %u \n",FIFO_data[i].AXIS_X, FIFO_data[i].AXIS_Y, FIFO_data[i].AXIS_Z, FIFO_data[i].AXIS_GX, FIFO_data[i].AXIS_GY, FIFO_data[i].AXIS_GY, FIFO_data[i].TIMESTAMP, FIFO_data[i].PEDOMETER, buffer[j+12], buffer[j+13], buffer[j+14], buffer[j+15]);
          j+=18;
      }
}

And now this the kind of output I get when running the code:

AXIS_X 90 AXIS_Y -72 AXIS_Z 16747 AXIS_GX 0 AXIS_GY 1535 AXIS_GZ 1535 TIMESTAMP 15376671 PEDOMETER 5977 TROUBLESHOOTING BYTE 12 161, BYTE 13 234, BYTE 14 177, BYTE 15 31 
AXIS_X 116 AXIS_Y -21 AXIS_Z 16841 AXIS_GX 0 AXIS_GY 2303 AXIS_GZ 2303 TIMESTAMP 16561667 PEDOMETER 64670 TROUBLESHOOTING BYTE 12 182, BYTE 13 252, BYTE 14 217, BYTE 15 3 
AXIS_X 100 AXIS_Y -64 AXIS_Z 16814 AXIS_GX 0 AXIS_GY 3071 AXIS_GZ 3071 TIMESTAMP 15356 PEDOMETER 64923 TROUBLESHOOTING BYTE 12 59, BYTE 13 0, BYTE 14 181, BYTE 15 252 
AXIS_X 86 AXIS_Y -55 AXIS_Z 16867 AXIS_GX 0 AXIS_GY 3839 AXIS_GZ 3839 TIMESTAMP 22268 PEDOMETER 64916 TROUBLESHOOTING BYTE 12 86, BYTE 13 0, BYTE 14 81, BYTE 15 252 
AXIS_X 148 AXIS_Y 127 AXIS_Z 16826 AXIS_GX 0 AXIS_GY 4607 AXIS_GZ 4607 TIMESTAMP 19708 PEDOMETER 65040 TROUBLESHOOTING BYTE 12 76, BYTE 13 0, BYTE 14 78, BYTE 15 252 

Any help would be greatly appreciated.

\$\endgroup\$
  • \$\begingroup\$ Garbage in, garbage out. Somewhere you have simple data corruption, such as start/stop flags, timing of semaphores or buffer-full watermark 1 step out of sync. \$\endgroup\$ – Sparky256 Jan 31 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.