Analog Devices 16 channels, 1MSPS, 12bit ADC with SPI interface

Analog Devices' AD7490 A/D converter chip is a great choice to increase ADC channels to mbed. I wrote a C++ class library, which allows multiple chips on the same SPI serial bus line.

main.cpp - usage of sequential mode (use 2 ADCs)

#include "mbed.h"
#include "AD7490.h"

DigitalOut myled(LED1);
SPI spi(p11,p12,p13);

int main() {

    // set up SPI interface. 
    // should be set before call AD7490 constructer
    spi.format(16,0);
    spi.frequency(1000000);

    // construct AD7490 instances
    AD7490 ad1(spi, p9);
    AD7490 ad2(spi, p10);

    // start ad conversion with sequential mode
    ad1.sequential();
    ad2.sequential();

    while(1) {
        short ad_data[32];      // user buffer area

        myled = 1;
        ad1.read(&ad_data[ 0]);  // save the first ADC data to buffer
        ad2.read(&ad_data[16]);  // save the second ADC data to buffer
        myled = 0;

        for(int i=0; i<32; i++)
            printf("ch[%2d]: %d\n", i, ad_data[i]);
        puts("");
        
        wait(1);
    }
}

API

AD7490
AD7490(SPI _spi, PinName _cs)Constructor. needs SPI instance and the Chip select pin
unsigned short convert(int ch=0)Single channel (one shot) conversion.
void convert(short data[]);All channels conversion with multiple 'one shot conversion'
unsigned short sequential(int ch=15);Start sequential mode, from channel 0 to 'ch'. ch=15 is default
void read(short buffer[]);Read data channel [0] to [ch], and copy them to user buffer area
Revision:
0:95be7403a10c
Child:
1:ac3b7f978aa3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD7490.cpp	Wed Aug 29 11:01:51 2012 +0000
@@ -0,0 +1,179 @@
+#include "mbed.h"
+#include "AD7490.h"
+
+AD7490::AD7490(SPI _spi, PinName _cs)
+:   spi(_spi),
+    cs(_cs)
+{
+    short x = 0;
+
+    for(int i=0; i<3; i++){
+ 
+        x = 0;    
+        x |= CREG_WRITE;
+    //    x |= CREG_SEQ;
+    //    x |= CREG_SHADOW;
+        x |= CREG_ADD3;
+        x |= CREG_ADD2;
+        x |= CREG_ADD1;
+        x |= CREG_ADD0;
+        x |= CREG_PM1;
+        x |= CREG_PM0;
+        x |= CREG_RANGE;
+        x |= CREG_CODING;
+     
+        cs = 0;
+        ret = spi.write(x<<4);
+        cs = 1;
+    
+//        printf("INIT: send = 0x%X, ret = 0x%X\n", x, ret);
+    }
+}
+
+AD7490::~AD7490()
+{
+}
+
+unsigned short
+AD7490::convert(int ch)
+{
+    unsigned short x = 0;
+
+    x |= CREG_WRITE;
+//    x |= CREG_SEQ;
+//    x |= CREG_SHADOW;
+//    x |= CREG_ADD3;
+//    x |= CREG_ADD2;
+//    x |= CREG_ADD1;
+    x |= (CREG_ADD0|CREG_ADD1|CREG_ADD2|CREG_ADD3) & (ch<<6);
+
+    x |= CREG_PM1;
+    x |= CREG_PM0;
+    x |= CREG_RANGE;
+    x |= CREG_CODING;
+
+    cs = 0;
+    ret = spi.write(x<<4);
+    cs = 1;
+
+//    printf("send = 0x%X, ch = %2d, ret = %d\n", x, (ret>>12)&0xF, ret&0xFFF);
+
+    return ret;
+}
+
+void
+AD7490::convert(short data[])
+{
+    for(int ch=0; ch<16; ch++) data[ch]=0;
+    for(int ch=0; ch<16; ch++){
+        unsigned short ret = convert(ch);
+
+        data[ ret>>12&0xF ] = ret&0xFFF;
+    }
+}
+
+
+unsigned short
+AD7490::sequential(int ch)
+{
+    unsigned short x = 0;
+
+    x |= CREG_WRITE;
+    x |= CREG_SEQ;
+    x |= CREG_SHADOW;
+//    x |= CREG_ADD3;
+//    x |= CREG_ADD2;
+//    x |= CREG_ADD1;
+    x |= (CREG_ADD0|CREG_ADD1|CREG_ADD2|CREG_ADD3) & (ch<<6);
+
+    x |= CREG_PM1;
+    x |= CREG_PM0;
+    x |= CREG_RANGE;
+    x |= CREG_CODING;
+
+    cs = 0;
+    ret = spi.write(x<<4);
+    cs = 1;
+
+    return ret;
+}
+
+
+
+unsigned short
+AD7490::read(void)
+{
+    unsigned short x = 0;
+
+//    x |= CREG_WRITE;
+//    x |= CREG_SEQ;
+//    x |= CREG_SHADOW;
+//    x |= CREG_ADD3;
+//    x |= CREG_ADD2;
+//    x |= CREG_ADD1;
+//    x |= (CREG_ADD0|CREG_ADD1|CREG_ADD2|CREG_ADD3) & (ch<<6);
+
+//    x |= CREG_PM1;
+//    x |= CREG_PM0;
+//    x |= CREG_RANGE;
+//    x |= CREG_CODING;
+
+    cs = 0;
+    ret = spi.write(x<<4);
+    cs = 1;
+
+//    printf("send = 0x%X, ch = %2d, ret = %d\n", x, (ret>>12)&0xF, ret&0xFFF);
+
+    return ret;
+}
+
+void
+AD7490::read(short data[])
+{
+    for(int ch=0; ch<16; ch++) data[ch]=0;
+    for(int ch=0; ch<16; ch++){
+        unsigned short ret = read();
+
+        data[ ret>>12&0xF ] = ret&0xFFF;
+    }
+}
+
+
+
+
+
+
+#if 0
+int main() {
+
+    wait(1);
+
+    // set up SPI interface
+    SPI spi(p11,p12,p13);
+    spi.format(16,0);
+    spi.frequency(1000000);
+
+    AD7490 ad1(spi, p9);
+    AD7490 ad2(spi, p10);
+
+    while(1) {
+
+        int ret=0;
+        for(int ch=0; ch<16; ch++){
+            ret = ad1.convert(ch);
+            printf("ch=%2d, ret= %d, %f\n", (ret>>12)&0xF, ret&0xFFF, 3.3*(float)(ret&0xFFF)/0xFFF);
+        }
+        printf("\n");
+        for(int ch=0; ch<16; ch++){
+            ret = ad2.convert(ch);
+            printf("ch=%2d, ret= %d, %f\n", (ret>>12)&0xF, ret&0xFFF, 3.3*(float)(ret&0xFFF)/0xFFF);
+        }
+        printf("\n");
+
+        myled = 1;
+        wait(0.1);
+        myled = 0;
+        wait(0.9);
+    }
+}
+#endif