SPI & ADCs: bit-banging vs SPI.h

Hi all,

I've noticed that there is very little code out there for SPI controlled ADCs using the SPI library SPI.h. Most implementations are just bit-banged in. One user from a previous post of mine (http://arduino.cc/forum/index.php/topic,65059.0.html) one user mentioned that the bit-banging was a much slower way to run the ADC. Does anyone know how much faster using SPI.h would be? I'm still having dramas getting the ADC (ADS8341), RTC (DS3234) and uSD card all working together, so looking at trying to run all SPI devices with the SPI library incase the ADC bit-banging code is causing the other devices grief. Any suggestions welcome!

Thanks in advance!

Take a look at the ADC code I put together here

You may need to tweak a little for the AD8341, like if it needs an address as part of the command byte or something.

I just did a bit-bang library for a number of Microchip SAR ADCs. For the MCP3201 I can get a reading in 9 microseconds. This requires two bytes and is the maximum spec speed for this ADC. I use a few nops to get a nice clock.

I did bit-bang SPI for SD cards as an option in the SdFat library, the base for Arduino SD.h. I get about the equivalent of 2.5 MHz SPI clock.

My estimate is bit-bang SPI is about 1/3 as fast as full speed hardware SPI.

I like bit-bang for ADCs in ISRs. That leaves hardware SPI free for non-interrupt use.

@fat16lib,
How do you think this would be as stereo sound capture/playback system?
Fast ADCs capture sound at 40 KHz, store to serial SRAM, or direct to SD if fast enough

Read back from SD to dual DACs

2 fast 16-bit ADCs for capture, need to read 3 bytes each
http://www.analog.com/static/imported-files/data_sheets/AD7683.pdf

Fast dual DAC for playback, need to write 3 bytes each channel
http://www.analog.com/static/imported-files/data_sheets/AD5663.pdf

I don't think 16-bit stereo audio at 44.1 ksps is possible. But I have been thinking about it for a while.

I can write a 512 byte block to SD in about 900 microseconds using a special multi-block write command. So about 1/3 of the CPU is needed for SD write at 176.4 KB/sec.

I am going to do an experiment reading out two ADC in parallel using bit-bang. I will connect a single pin to clock on both ADCs but have separate pins for data out. For ADCs that need input I would use a common data in pin.

My guess is that it will take too long.

http://www.analog.com/static/imported-files/data_sheets/AD7654.pdf

Dual 16-bit ADC, can have 2 conversions ready really fast!

Page 24:

Figure 34 shows an interface diagram between the AD7654 and the SPI equipped ADSP-219x. To accommodate the slower speed of the DSP, the AD7654 acts as a slave device and data must be read after conversion. This mode also allows the daisy-chain feature. The convert command can be initiated in response to an internal timer interrupt. The 32-bit output data is read with two serial peripheral interface (SPI) 16-bit wide accesses. The reading process can be initiated in response to the end-of-conversion signal (BUSY going low) using an interrupt line of the DSP. By writing to the SPI control register (SPICLTx), the serial interface (SPI) on the ADSP-219x is configured for master mode (MSTR) = 1, clock polarity bit (CPOL) = 0, clock phase bit (CPHA) = 1, and SPI interrupt enable (TIMOD) = 00. To meet all timing requirements, the SPI clock should be limited to 17 Mbps, which allows it to read an ADC result in less than 1 ?s.

I was talking about recording audio on the Arduino using a simple ADC. I have recorded mono at 44.1 ksps on the Arduino.

You can't use the hardware SPI bus that the SD is on for the ADCs. SD cards do not allow interruption of a 512 byte block transfer. CS must be kept low for the whole transfer.

With higher powered processors like ARM with a 4-bit SDIO bus and a fast I2S bus, recording stereo is easy. There are wonderful cheap codecs you can use with higher power processors

Playback direct from flash would not be a problem then?

Was thinking buffer the whole sample to SRAM, did some searching and realized that SRAMs are not that big yet (ex 40k/second x 16/channel x 60 seconds/min x 4 min/song = 9.6Mx16/channel/song, while SRAMs are only 512x8, so would need a huge bank of them, x 2 for stereo).

For recording, the code can be written to do this kind of thing; would this work?

repeat while recording{

SD_CS low;

for (bytes = 1 to 512){
ADC conversions via I2C or parallel;
SPI write to Flash;
}
SD_CS high;
}

Would need code to append to existing file, however that works.

The only possibility I can think of is parallel read from the ADC. On the 328 you would need to use pins 0 - 7. They are port D.

You just can't write to memory, read back, and write to an SD. The max speed of SPI, 8 MHz, is a killer.

I2C is way too slow for ADCs, 400 kHz max.

No, I was thinking read from ADC, write 4 bytes to SD. Read, write 4 bytes. Every 128 cycles (512 bytes), close the sector, start another, whatever that process is.
The 2nd ADC I found did dual 16 bit conversions with 4 bytes ready to read every 1uS.
40Kz is 25uS, x2 would be 80KHz, 12.5uS. So just 40 clock cycles at 16MHz.

What if the ADC read is the same set of clock pulses that puts it in the SD so the uC is not buffering the data all, just creating the CS and SCK?

I made a digital delay line for 12-bit audio a ways back, read a parallel 12-bit ADC, wrote it to parallel 16-bit SRAM (4 bits not used), had user selected delay time to read it back and write to 12-bit DAC. Output mixed in analog to feed into input for repeats. Had 3 delays so multiple delay times could be mixed in (remember Australian group "Men At Work"? Someone told me they used multiple echos for their sound, was going for something like that). Worked well. I still have, big board of parts all wirewrapped up.

The SD has a lot of overhead between blocks and can be busy at times. I use two 512 byte buffers to record mono.

I think a Mega would be required for more buffering.

You can't do the four byte thing.

Dang.

Ok, I'm gonna go after my electronic drums again then.
Will build 2 different circuits, one to capture 16-bit sound in mono to serial SRAM, some large sample size, write it to SD for transfer to PC for editing.
2nd to play back from SD into SRAM for playback thru DAC when triggered. Have xx number of sounds stored. Maybe an LCD screen with menu to show file name selected, button to load into SRAM when selected. Have volume controlled by peak of drum strike on a Remo practice pad with microphone inside running thru peak detector circuit. Make a bunch up, run outputs into a mixer with pan/reverb/tone/etc. -> amplifier/headphones/etc.
Or maybe something more central, PC that can talk to each channel via USB for downloading.