1
\$\begingroup\$

I am collecting data from several dozen sensors over an 8 MHz SPI bus at 400 Hz. It is critical that the sensors are sampled at this rate with no lost packets. In order to do this, I have a timer (which I will refer to as TimerA) which raises an interrupt every 2.5 milliseconds. To store the large amount of data, I am using an SD card.

Here is my current program flow

  • Within the TimerA ISR, data is collected from all the sensors. This takes approximately 1 millisecond.
  • This data sample is stored in a FIFO buffer. The buffer can store up to 400 samples (1 second of data).
  • Each time a sample is written to the buffer, an index k is incremented. k keeps track of the number of samples in the FIFO buffer.
  • The main() loop watches the index k. If k > 0, it pulls an entry from the FIFO buffer, processes it, then stores the result in the SD card write buffer. k is decremented.
  • Once the SD card write buffer reaches 512 bytes, the SD card write buffer is written to the SD card.

I know that having the data acquisition within the TimerA ISR is a no-no as the ISR code should be short and sweet. I originally had the TimerA ISR raise a flag that would be handle in main(), but during long SD card writes I would lose several data samples.

My question is: is my current program flow acceptable? Or is having the data acquisition code within the TimerA ISR going to cause issues?

\$\endgroup\$
  • \$\begingroup\$ And your hardware is... ? \$\endgroup\$ – Eugene Sh. Sep 10 '15 at 21:14
  • \$\begingroup\$ TI TM4C1294NCPDT, ARM Cortex-M4F (ti.com/product/tm4c1294ncpdt) \$\endgroup\$ – dgreenheck Sep 10 '15 at 21:15
  • \$\begingroup\$ First justify this: "I originally had the TimerA ISR raise a flag that would be handle in main(), but during long SD card writes I would lose several data samples". This method is working for me for years for different application. If the SD writing is taking longer than the main cycle allowing, you should either increase it, or break the write to shorter stages. Or do it totally asynchronously (using DMA if possible). \$\endgroup\$ – Eugene Sh. Sep 10 '15 at 21:19
  • \$\begingroup\$ SD card writes can take up to tens of milliseconds. In that time I would lose several samples. I fail to see how changing the number of bytes written would solve the issue. I am not familiar with DMA. How would that help the issue? \$\endgroup\$ – dgreenheck Sep 10 '15 at 21:30
  • 1
    \$\begingroup\$ You will loose them in either approach, if the write is done in a blocking way. You have to do it asynchronously. Either by using DMA or just interrupt-driven (without busy waits) \$\endgroup\$ – Eugene Sh. Sep 10 '15 at 21:33
2
\$\begingroup\$

Within the TimerA ISR, data is collected from all the sensors. This takes approximately 1 millisecond

This could work fine, but why don't just start an SPI DMA Transfer in your timer? These beefy Cortex M4Fs usually have multiple DMA channels, the core is free to do other things (like finishing the SD card transfer one ms sooner) or to sleep, saving power.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Eugene mentioned the DMA transfer also. This is something I'm not familiar with so I'll have to read up on it. \$\endgroup\$ – dgreenheck Sep 10 '15 at 21:31
  • \$\begingroup\$ @dgreenheck You should do that. It is useful yet pretty complicated thing. \$\endgroup\$ – Eugene Sh. Sep 10 '15 at 21:40
  • \$\begingroup\$ @EugeneSh. It looks like it will solve my problem. You weren't kidding about the complexity though... \$\endgroup\$ – dgreenheck Sep 10 '15 at 21:44

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.