SPI interface Take 2

This topic has taken an interesting but not useful detour down memory lane.

To the question about the speed of SPI transfers and the code that handles that:

What code in the Raspi code base handles the SPI interface and what is known about it ?

How can it be sped up to get some real-time data transfers, or at least a reasonable flow of data from an external A/D converter ?

Does the SPI interface code use the Broadcom BCM2835 DMA interface for block transfers ?

Looking at this doc:

formatting link

I do not see how to setup the DMA to transfer data to/from the SPI interface. ( this is because I am new to the BCM2835 )

This link:

formatting link

shows that the SPI interface is one byte at a line with lots of overheard. ( non-DMA )

Thanks

hamilton

Reply to
hamilton
Loading thread data ...

So I guess the rPi SPI driver can't handle devices larger than a byte?

--

Rick
Reply to
rickman

As a hardware guy, yes.

But the code in the link supplied shows a software loop feeding bytes one at a time to the hardware.

From this link:

formatting link

A note about sampling speed:

The maximum sampling frequency for the MCP3008 Chip is 200ksps at 5V and

75Ksps at 2.7V. At 3.3V, I doubt that it would go above 100Ksps. Furthermore because the spidev interface used here is a Linux userspace interface with slow access to kernel space and non-deterministic timing, expect significantly lower sample rates.

There really is no way to directly control the sampling speed. You could speed up/slow down the speed of the spi clock (in the code example set to 1MHz?Maximum is 1.35MHz @ 2.7V) and call the spiWriteRead function at regular intervals using functions such as usleep or POSIX timers but I?m not sure what kind of sample rates you?ll get without doing some experimentation.

At maximum spi clock speed and calling spiWriteRead as fast as possible I doubt you?d be able to achieve anything near 20ksps. There will also be synchronicity issues i.e. the delay between consecutive samples could exhibit a large variance due to the non-deterministic nature of the Linux Kernel. Remember?.Linux is NOT a real-time operating system!!!

If you are trying to say that the ethernet and SDcard interfaces use SPI, you are wrong.

hamilton

Reply to
hamilton

There is a standard Linux device driver.

Write your own kernel module to either poke the hardware directly or use the existing kernel interface.

Don't know.

That code shows some code in userland that poke the hardware directly and doesn't appear to use the FIFO, however it will probably have less latency starting a transaction.

The kernel driver is perfectly capable of transfering many MB over the SPI interface in a single transaction (ie. one pulse of the CEx line) at almost full clock rate - e.g. 32Mb/sec. I have used this many times in my own code - e.g. to "blit" an in-memory framebuffer to an LCD display

30 times/second.

To mt knowldege, the kernel does this using the FIFO thats part of the SPI interface and I do not know if the FIFO is filled/emptied via the DMA engine or via a "fifo-low" interrupt. (It's not that important as it's still able to drive the bus at full rate)

The issue is the time taken from your code in userland to call the kernel routine that starts the transfer going. This is somewhat high, so lots and lots of small transactions suffer from this latency, not anything to do with the hardware directly.

Gordon

Reply to
Gordon Henderson

This is all true.

In a frame-buffer where time is not a factor, this does work.

In the discussion about analog signals, timing is everything.

Setting up a timer for (say) 8khz, and triggering the SPI to sample the A/D does not seem possible.

The latency between samples will be all over the map.

Higher sample rates would be even worse.

hamilton

Reply to
hamilton

That may or may not matter, depending.

jitter on sample delivery - provided samples are actually taken like clockwork - is acceptable if they are not required to do something immediately - i..e for audio you can tolerate a fair few microseconds, even a millisecond, before delay is noticeable, assuming you can compare with the unsampled raw feed.

It is not clear whether the external ADC is sampling at a fixed frequency and stuffing a buffer, or has to be told every cycle to read...

--
Everything you read in newspapers is absolutely true, except for the  
rare story of which you happen to have first-hand knowledge. ? Erwin Knoll
Reply to
The Natural Philosopher

The Pi is SPI master only, and a lot of the common SPI ADCs use the incoming SPI clock as their sampling clock, so the first (e.g.) 4 clock ticks do stuff like select the input channel, then sample & hold the signal, then start the conversion, then the next (e.g.) 12 clocks form part of the conversion process via the successive approximation chain... so you've just done a 2-byte transaction over the SPI bus.

Sampling ADCs at fixed intervals over SPI isn't the easiest thing. Sometimes it's easier to just buy a USB sound card if it's audio you're trying to sample.

Some time back, I tried audio sampling via SPI on the Pi. My hardware was questionable, and I used the SPI timing as my timing source - ie. played back at the same speed as I recorded which I did as fast as the hardware allowed me to do (it worked out at just over 8K samples/sec)

The results were OK, but ...

formatting link

Gordon

Reply to
Gordon Henderson

Someone has to tell the ADC when to take a sample. Normally this is the read of the data from the previous conversion. Can the SPI transfer be initiated by DMA based on a timer?

I read the register spec and the SPI interface is a bit complex. It says it can perform an SPI transfer of up to 32 bits "single beat", which I assume means one register write/read. But the data registers are specified as only having 16 bits of usable data and the upper 16 bits should be written as zeros. The text talks about using up to 24 bits of the transmit FIFO data and the upper 8 as control in variable width/CS modes. They have an example of a 96 bit SPI transfer which uses a total of 3 32 bit transfers. How can this be done using 16/24 bit registers???

The register addresses are such that a DMA operation could walk through the address and perform transfers of up to 160 bits. A write to 0x7E21

50B0 followed by a write to 0x7E21 50AC would do a 64 bit transfer. This would be a decrement rather than an increment, don't know if that complicates the DMA.

As to the timing issues, the timing of the sample by the ADC can be paramount depending on your application. In some signal processing apps this is crucial and needs to be controlled as accurately as possible. This app is one of those requiring cross correlation between multiple channels of an audio signal. Any offset in the sample time will distort the results. However, this can also be mitigated by hardware by having the hardware perform the simultaneous sampling relieving the software/DMA of critical timing. Still, it would be great to have the SPI timing controlled by a timer in the CPU. Otherwise there has to be synchronization by some means between the two.

--

Rick
Reply to
rickman

It is a bit unusual for an ADC to use the SPI clock to control its internal timing, they are typically self timed. Of course there will be exceptions to everything. A conversion is typically started by some signal external to the ADC, the last read of data or there are often "auto" modes which perform conversions as fast as the ADC will run (you have to keep up reading, lol). The actual conversion typically runs as fast as the chip will convert and at the end of the conversion time the sample is available to be read.

In this case the user needs more than 2 channels. USB is virtually impossible to synchronize between different units.

If there is a little thought given to and SPI interface it can be driven by DMA and a hardware timer to give very consistent timing to the sampling as controlled by the SPI CS. Otherwise a separate pin and hardware timer can be used to initiate the conversions and SPI only used to move the data.

I couldn't tell much from that video the sound was too low. A lot can be gleaned by the ear. The human brain is a great signal processor.

--

Rick
Reply to
rickman

Using a multiprogrammed OS running on a cached (non-deterministic) processor is a bad match to time-critical jobs.

Better to use an inexpensive microcontroller to do the timing and administer a FIFO.

--
-michael - NadaNet 3.1 and AppleCrate II: http://home.comcast.net/~mjmahon
Reply to
Michael J. Mahon

Only a small part of this application is "time-critical". That is the capture of data from the ADC. I believe the hardware in the rPi is sufficient to make this work well. I wish I knew more about programming in Linux or I would tackle this myself. I'm more of an FPGA guy and in FPGAs we do multitasking by having dedicated hardware for each and every task... :)

Maybe that is what this problem needs, an FPGA in the middle to manage the capture of data. I actually looked into building such an addon card once, but I couldn't find anyone who knew how to make the FPGA talk to the rPi over a high speed interface. I also looked at the Beagle Bone but had the same problem, no one who could handle the software side of things. The Beagle Bone has an actual parallel bus on its I/O connector, but its not much good without software support. This could make for an interesting Kickstarter project.

That is not the question. The question is about why the rPi SPI driver is as slow as it is. Surely it can't be harder to read data from some ADCs than it is to do similar things with video cameras and displays. Does the camera only provide data at an 8 kHz rate?

I think the problem is that no one who had worked on the problem understands the rPi and the software well enough to do a "proper" job of it. I'm not trying to knock anyone who had contributed their time. I'm just saying they were trying to do something that met their needs and skill level. Kudos for doing that much.

--

Rick
Reply to
rickman

wwell I think everybody has learnt a lot from te discussions.

I will toss in a final thought.

the sort of 'timed sample and buffer' thing is ideal for yer arduino, etc. And you could have it on the end of USB I suspect which is well fast enough for 8k samples/second

Alternatively, I did find instructions on how to code and install bare metal (i.e. no OS at all) code on a Pi. A la Arduino.

Its not hard to knock up a multitasking scheduler to run on a chip, and some ISRs capable of handling real time hardware...but it is of course a lot harder to drive e.g. the graphics for a GUI or a pretty screen and the network.

Its the sort of thing that would have taken me a couple of years back in the day when I did it for a living, although you might be able to plagiarise existing code and do it faster.

--
Everything you read in newspapers is absolutely true, except for the  
rare story of which you happen to have first-hand knowledge. ? Erwin Knoll
Reply to
The Natural Philosopher

Have you looked at buying a USB "sound card"? It may contain everything you need: an A/D, a clock generator that makes it sample at specified times without software attention, a buffer, and a microcontroller to transfer blocks of samples to the Pi over USB.

They come at different levels of design and sophistication, starting at $3 chinese cheapies and up to high-quality equipment for HIFI music.

The camera interfaces to a dedicated subsystem in the ASIC that transfers entire blocks of data using DMA and allows the graphic processor to do operations on it.

Reply to
Rob

USB won't work. There is no way to sync multiple ADCs.

Yeah, and is there any reason why DMA can't be used with the SPI port? The timing needs to be controlled by a timer in the CPU in order to get a fixed sample rate with little jitter. Once the data is in a memory buffer, the CPU can handle the rest. I don't think we need an audio process or deal with the rest.

Ok, even if we don't consider the video stuff because of the dedicated processor, in order to display video from the network the Ethernet interface has to provide the data for the display processor to decode. That is some multiple Mbps. Clearly there are solutions to handling higher bit rates in real time on the rPi processor. So I can't see a reason why it couldn't be done with the SPI interface at lower data rates. The problem is just software that isn't remotely optimized for the task.

--

Rick
Reply to
rickman

It seems to me that the most critical requirement is that a number of ADCs receive a command to sample all at the same time. It's difficult to see how this can be done by the CPU, even if the process is triggered by an interrupt from a timer. However this step seems easy to do with an external timer. The rPi then just has to handle the incoming data, either using DMA or interrupts, depending on how fast the CPU could do this under interrupt.

--
Alan Adams, from Northamptonshire 
alan@adamshome.org.uk 
http://www.nckc.org.uk/
Reply to
Alan Adams

Not an interrupt, the DMA is performing the register accesses which strobe the ADCs. The DMA needs to be timer based.

How do you think the existing *working* peripherals operate? Maybe I should ask that as a serious question. How *do* they operate?

A UART is self timed.

The Ethernet interface isn't timed.

I doubt that USB is timed.

The video interfaces are likely timed by the graphics coprocessor.

Is the audio also produced by the graphic coprocessor?

So I guess there aren't other interfaces that are timed by the GP hardware. But surely the DMA can be controlled by a timer, no?

--

Rick
Reply to
rickman

yes

so how does it tranmit at 100Mbps?

See above

Yes

Not usually.

Depends

The easiest thing in hardware and the most necessary thing in any digital chip is an oscillator, probably Xtal

Ethernet for example would self clock off incoming and send clock from its internal oscillator. Everything is self timed or timed by what its receiving.

Its the interface where you need interrupts or polling

--
Everything you read in newspapers is absolutely true, except for the  
rare story of which you happen to have first-hand knowledge. ? Erwin Knoll
Reply to
The Natural Philosopher

I'm referring to the data transfers to/from memory.

See above

So how is the audio produced and what controls the timing of the ADC/DAC sampling?

Duh!

More Duh! Or DMA.

--

Rick
Reply to
rickman

??? then the concept of timing is irrelevant, since it will be at some sub multiple of the system bus.

The internal oscillator of the sound chip.

DMA IS polling.

Or interrupt.

Duh Duh!

Its just another processor, of very limited scope, when all is said and done.

--
Everything you read in newspapers is absolutely true, except for the  
rare story of which you happen to have first-hand knowledge. ? Erwin Knoll
Reply to
The Natural Philosopher

You aren't with the program. The context is how to do ADC transfers with precise control over the timing which in turn controls the sampling by the ADC. So we are looking at other interfaces on the CPU to see how they are timed.

Ethernet isn't timed in that way. It is governed by the arrival of data or triggered by software needing to send data.

USB has some modes which provide for operation of devices like ADC/DAC which *must* get their data transferred in a timely manner. But I don't think it has a hard time control like we are looking for.

You don't seem to understand how these things work. It's ok to say, "I don't know". Sound chips don't have internal oscillators, at least they are very infrequent. Even if they did, they would then be telling the rPi when to transfer data. How does that happen? I don't recall seeing a "sound chip" on the rPi board. Which one is it?

DMA is DMA. Polling is software on the CPU.

Ok, thank you for your input.

--

Rick
Reply to
rickman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.