Best way to aquire data from SPI

Showing results for 
Show  only  | Search instead for 
Did you mean: 

Best way to aquire data from SPI

Contributor III

Hi community,

I'm using an external ADC with my kinetis k64.

The micro is configured as SPI Master.

The ADC is sampling two analog signals at 42 KiloSamplesPerSeconds.

A GPIO input pin (configured as interrupt), drives me a falling edge at each new sample. Then I need to send 12 bytes through SPI to get the samples (4 bytes status, 4 bytes sample channel 1 and 4 bytes sample 2).

After some testbenches, I see that it is impossible to work in interrupt mode. This make the microcontroller "crazy".

Note that for each 16 samples I need to write the block of aquiered data into a flash memory.

My question is:

What is the best model to use with DMA/SPI ?

Is there a way to start a DMA transfer with gpio interrupt ?

The operation should be:

1) Interrupt occurs (DMA trigger)

2) DMA send through SPI 12 bytes

3) The retrieve data are stored in memory.

4) After 16 samples, write the block into memory, but should not stop the data retrieval.

Any idea ?


Tags (1)
0 Kudos
2 Replies

Specialist V


- All GPIOs have DMA trigger capability.

- Beware that the K64 has 3 SPIs but only one of them is buffered (SPI0)
- There are two flash planes in the K64 so it is possible to write data to the upper half of flash while the code is still working in the lower half (no interrupt complications)
- Writes to Flash are 8 bytes in length each so buffer the data to this length (best in a RAM buffer which can be committed in a ping-pong fashion)

- Interrupts shouldn't be a problem and often are easier at the end of the day, since often some on-the-fly processing is required at some point

I have used the uTasker project [] a number of times in similar projects (which also allows complete simulation) where ADC rates of 320kBytes via SPI with some on-the-fly DSP processing (floating point calculations) are not a problem for the K64 in interrupts. The IRQ requires about 50..60% of the processing power but this is not usually noticeable overall.



0 Kudos

Senior Contributor III

Before you give up entirely on interrupt-mode, know that it is NOT 'impossible'.  42Ks/s comes to 'every 20.8us', so IF your general firmware environment allows tight latency (helped by putting THIS IRQ alone on the highest priority, and never use 'global disable' but only change BASE_PRI to quench all other interrupts) THEN:  all we need to do is keep each data-interrupt-handling at about 10us 'or so' and the 'general handling' of this data IS possible.  I find that to hit this kind of overall-processing one needs control the SPI interface directly in the IRQ code, and we need to fully utilize the FIFO capabilities of the Kinetis SPI interface.  That is, you blast four 'byte transactions' into the TX FIFO to instigate the receive of the first 4 status bytes, and while those 4 'trickle in' you do your basic setup for the IRQ, and when you've done these things spin waiting for the RX queue to come 'full' with 4 bytes.  By continuing with this send and receive overlap, you can get the 'whole' IRQ handler done in 'little more time' than the raw transfer time for SPI --- I assume you might run something like 16MHz to net your 12bytes 'possible in 6us'.

You don't give us any details on how this 'flash write' needs to occur, but since such writes are 'inherently slow' it seems like THOSE functions are going to drive how you handle data overall.  If you mean INTERNAL flash, then things get MUCH more complicated..

0 Kudos