AD7606 Library for mbed

Dependents:   AD7606_demo

This is my first attempt to develop a library to control an Analog Devices' AD7606BSTZ (8-channels, 16-bits, 200 kHz simultaneous sampling ADC) connected to an mbed enabled processor via an SPI port; I need to use this ADC in an applications requiring many simultaneous sampling analog input channels.

Until now the library has been tested with a FRDM-KL25Z and FRDM-K64F using this breakout board from ARMFLY, a Shenzhen-based Chinese Company, that I found on Aliexpress:

/media/uploads/frada/ad7606_breakout.jpg

It works well, at least for my needs.

Some important notes:

1) The AD7606 on the breakout board comes enabled to work in parallel mode, that is to tranfer the conversion results on a 8- or 16-bits wide data bus; to enable the SPI mode, it is mandatory to remove resistor R2 (10 kohm) and to solder it in place of R1.

2) as per the suggestions on the AD7606 data-sheet, when using the SPI connection, DB7 assumes the role of DOUTA and DB8 assumes the role of DOUTB; all remaining lines of parallel data bus should be connected to ground;

3) my library uses only DOUTA (DB7) to shift-out the conversion results of all channels; this is documented in the AD7606 data sheet:

SERIAL INTERFACE (PAR/SER/BYTE SEL = 1)

... Data can also be clocked out using just one DOUT line, in which case it is recommended that DOUTA be used to access all conversion data because the channel data is output in ascending order. For the AD7606 to access all eight conversion results on one DOUT line, a total of 128 SCLK cycles is required. ...

4) the 8 T/H (track and hold) devices in the AD7606BSTZ are divided in 2 groups of 4; each group being controlled by a CONVST line. I connected the two lines together to trigger the hold phase at the same time for all 8 T/H.

5) Until now I'm unable to find the cause of a problem with reading the correct status of the BUSY pin of the AD7606 (the while(_busy) loop in readAnalog and readRaw methods seems to hang, nonetheless the BUSY pin goes low after the conversion completion), so I am forced to wait for a fixed time (5 us) after the CONVST pulse to read the conversion result. However the conversion time is a function of the oversampling factor programmed using pins OS0, OS1, OS2 of the AD7606.

Committer:
frada
Date:
Tue Jan 20 10:58:53 2015 +0000
Revision:
1:d6f1d3498d75
Parent:
0:e50a779f4f59
Child:
2:1e367d82baff
-

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frada 1:d6f1d3498d75 1 /***************************************************************************
frada 1:d6f1d3498d75 2 * @author Francesco Adamo
frada 1:d6f1d3498d75 3 *
frada 1:d6f1d3498d75 4 * @section LICENSE
frada 1:d6f1d3498d75 5 *
frada 1:d6f1d3498d75 6 * Copyright (c) 2015 Francesco Adamo, Italy
frada 1:d6f1d3498d75 7 *
frada 1:d6f1d3498d75 8 * @section DESCRIPTION
frada 1:d6f1d3498d75 9 *
frada 1:d6f1d3498d75 10 * AD7606.CPP
frada 1:d6f1d3498d75 11 * Source file for AD7606 class library
frada 1:d6f1d3498d75 12 * The AD7606 is a 16-bits, 8-channels, SPI/Parallel-interfaced ADC from Analog Devices
frada 1:d6f1d3498d75 13 *
frada 1:d6f1d3498d75 14 *****************************************************************************/
frada 1:d6f1d3498d75 15
frada 0:e50a779f4f59 16 #include "ad7606.h"
frada 0:e50a779f4f59 17
frada 0:e50a779f4f59 18
frada 0:e50a779f4f59 19 // Constructor
frada 1:d6f1d3498d75 20 AD7606::AD7606(PinName MISO, PinName SCLK, PinName CS, PinName CONVST, PinName BUSY, PinName RESET, int frequency) : _spi(NC, MISO, SCLK), _cs(CS, 1), _convst(CONVST, 1), _busy(BUSY), _reset(RESET, 0) {
frada 0:e50a779f4f59 21 _spi.frequency(frequency);
frada 0:e50a779f4f59 22 _spi.format(8, 0);
frada 1:d6f1d3498d75 23 _reset.write(1);
frada 1:d6f1d3498d75 24 _reset.write(0);
frada 0:e50a779f4f59 25 };
frada 0:e50a779f4f59 26
frada 1:d6f1d3498d75 27 void AD7606::reset() {
frada 1:d6f1d3498d75 28 _reset.write(1);
frada 1:d6f1d3498d75 29 _reset.write(0);
frada 1:d6f1d3498d75 30 }
frada 1:d6f1d3498d75 31
frada 0:e50a779f4f59 32 void AD7606::readRawValues(uint16_t *rawData) {
frada 1:d6f1d3498d75 33 _convst.write(0); // Pulse CONVSTA/CONVSTB to start conversion
frada 1:d6f1d3498d75 34 _convst.write(1);
frada 1:d6f1d3498d75 35 wait_us(5);
frada 1:d6f1d3498d75 36 //while (_busy.read()); // wait for conversions to be completed (low level on BUSY)
frada 1:d6f1d3498d75 37 _cs.write(0); // Enable DOUTA/DOUTB lines and shift-out the conversion results
frada 1:d6f1d3498d75 38 for (char k = 0; k < 8; k++) {
frada 0:e50a779f4f59 39 *(rawData + 2*k*sizeof(uint8_t)) = _spi.write(0x00);
frada 0:e50a779f4f59 40 *(rawData + (2*k + 1)*sizeof(uint8_t)) = _spi.write(0x00);
frada 0:e50a779f4f59 41 }
frada 0:e50a779f4f59 42 _cs.write(1);
frada 0:e50a779f4f59 43 }
frada 0:e50a779f4f59 44
frada 0:e50a779f4f59 45 void AD7606::readAnalogValues(double *analogData) {
frada 1:d6f1d3498d75 46 uint8_t tmpData[2];
frada 1:d6f1d3498d75 47
frada 0:e50a779f4f59 48 _convst.write(0);
frada 0:e50a779f4f59 49 _convst.write(1);
frada 0:e50a779f4f59 50 _cs.write(0);
frada 1:d6f1d3498d75 51 _convst.write(0); // Pulse CONVSTA/CONVSTB to start conversion
frada 1:d6f1d3498d75 52 _convst.write(1);
frada 1:d6f1d3498d75 53 while (_busy.read()); // wait for conversions to be completed
frada 1:d6f1d3498d75 54 _cs.write(0); // Enable DOUTA/DOUTB lines and shift-out the conversion results
frada 1:d6f1d3498d75 55 for (char k = 0; k < 8; k++) {
frada 1:d6f1d3498d75 56 *(tmpData) = _spi.write(0x00);
frada 1:d6f1d3498d75 57 *(tmpData + 1) = _spi.write(0x00);
frada 1:d6f1d3498d75 58 *(analogData + k*sizeof(double)) = (double) ((int16_t) *tmpData)*VFSR/65535;
frada 1:d6f1d3498d75 59 }
frada 0:e50a779f4f59 60 _cs.write(1);
frada 0:e50a779f4f59 61 }