chipKIT® Development Platform

Inspired by Arduino™

Read 16 bit ADC using Chipkit Max 32 SPI

Created Fri, 21 Mar 2014 15:32:24 +0000 by randomrichard


randomrichard

Fri, 21 Mar 2014 15:32:24 +0000

Hello any data collectors out there I have just acquired a Max 32 and want to read a fast 16bit ADC (AD977) I have installed on an Arduino shield. I have had this running at a serial USB rate of 921600 baud on an Arduino Due using the SPI.transfer(10,0x00, SPI_CONTINUE) code provided for the Due. Apparently the Max32 can't use this code. Is there another way of reading 16 bit words fast, MSB first?


majenko

Fri, 21 Mar 2014 15:48:56 +0000

The DUE uses a hardware method to control the SS signal, which you can't easily do on a PIC32.

Instead, you should use the DSPI library (bundled with MPIDE) and switch it to 16-bit mode:

#include <DSPI.h>
DSPI0 spi;
const uint8_t chipSelect = 10;

void setup() {
  spi.begin();
  spi.setTransferSize(DSPI_16BIT);
  pinMode(chipSelect, OUTPUT);
  digitalWrite(chipSelect, HIGH);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(chipSelect, LOW);
  uint16_t val = spi.transfer(0x00);
  digitalWrite(chipSelect, HIGH);
  Serial.println(val);
}

randomrichard

Sat, 22 Mar 2014 08:40:58 +0000

Thanks; just what I was hoping for. It's sometimes difficult to find the right package of software amongst all the marvellous stuff Microchip, Digilent, etc. give away so freely.


Jacob Christ

Sat, 22 Mar 2014 23:48:55 +0000

As an aside, why did you switch from Due to Max32?

Jacob


randomrichard

Sun, 23 Mar 2014 08:20:12 +0000

Hi The Due is great but I need a faster processor to carry out a DSP correlation algorithm on the sonar data I am collecting. The PIC 32 has an extensive DSP library in the MPLAB X IDE, which should do the job if I can master the IDE + Harmony. In the mean time I intend to push the SPI/ADC link as fast as it will go on the Max32 using first USB/serial on the programming link to my PC and then USB/Device on the network shield. I was going to use the AD7680 on MM's EB085 but it puts out 16bits padded with 8 fore and aft bits, making 24. Digilent haven't supplied 24bit DSPI so I am using the straight 16bit AD977 instead. Perhaps you know how to collect AD7680's data with the 32bit option?


majenko

Sun, 23 Mar 2014 10:45:27 +0000

It's possible to "bend" the SPI to work in 24-bit mode, but it's not easy, and you won't do it with a friendly library.

The SPI can work in 2 main modes - normal SPI, and I2S Audio mode. In Audio mode it can do automatic frame pulse generation (hardware SS signals) and also operate in 24-bit mode. You'd need to cross-reference the data sheet and SPI reference manual to directly manipulate the registers though.

Alternatively, do a 32-bit transfer and ignore 8 of the bits? Or do an 8 bit transfer and a 16 bit transfer in sequence? (not as fast).

Of course, I'd pick a dsPIC33E for the processing, not a PIC32. Yes, the PIC32 runs faster and is better at general operations, but the dsPIC33 has a hardware DSP in it. Downside is it's harder to program as there's no nice friendly MPIDE for it.


randomrichard

Sun, 23 Mar 2014 15:55:27 +0000

Thanks for the advice. I have programmed dsPIC33EP256GP502 with Flowcode6 but haven't been able to get the necessary speed from the chip to the PC via the UART. This has been the bottleneck all along. Chip speed is useful but so far, and I have shedloads of evaluation boards, I have not found a workable USB device that I can actually program! UART -> USB serial (Due, dsPIC33) is inadequate for sonar. So I am hoping that the Chipkit Max32 with the comms shield and the mpide USB facility will do the trick. The problem is that the examples are rather esoteric for a simple, non-game playing data collector like myself. But I have ordered a PICkit3 and will tackle MPLAB/Harmony if mpide fails me... When I get a FAST datalogger going maybe you can sell it with my nice VB.NET sonar display in your shop!


randomrichard

Mon, 24 Mar 2014 20:45:20 +0000

Further answer to Jacob Christ's question: The Chipkit Max 32 is approximately 4x faster than the Arduino Due when collecting data via SPI from the AD7680 (which is supplied with a good preamp on the MM EB085); 24ksps vs. 6ksps. The Max 32 will drive the SPI at up to 1MHz, well within the AD7680's limit, and accepts a fast serial baud rate (I used 1,843,200 baud; 921600x2!) without a murmur. Further increases in Baud don't speed up the throughput and I suspect I may have to lower it a little to minimise transfer glitches. I was frankly surprised that the same USB line as used for programming with mpide will operate as a link to the PC at such a speed. So much for that "network" shield I purchased!

Converting the 24bit AD7680 data is easy. I save it to a UINT32 word using the 32bit DSPI option and then save and send a UINT16 word obtained by shifting the 32bit word 12 bits rightwards. The leftward 4 zero bits are lost.

So now I can build some kit with a decent nyquist frequency; not hifi, but good enough for government work, as they say across the pond, and all with 15 lines of code.


pito

Tue, 25 Mar 2014 19:02:54 +0000

The Chipkit Max 32 is approximately 4x faster than the Arduino Due when collecting data via SPI from the AD7680 .. The Chipkit Max 32 is approximately 4x faster than the Arduino Due when collecting data via SPI from the AD7680 (which is supplied with a good preamp on the MM EB085); 24ksps vs. 6ksps. The Max 32 will drive the SPI at up to 1MHz, well within the AD7680's limit

The Due and pic32 can do easily at least 20x the SPI speed required by the AD7689 (1MHz as you indicate). The ad7680 require at least 20 SPI clocks (while /CS=low) in order to provide the ADC conversion. So the only way how to do it is with 32bit transfer, or bit-banging.

You most probably will not be able to do a lot of DSP while receiving data from SPI without DMA. So you have to receive data from ADC in a ping-pong mode via DMA into 2 buffers, and in the halftime you may process what you need to process (while still receiving SPI data into the other buffer). That could be done with dspic33 (2x2kB dma ping-pong buffers afaik).


randomrichard

Wed, 26 Mar 2014 08:13:51 +0000

Pito: you are right - the restriction is the USB/serial link. Setting the baud to 12MHz - "full speed" - has the AD7680 operating at design speed but data is not then available to the PC, which disables the serial link above 2MHz. But an adequate 28kbps goes to the PC at 2MHz baud. I have already written FFT code on the PC to perform the correlation function. The 0.25sec delay between each 4096word line of data gives plenty of time for DSP to be carried out by the PC, line by line, and allows a x4 data compression afterwards. This means I don't have to learn about DMA, PIC hardware DSP, USB device, etc. Such learning is costly in time and money for us non-engineers...


pito

Wed, 26 Mar 2014 10:26:50 +0000

Setting the baud to 12MHz - "full speed" - has the AD7680 operating at design speed but data is not then available to the PC, which disables the serial link above 2MHz. But an adequate 28kbps goes to the PC at 2MHz baud.

Frankly I do not understand the above dependencies. "USB full speed and AD7680 SPI speed and the Serial link above 2MHz" seems to me a bit unrelated. Maybe you have to rethink the overall design of your measurement system.

Such learning is costly in time and money for us non-engineers...

It is good to spend a while with such learning - it is a good investment always ;)


majenko

Wed, 26 Mar 2014 11:09:00 +0000

I think the problem is that of mixing up of terms.

The SPI should be measured in MHz and the serial UART port in baud, but I think they may be being used backwards there.

With SPI set to 12MHz the ADC works at full speed, but the UART can't run at more than 2Mbaud reliably, which means the data captured by the ADC can't be transmitted to the PC at a high enough rate.

Using direct USB is the best way, but unless someone else has already written the code for you (i.e., using chipKIT for instance) then getting USB to work is a HUGE task. Yes, there is the MCHP USB stack, but that really doesn't help that much as getting that to work in anything but their demos is also a HUGE task. Yes, it would be nice to understand it all better, but even I haven't found the time to dedicate to that side of things, and I know lots about the PIC chips already, so a relative newcomer has less chance of doing it in a reasonable amount of time - especially if they want to get a product out of the door this side of Armageddon.

So it's either UART or USB on a system that has it pre-written, and as UART isn't fast enough I guess that means PIC32 on chipKIT.

... or that's my understanding of the conversation thus far.


randomrichard

Wed, 26 Mar 2014 14:04:18 +0000

Yes, majenko is right. I should have used "baud" to describe the set speed for the USB/serial link, not MHz. I know the AD7680 talks to the Chipkit Max32 via spi much faster when the USB/serial baud rate is set to 12,000,000, i.e. "Full speed", because I can see the data on an oscilloscope arriving at the MOSI pin at about 50ksps when the mpide "sketch" uses that figure. But it can't then get to the PC because the USB/ serial link won't work above 2,000,000 baud, presumably because the UART won't let it.

I'm glad I don't have to use "direct" USB now in my current project because, as majenko points out, it is a big job. This illustrates a continuing problem with microprocessors for amateurs. Despite years of "progress" we are still stuck with the FTDI232 variants and USB/serial. I published my results on this forum because at least the Max32 goes to the limit of that decade-old technology. If someone knows of a book, or a company, offering anything faster that is intelligible to the amateur (i.e. lacking big-company resources), I would be very grateful for the tipoff. I have uploaded MPLABX and Harmony.


majenko

Wed, 26 Mar 2014 14:12:57 +0000

The "Direct" USB is already written for you in MPIDE. If you use a board like the Fubarino SD you get the same chip as is on the MAX32 but bypass the FT232 chip. You get the full speed USB connection and all the benefits (and problems) that gives you. You can't just plug a shield in though as it's a much smaller footprint.


randomrichard

Wed, 26 Mar 2014 14:22:19 +0000

Thanks, I shall add a fubarino to my collection immediately!


pito

Wed, 26 Mar 2014 19:24:02 +0000

maj:With SPI set to 12MHz the ADC works at full speed

The max clock speed of AD7680 is 2.5MHz, so max SPI speed for the ADC is 2.5MHz clock (about 100ksamples/sec, 1sample = 16bit)

But it can't then get to the PC because the USB/ serial link won't work above 2,000,000 baud, presumably because the UART won't let it.

USB - we do not know the "baud" speed actually.. It works "volle Pulle" as our friends say.. It is limited by pic32 and PC somehow. 2Mbaud with Uart is something like 200kBytes/sec. USB full speed maxes 12MBit/sec that is 1MBytes/sec maybe..

So:

  1. your DUE or MAX32 can do 20MHz SPI clock (or more)
  2. your ADC can do max 100ksamples/sec at max 2.5MHz SPI clock
  3. your full speed USB can do 12Mbits/sec or <1.2Mbytes/sec (bulk, 64kB data packets) max.

EmbeddedMan

Wed, 26 Mar 2014 19:27:45 +0000

Maximum practical data bandwidth into or out of the PIC32 over built-in USB using current chipKIT/MPIDE CDC USB serial driver is about 500KB to 600KB per second.

See [url]http://www.pjrc.com/teensy/benchmark_usb_serial_receive.html[/url]

*Brian


pito

Wed, 26 Mar 2014 19:40:18 +0000

So we know the practical USB speed..

  1. your DUE or MAX32 can do 20MHz SPI clock (or more)
  2. your ADC (AD7680) can do max 100kSamples/sec at max 2.5MHz SPI clock - easily doable
  3. your full speed USB can do 500kBytes/sec with MAX32 - that is slow for a transfer of 100kSamples/sec (100kS/sec * 16 = 1.6Mbytes/sec)

It seems to me you can sample 100kSamples/second easily and transfer ~33kSamples/second to the PC. You may process the 100kSamples/sec data stream (inside the MAX32 - a kind of pre-processing) into a 33kSamples/sec data stream while doing averaging, decimation, oversampling, or other "dsp blahblah" in order to get maximum data out of your sonar.. :x

PS: AD7680's max clock is 2.5MHz (datasheet), it assumes 24bit transfers, but you will do 32bit transfers @ 2.5MHz max - that means you will not achieve full 100kS/sec, but less: 24/32 * 100 = 75kSamples/second. You may average the samples (ie. I like the exponential moving average as it works as a low-pass filter - see http://en.wikipedia.org/wiki/Moving_average) and you get 36.5kSamples/sec - that could be transferable via USB to your PC.

PS1: When processing "sonar" or "radar" data one needs an I/Q processing chain. Therefore I would use a "2 channels simultaneously sampling ADC" to get the I/Q channels sampled properly. The STM32F4xx (3channel ADC, 168MHz, 32bit FPU and DSP inside) or the new PIC32MZ (5channel ADC, 200MHz, DSP)are the good candidates for such toying, though :P


randomrichard

Thu, 27 Mar 2014 09:57:52 +0000

NI's notes suggest to my untutored eye that I/Q processing of chirp sonar is inappropriate because there is no carrier wave. The transducer emits a chirp for a short time period then waits for echoes. M/phi processing is certainly involved in the recovery of chirp echoes by correlation - as a string of minimum phase wavelets (hopefully!) but I don't see where the need for transformation to I/Q helps. The NI notes remind me that the whole purpose of this year-long project was to avoid the cost of Labview! Maybe I should just cave in and purchase.


pito

Thu, 27 Mar 2014 12:01:32 +0000

I/Q processing of chirp sonar is inappropriate because there is no carrier wave

I've been processing SSB signals with I/Q and there is no carrier in SSB signal .. :) Without the I/Q processing the phase information of the signal is lost. I think you can do it with chirped signals too (phase changes across the frequency sweep in the chirp).