Does Arduino support SPI DMA input?

I am new to Arduino.

I would like to know if the following is feasible, so any pointer will be greatly appreciated!

  1. Can Arduino support two SPI ports at the same time?

  2. If so, can these two ports use DMA to transfer data? (expected data rate is 10KB/s, may be half-duplex, higher data rate the better)

  3. If so, can someone suggest a micro for the project?

Again, thanks for any pointer (idea, reading, example, comment, etc)!

As far as I know the Atmega MCUs only have one SPI interface but, obviously, it can connect to several SPI devices.

If by DMA you mean placing data into memory with CPU intervention then I believe the answer is NO. You mention 10KB/s - remember that an Uno only has 2k of SRAM.

I don't understand your use of the term "half-duplex" in the context of SPI.

What exactly are you trying to do?

...R

I read something in the Due forum a few days ago which indicated that DMA to SD had been achieved, but I don't remember the details.

Note. This doesn't contradict Robin2, as the Due is not an ATMega powered device,
But the Due is an Arduino device, albeit a quite different sort of Arduino e.g. Uses 3.3v interfaces etc

Thank you both so much for replying!

The project is like:
External data is coming in via SPI port, at 10KB/s or higher (DMA is necessary), continuously, and the Arduino device will examine every byte of data and act upon it. The second SPI port would provide communication to another Arduino device at a lower data rate (data pulling will be OK on this port)

Since my expected data transfer rate is around 10KB/s, SPI pulling would not work, I need to use DMA to move the data from SPI to internal circular memory without CPU intervention. Arduino would be checking the data at its own pace, say 100Hz, so it will examine 100B data every time it checks the memory and acts upon it, then the data would eventually be overwritten by the incoming data.

The above can be easily achieved by C, but if we can do it in Arduino, it gives the end user a LOT of flexibility

Half-duplex simply means the flow of data is one way at any time

Robin2:
If by DMA you mean placing data into memory with CPU intervention then ...

without

Saxe:
External data is coming in via SPI port, at 10KB/s or higher (DMA is necessary), continuously, and the Arduino device will examine every byte of data and act upon it. The second SPI port would provide communication to another Arduino device at a lower data rate (data pulling will be OK on this port)

Sorry but this does not make sense to me.
First, 10k/second is a moderate speed for a 16MHz Arduino. I think Arduino SPI can do about 400k per second.
If the Arduino must examine every byte then the CPU has to be involved - so why the insistence on DMA?
If the role of the second SPI port is to pass on the data to another Arduino it CANNOT work at a slower speed or the incoming high-speed data will overflow the Arduino SRAM.

Tell us exactly what you want to achieve - not how you think you should implement a solution.
Tell us how much data must transfer per minute (or per hour) to get away from instantaneous rates.
Tell us what is sending the 10k/s data to the Arduino.
Tell us what the data represents.
Tell us why there is a second Arduino.

...R

I understand the hardware have no problem dealing with the data bandwidth.

As I said, I am new to Arduino, so my view could be totally wrong: I thought Arduino only provides simple immediate SPI R/W, that's why I was asking DMA operation.

OK, here is what I like to achieve:

  1. Two SPI ports, one for data (receive only), one for command and status report
  2. The data port will receive data at 10KB/s continuously, if we can do higher, it would be even better
  3. The data will be examined to check against trigger condition.
  4. Toggle I/O based when trigger condition is met

There is only one hardware SPI port on ATmega-based Arduinos, but you can add another using software SPI.

10 kilobytes/second is about what you expect from the standard SPI clock rate of 100 kHz, but as Robin pointed out, a clock rate of 400 kHz is possible. If you are not storing the data, but only looking for a particular pattern in the data, there should be no difficulty implementing this project.

jremington:
There is only one hardware SPI port on ATmega-based Arduinos, but you can add another using software SPI.

10 kilobytes/second is about what you expect from the standard SPI clock rate of 100 kHz, but as Robin pointed out, a clock rate of 400 kHz is possible. If you are not storing the data, but only looking for a particular pattern in the data, there should be no difficulty implementing this project.

Correct me if I'm wrong, but I believe it's I2C that's 100/400kHz. The default SPI speed is 4MHz and can be bumped up to 8MHz if desired.

Saxe:
OK, here is what I like to achieve:

  1. Two SPI ports, one for data (receive only), one for command and status report
  2. The data port will receive data at 10KB/s continuously, if we can do higher, it would be even better
  3. The data will be examined to check against trigger condition.
  4. Toggle I/O based when trigger condition is met

This is still mainly a description of HOW you want to achieve things.

Tell us what device is sending data?
what the data is about?
how often it is sent?
how much of it is sent (as I asked earlier)?
what trigger condition do you want to test for?
how often does the trigger conditon arise?
what is to happen when the trigger condition is detected - just change a single I/O pin from 1 to 0 and back?
Why can't one SPI port cover both tasks - especially if the command and status stuff is infrequent?

Your question is a bit like asking how to fix the ignition in your car without saying what sort of car you have, or even if it is diesel or petrol.

...R

Correct me if I'm wrong, but I believe it's I2C that's 100/400kHz. The default SPI speed is 4MHz and can be bumped up to 8MHz if desired.

You are right, too many three letter acronyms!

Tell us what device is sending data?
--> Not sure why this is important if I give answer the next few questions, but anyway, just say it is a TI's Micro TM4C1294 since it would be used in the project any way.

what the data is about?
---> ADC readings

how often it is sent?
---> Continuously, at least 10KB/sec, if Arduino can handle higher bandwidth, I will take it happily

how much of it is sent (as I asked earlier)?
---> Until I tells it to stop

what trigger condition do you want to test for?
---> User defined, that's one reason I use Arduino, but let's say I checks the RMS of the ADC readings and check for RMS(ADCreading)>1V

how often does the trigger conditon arise?
---> Totally depends on the test environment, but again, I can assume it is less than 10 times/second

what is to happen when the trigger condition is detected - just change a single I/O pin from 1 to 0 and back?
---> At this stage, change a single I/O pin from 1 to 0 and back is good enough to get me started

Why can't one SPI port cover both tasks - especially if the command and status stuff is infrequent?
---> The data source is from one device, but the command center is from another device (also let's assume it is TM4C1294)

There is only one hardware SPI port on ATmega-based Arduinos, but you can add another using software SPI.

Err

Section 20 of the datsheet for the 328P (Arduino uno) shows you hoe to use the UART in SPI mode. So the AVR's can have more than more than one SPI.

Section 19.9 "Multi-processor Communication Mode" shows the UART being used in a way which is very similar to I2C/TWI.

Mark

Saxe:
The data source is from one device, but the command center is from another device (also let's assume it is TM4C1294)

A single SPI port can communicate separately with several devices by controlling the Slave Select pin.

For some reason we are having great difficulty finding a common currency for conversation (if I'm not mixing too many metaphors).

All this data will be coming into the Arduino in a continuous stream of 10k bytes per second. And it seems lke the Arduino has to calculate the RMS values within that data stream and react if the RMS value is (briefly?) above 1 volt.

I have no difficulty with the Arduino having this task - it is probably well able to do it. But I just can't relate the requirement to any need for DMA.

Let's put DMA to one side for a moment and concentrate on the RMS calculations.

It seems to me that one might do the calculation in chunks (take in, say 100 or 500 bytes and do some calculation on them) or continuously (as each byte is received the oldest one is dropped and the new one taken into the calculation). Either way should be possible.

Presumably after the RMS value is calculated the data is just thrown away.

In between calculating RMS values the Arduino should have no trouble switching the attention of the SPI port to a different task.

The only part of this that I have an uncertainty about is the RMS calculation. If it involves floating point maths it might be the bottleneck as far as performance is concerned.

Have you written any code and done some performance tests?

...R

I am C programmer and never wrote anything for Arduino.

The reason I need a second SPI port is the data channel and command channel are not in sync at all

I asked about DMA, for I thought Arduino would not be fast enough to retrieve the data, maybe the following scenario would explain my worries

The data channel sends data at a rate of 10KB, if Arduino doesn't use DMA, it has to retrieve the data every 0.1ms (assuming single Rx buffer), can Arduino do that while calculating RMS ? How about increasing the data rate to 100KB? can Arduino still do it?

If your answer is YES, then my DMA question is resolved

Saxe:
can Arduino do that while calculating RMS ? How about increasing the data rate to 100KB? can Arduino still do it?

Depends on the algorithm used to calculate RMS. Can you paste it in to this thread here?

Saxe:
can Arduino do that while calculating RMS ? How about increasing the data rate to 100KB? can Arduino still do it?

If your answer is YES, then my DMA question is resolved

I would say 10kb/s yes, 100kB/s maybe.

As @tylernt says, we need to know the exact calculation you want to do before being able to give a definitive answer. Since you know C you could write a typical function to do what you want and post it here.

But the real difficulty (for me) is the way you are thinking about the problem. The gathering of data and the processing of data are not two activities running in parallel like a pair of decorators painting two different rooms in a house. They have to be interleaved at some level of granularity - maybe it is one byte at a time or maybe it is 100 bytes at a time. I asked you about this in an earlier post but you didn't respond.

Also, it doesn't make sense (to me) to ask if it can do it at 10k and also at 100k. There must be some limit on the supply of data - perhaps upper and lower limits. Again, you have refused several requests to explain what the data represents and what it is coming from.

All these matters affect the ability to achieve your project. If, for whatever reason, you want to keep that information secret from us I suggest you get an Arduino and write a few programs to do some practical tests. The Arduino is a great device for learning-by-doing.

The reason I need a second SPI port is the data channel and command channel are not in sync at all

What exactly do you mean by this and why do you think it matters? I am increasingly unsure if you understand SPI at all.

I wonder if you are applying a big-computer mindset to a microprocessor?

...R

sigh I agree that we are having difficulty to convey our thoughts.....

I am not a newbie in hardware design, even though I have never touched Arduino, but I have designed quite a few products, all data acquisition applications

For example, for the two SPIs, this arduino will be the slave for the two SPI channels, each has its own independent clock and timing, so I don't want to combine them.

For the RMS, it was just an assumption, I was going to allow the user to define its own algorithm, so there is not much meaning to discuss how I am going to implement RMS. I say RMS simply because it may represent an average work load for the Arduino device.

"you have refused several requests to explain what the data represents and what it is coming from. " --- I thought I gave my best shoot, by saying it was ADC readings from TM4C1294, I really don't know what else you want.

"it doesn't make sense (to me) to ask if it can do it at 10k and also at 100k" --- all I tried to say was that I need to handle at least 10KB/s, but I will be thrilled if Arduino can handle higher.

Anyway, I really appreciate your time and effort trying to help, and I really mean it.

Saxe:
For example, for the two SPIs, this arduino will be the slave for the two SPI channels, each has its own independent clock and timing, so I don't want to combine them.

Aha, now we're getting somewhere. I think a lot of us were probably assuming the Arduino would be the SPI master.

At what data rate will the other SPI masters clock data? Unless it's in the MHz range, I don't see why you can't attach interrupts to the two clock pins and read/toggle the appropriate MISO and MOSI pins in your ISR(s). Then your main loop can just keep the data buffers from over or underflowing and run the calculations any ol' time it wants to.

Saxe:
For example, for the two SPIs, this arduino will be the slave for the two SPI channels, each has its own independent clock and timing, so I don't want to combine them.

I'm the one that should be sighing. Why has it taken until Reply #17 to get this important piece of information.
For what you say you want to do it would make far more sense if the Arduno is the master.

For the RMS, it was just an assumption, I was going to allow the user to define its own algorithm, so there is not much meaning to discuss how I am going to implement RMS.

And on that basis there is not much meaning to any guess I might make about what is or is not possible.

I say RMS simply because it may represent an average work load for the Arduino device.

Even this does not make any sense unless you have a specific algorithm in mind

I thought I gave my best shoot, by saying it was ADC readings from TM4C1294, I really don't know what else you want

It would help to know if the data represents Audio samples or measurements of vibration in some machine - or whatever.
As far as I can see the TM4C1294 is itself a microprocessor. Why bother with an Arduino at all ?

"it doesn't make sense (to me) to ask if it can do it at 10k and also at 100k" --- all I tried to say was that I need to handle at least 10KB/s, but I will be thrilled if Arduino can handle higher.

Why? This is probably closely connected with the question of what the data represents.

...R