cancel
Showing results for 
Search instead for 
Did you mean: 

FIFO_Pattern seems desynchronized

DMeye.4
Associate II

I have configured the LSM6SDM into continuous mode, 104Hz as is described in AN487, Example 1. I am reading first the number of words in the FIFO, and then the FIFO Pattern (from FIFO Status 3).

Here are some code snippet for initialization:

unsigned char init[6][2]={

{0x08,0x09}, // FIFO_CTRL3 set to no decimation (accel+gyro)

{0x0a,0x26}, // FIFO_CTRL5 set to continuous mode, 104 Hz (accel+gyro)

{0x10,0x40}, // CTRL1_XL set to 104Hz, +/- 2g, ODR/2

{0x11,0x42}, // CTRL2_G set to 104Hz, +/- 125 dps

{0x12,0x44}, // CTRL3_C set to BDU + IF_INC

{0x14,0x60}}; // CTRL5_C set to rounding for accel+gyro

for (i=0;i<6;++i)

write(i2c_fd,&init[i][0],2);

Roughly every 100ms I call a function which does the following:

write(i2c_fd,&fs1,1); // Read FIFO_STATUS1

read(i2c_fd,data,2);

numsamples=((data[1]&7)<<8)+data[0];

if ((data[1]&64)==64) numsamples=1023; // I don't really understand this, but sometimes the FIFO shows 0 bytes available until the first read

write(i2c_fd,&fs3,1); // Read FIFO_STATUS3

read(i2c_fd,,&fp,1); // Get FIFO Pattern (ignoring the top 8-bits because it should never exceed 5

switch (fp) { // Ignore incomplete data based on FIFO_Pattern

case 1 : start=2; fp=3; break;

case 2 : start=1; fp=3; break;

case 4 : start=2; fp=0; break;

case 5 : start=1; fp=0; break;

default : start=0;

}

numsamples-=(numsamples-start)%3; // Adjust numsamples to bring in an integer number of 3-axis samples plus whatever is at the front of the buffer. That means after the first read, it should always be aligned with either fp=0 or fp=3.

write(i2c_fd,&fsl,1); // Read FIFO_DATAOUT_LOW

read(i2c_fd,data,numsamples<<1); // Collect the data

Of the 6 words, one of them is approximately 16600, the remainder are <400. I think it's reasonable to assume since the board is sitting on my bench, that the 16600 number is Az (FIFO_Pattern=5), we can figure out the others from that and they appear to be in order. But when Az is the first word to be read, FIFO_Pattern isn't always 5. It seems to drift, as if some reads do not update FIFO_Pattern, or update it too much. Once it gets desynchronized, it stays desynchronized for hundreds, thousands, or even tens of thousands of patterns before it appears to jump again. So I believe whatever is causing it is screwing something up on chip, it's not garbled communications (and the number in FIFO_Status3 is always between 0 and 5).

3 REPLIES 3
Eleon BORLINI
ST Employee

Hi @DMeye.4​ ,

can you please have a look to the C examples on Github, lsm6dsm_read_fifo.c and lsm6dsm_fifo_stream_to_fifo.c, if there is something that can help you?

It is however strange that the device works for tens of thousands of patterns and then it get desynchronized after a glitch... can you test the code also on another sample, to see if it is a device-related issue or a code/board issue?

-Eleon

DMeye.4
Associate II

Hello Eleon,

I have four boards built up (they were professionally built up). I have tested two boards so far, both exhibit the problem. I'm not sure how I'd easily go about isolating it to whether it's my hardware setup or software setup or a problem elsewhere... The hardware should be a CubieBoard2 (embedded Linux board similar to Raspberry Pi) talking to a separate board with the LSM6DSM (and 2 LPS22's and a few other parts) on it. All are communicating over i2c. I believe the LSM6DSM is the only one being actively communicated with. The board itself is powered by 5V from the CubieBoard, and there is a 3.3V linear regulator powering the part. VDD and VDDIO are both bypassed by 100nF caps at the part. The regulator itself has pi filter consisting of a 10uF cap, ferrite beads, and a 1uF cap, there is then a pair of ferrite beads which connect from the output of the pi filter to the two 100nF caps. Pretty sure it's good filtration.

I did notice something that I found a bit disturbing on the LPS22HH. I was curious about the timing jitter -- that is, if you were to measure the time between samples at a fixed ODR, what would the mean and standard deviation be. I wrote a quick program which basically polls the FIFO_STATUS. When there is a sample available, I'd write the time out, read the sample, and then proceed to poll until the next sample showed up. And keep doing this indefinitely.

When I did that, I found that within 1ms of reading the data out, the FIFO was already reading 1, despite an ODR of 75Hz, which means, that samples should have been coming 13-14ms apart. I tried changing it so that I didn't perform the read or report the time until the FIFOSTATUS showed 3 available. Suddenly, it worked perfect, all samples were 13-14ms apart. So now I'm wondering why? Is the FIFO_STATUS reading bytes available rather than words (the LPS22HH has 24-bit pressure words)? If so... is the LSM6DSM reading bytes as well?

I was setup with a 104Hz FIFO ODR, 104Hz Accelerometer ODR, 104Hz Gyro ODR... When it shows a FIFO status of 6 does this mean 6 (16-bit) words i.e. Gx, Gy, Gz, Ax, Ay,Az or did it mean 6 bytes (Gx, Gy, Gz OR Ax,Ay,Az). If it's the latter, then I'm definitely reading past the end of the FIFO -- although this would also imply that for a 104Hz Accel + 104Hz Gyro, I'd want a 208Hz FIFO. There's nothing about the documentation that would lead me to believe the latter, but there's nothing about the documentation that would lead me to believe that I shouldn't read out an LPS22HH until FIFOSTATUS shows 3 samples available.

dan

DMeye.4
Associate II

I tried a couple experiments:

1) I tried changing FIFO to 208Hz, this made no difference.

2) I tried only reading FIFO_STATUS1 worth of bytes rather than 2*FIFO_STATUS1. When I did this, FIFO_STATUS1 from block read to block read went from the original number to 2*original number. This seems consistent with it being the number of samples not bytes, I.e. if you read: (((((1)/2+1)/2+1)/2+1)/2+1)/2... it eventually should (and does reach 2).

Neither seemed to alter the improper behavior.