Levente,
There is actually a solution to your problem. From your initial post you stated you are running at 800Hz and at this frequency you are dropping samples. To me that's somewhat surprising, 800Hz is actually pretty slow and if you are dropping samples then somewhere you are getting IO bound. So I decided to go and have a read of the datasheet and think about it over a cup of tea.
The solution I came up with is probably more complex but when you think about it, it'll make sense. The first thing that the datasheet showed was that the device supports a FIFO mode called streaming. The FIFO is 32samples in depth and provides a "watermark" interrupt. The trick here is simple when you know but not obvious and it's use the GPDMA to move the data out of the device into a buffer area. However, getting all this married together isn't simple. So let me describe how I would do it:-
First, we need two buffers. Each buffer is made up of blocks, the block size memory area should match the number of samples * the watermark. So, lets imagine this for a second. Say we set the watermark to 16samples. Since each axis is two bytes of data our block needs to be 32bytes in size. Now, if we say we have 64 blocks in one buffer, that's just 2k for a buffer. Two buffers therefore use 4k.
Why two buffers? Well, here's how it works.
When the watermark IRQ fires, we setup the GPDMA/SPI to stream read the ADC345 registers using one GPDMA channel. That DMA channel is setup to point at a const memory buffer that merely describes the ADC read operation. Then another channel is used to read the SPI coming back into a block. Each time a watermark IRQ fires GPDMA transfers the data the next block, so on and so on. Until a buffer is full. When the buffer (2k) is full, you switch to the second 2k buffer and start all over.
While the second buffer is filling in DMA stream mode, you now have plenty of time to write the first buffer via USB to the memory stick. The whole operation just "round robins" swapping back and forth between the two buffers.
By using the GPDMA to manage the IO portion of the data transfers it should be able to keep up quite easily. Your CPU should have time left over to try and calculate a new decimal place of PI ;)
The tricky part is arranging the GPDMA transfers at each watermark IRQ. Also, the datasheet notes you'll have to run the SPI below 1.6MHz to ensure the transfers from FIFO to data registers.
Anyway, something for you to chew on! Have fun!
Btw, I have a GPDMA library, MODDMA, that makes handling the GPDMA setup in real simple ways using configurations. You could setup a configuration on a per block basis.
Andy
[edit: I should add I have used this technique before, just not with an ADC345 and it works quite well.]
Hello,
I'am building an acceleration data logger. (ADXL345 through 4-wire SPI, to USB mass storage). My sample rate is 800Hz which seems to be too high frequency to write it continuously to the USB. So at the moment I am missing some samples time to time. I accepted this and want to rebuild the missing section of my acceleration signal with some array filling/filtering method. To do this I will need to add a sequence number front of each set of samples.
Firstly I tried to use the InterruptIn interrupt triggered from the DATA_READY interrupt of the ADXL345, but it seems the InterruptIn has no priority over the other lines of the code.
My second attempt is to use the Ticker to increase the value of a variable, which then can be then used as the data sequence number. I set the Ticker to 1250us but somehow the output txt file I'm recording has repeatedly the same value (ticker did't call the func?) and then some missing (not after the data reaching the 512byte block size to transfer the USB how would expect it). /media/uploads/levissz/code_secion.txt
I would appreciate any suggestion how I could modify my code or hardware to achieve a correct sequence number generation, preferably from the data ready interrupt of the ADXL345.
Thanks Levente