Simple readout code for MAX110/111 14-bit ADC

Dependencies:   mbed

Committer:
oliverb
Date:
Thu Jul 12 10:21:16 2012 +0000
Revision:
2:41e59824652f
Parent:
1:46c26c1de51f
Added a "flush" stage, ADC seems to calibrate far more consistently?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oliverb 1:46c26c1de51f 1 #include "mbed.h"
oliverb 1:46c26c1de51f 2 // Use SPI port to control MAX110/111 Analog to digital converter
oliverb 1:46c26c1de51f 3 // MAX110 is split-supply device, MAX111 single supply.
oliverb 1:46c26c1de51f 4 // Devices require 5v for full performance, may be testable at 3.3v
oliverb 1:46c26c1de51f 5 //
oliverb 1:46c26c1de51f 6 //
oliverb 1:46c26c1de51f 7 // Conversion is SLOW.
oliverb 1:46c26c1de51f 8 //
oliverb 1:46c26c1de51f 9 // Data is clocked in on rising edges so SPI 0,0 or SPI 1,1.
oliverb 1:46c26c1de51f 10
oliverb 1:46c26c1de51f 11 Serial pc(USBTX, USBRX); // tx, rx
oliverb 1:46c26c1de51f 12
oliverb 1:46c26c1de51f 13 SPI spi(p5, p6, p7); // mosi, miso, sclk
oliverb 1:46c26c1de51f 14 DigitalOut max_cs(p22);
oliverb 1:46c26c1de51f 15 DigitalIn max_busy(p23);
oliverb 1:46c26c1de51f 16
oliverb 1:46c26c1de51f 17 //module libmax110
oliverb 1:46c26c1de51f 18 //
oliverb 1:46c26c1de51f 19 //const
oliverb 1:46c26c1de51f 20 #define max_12bit 0x9200
oliverb 1:46c26c1de51f 21 #define max_13bit 0x8600
oliverb 1:46c26c1de51f 22 #define max_14bit 0x8c00
oliverb 1:46c26c1de51f 23 #define max_div4 0x0100
oliverb 1:46c26c1de51f 24 #define max_div2 0x0080
oliverb 1:46c26c1de51f 25 #define max_chan1 0x0000
oliverb 1:46c26c1de51f 26 #define max_chan2 0x0010
oliverb 1:46c26c1de51f 27 #define max_full 0x000c
oliverb 1:46c26c1de51f 28 //#define max_gain 0b0000000000001000
oliverb 1:46c26c1de51f 29 #define max_ofs 0x0004
oliverb 1:46c26c1de51f 30 //
oliverb 1:46c26c1de51f 31 // procedure max_init(dim mode as word, dim byref port as //byte, dim cs,bf as byte)
oliverb 1:46c26c1de51f 32 //
oliverb 1:46c26c1de51f 33 // mode must be one of max_12bit, max_13bit, max_14bit
oliverb 1:46c26c1de51f 34 // mode may be modified by "or-ing" with max_div2 or max_div4 to set clock divider
oliverb 1:46c26c1de51f 35 // mode may be modified by "or-ing" with max_chan1 or //max_chan2 to set input channel
oliverb 1:46c26c1de51f 36 // mode may be modified by "or-ing" with a calibration type //max_full,max_ofs
oliverb 1:46c26c1de51f 37 //
oliverb 1:46c26c1de51f 38 // port is the port the busy and cs pins are connected to (doesn't have to be PORTC)
oliverb 1:46c26c1de51f 39 // cs is the bit number for the chip select pin
oliverb 1:46c26c1de51f 40 // bf is the bit number for the busy flag pin
oliverb 1:46c26c1de51f 41 //
oliverb 1:46c26c1de51f 42 // function max_read(dim byref data as integer) as boolean
oliverb 1:46c26c1de51f 43 //
oliverb 1:46c26c1de51f 44 // notes returns true if a value was read, immediately restarts converter
oliverb 1:46c26c1de51f 45 // otherwise returns false
oliverb 1:46c26c1de51f 46 //
oliverb 1:46c26c1de51f 47 // result is integer, valid results are from -16384 through 16383.
oliverb 1:46c26c1de51f 48 // values beyond this are overrange
oliverb 1:46c26c1de51f 49 //
oliverb 1:46c26c1de51f 50 //
oliverb 1:46c26c1de51f 51 // MAX110/111 Control register bits
oliverb 1:46c26c1de51f 52 // 15 !NOOP Set to 1 for action, 0 for pass-through
oliverb 1:46c26c1de51f 53 // 14 NU, set to 0
oliverb 1:46c26c1de51f 54 // 13 NU, set to 0
oliverb 1:46c26c1de51f 55 // CONV 4,3,2,1
oliverb 1:46c26c1de51f 56 // 12 CONV4 1 0 0 1 20ms
oliverb 1:46c26c1de51f 57 // 11 CONV3 0 0 1 1 40ms
oliverb 1:46c26c1de51f 58 // 10 CONV2 0 1 1 0 160ms
oliverb 1:46c26c1de51f 59 // 9 CONV1 0 0 0 0 200ms SPECIAL
oliverb 1:46c26c1de51f 60 // SPECIAL = NO INTERNAL GAIN CALIBRATION, FIX IN SOFTWARE
oliverb 1:46c26c1de51f 61 // 8 DV4 1=DIVIDE XCLK BY 4
oliverb 1:46c26c1de51f 62 // 7 DV2 1=DIVIDE XCLK BY 2
oliverb 1:46c26c1de51f 63 //
oliverb 1:46c26c1de51f 64 // 6 NU, set to 0
oliverb 1:46c26c1de51f 65 // 5 NU, set to 0
oliverb 1:46c26c1de51f 66
oliverb 1:46c26c1de51f 67 // 4 CHS 0:CHANNEL 1 1:CHANNEL2
oliverb 1:46c26c1de51f 68 //
oliverb 1:46c26c1de51f 69 // CAL NUL FUNCTION
oliverb 1:46c26c1de51f 70 // 1 1 INTERNAL ZERO (PERFORM FIRST)
oliverb 1:46c26c1de51f 71 // 3 GAIN CAL 1 0 INTERNAL GAIN (NEXT)
oliverb 1:46c26c1de51f 72 // 2 OFFSET NUL 0 1 INPUT NUL (LAST)
oliverb 1:46c26c1de51f 73 // 0 0 NORMAL CONVERT
oliverb 1:46c26c1de51f 74 // 1 PDX POWER DOWN OSC
oliverb 1:46c26c1de51f 75 // 0 PD POWER DOWN ADC
oliverb 1:46c26c1de51f 76 //
oliverb 1:46c26c1de51f 77 //
oliverb 1:46c26c1de51f 78 unsigned int max_mode;
oliverb 1:46c26c1de51f 79 //
oliverb 1:46c26c1de51f 80 void max_setup(unsigned int mmode)
oliverb 1:46c26c1de51f 81 {
oliverb 1:46c26c1de51f 82 max_mode=mmode;
oliverb 1:46c26c1de51f 83 max_cs=0;
oliverb 2:41e59824652f 84 spi.write(0);
oliverb 2:41e59824652f 85 spi.write(0);
oliverb 2:41e59824652f 86 max_cs=1;
oliverb 2:41e59824652f 87 // not sure why the above step helps but it seems to improve restarts after random
oliverb 2:41e59824652f 88 // reset
oliverb 2:41e59824652f 89 max_cs=0;
oliverb 1:46c26c1de51f 90 spi.write((max_mode & 0xff00) >> 8);
oliverb 1:46c26c1de51f 91 spi.write(max_mode & 0xff);
oliverb 1:46c26c1de51f 92 max_cs=1;
oliverb 1:46c26c1de51f 93 }
oliverb 1:46c26c1de51f 94
oliverb 1:46c26c1de51f 95
oliverb 1:46c26c1de51f 96 int max_read(int *data)
oliverb 1:46c26c1de51f 97 {
oliverb 1:46c26c1de51f 98 if (max_busy)
oliverb 1:46c26c1de51f 99 {
oliverb 1:46c26c1de51f 100 if (max_mode & 0x0c)
oliverb 1:46c26c1de51f 101 {
oliverb 1:46c26c1de51f 102 max_mode = max_mode - 0x04;
oliverb 1:46c26c1de51f 103
oliverb 1:46c26c1de51f 104 max_cs=0;
oliverb 1:46c26c1de51f 105 spi.write((max_mode & 0xff00) >> 8);
oliverb 1:46c26c1de51f 106 spi.write(max_mode & 0xff);
oliverb 1:46c26c1de51f 107 max_cs=1;
oliverb 1:46c26c1de51f 108 wait(0.1);
oliverb 1:46c26c1de51f 109 return(false);
oliverb 1:46c26c1de51f 110 }
oliverb 1:46c26c1de51f 111 else
oliverb 1:46c26c1de51f 112 {
oliverb 1:46c26c1de51f 113 short t;
oliverb 1:46c26c1de51f 114 max_cs=0;
oliverb 1:46c26c1de51f 115 t =spi.write((max_mode & 0xff00) >> 8);
oliverb 1:46c26c1de51f 116 t =spi.write(max_mode & 0xff) | (t<<8);
oliverb 1:46c26c1de51f 117 *data= (int) t;
oliverb 1:46c26c1de51f 118 max_cs=1;
oliverb 1:46c26c1de51f 119 return(true);
oliverb 1:46c26c1de51f 120 }
oliverb 1:46c26c1de51f 121 }
oliverb 1:46c26c1de51f 122 else
oliverb 1:46c26c1de51f 123 {
oliverb 1:46c26c1de51f 124 return(false);
oliverb 1:46c26c1de51f 125 }
oliverb 1:46c26c1de51f 126 }
oliverb 1:46c26c1de51f 127
oliverb 1:46c26c1de51f 128
oliverb 1:46c26c1de51f 129 int main() {
oliverb 1:46c26c1de51f 130 spi.format(8,0);
oliverb 1:46c26c1de51f 131 spi.frequency(100000);
oliverb 2:41e59824652f 132 max_cs=1;
oliverb 2:41e59824652f 133 // pc.printf("Start converter\r\n");
oliverb 1:46c26c1de51f 134 max_setup(max_14bit | max_full);
oliverb 1:46c26c1de51f 135 while(1) {
oliverb 1:46c26c1de51f 136 int val;
oliverb 1:46c26c1de51f 137 val=0;
oliverb 1:46c26c1de51f 138 if (max_read(&val))
oliverb 1:46c26c1de51f 139 {
oliverb 2:41e59824652f 140 pc.printf("Readout: %d \r\n",val);
oliverb 2:41e59824652f 141 // optional: force a recalibrate
oliverb 2:41e59824652f 142 // max_setup(max_14bit | max_full);
oliverb 1:46c26c1de51f 143 }
oliverb 1:46c26c1de51f 144 }
oliverb 1:46c26c1de51f 145 }