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 16:19:17 2015 +0000
Revision:
4:9341319c0d8e
Parent:
3:ca87f4989281
-

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 3:ca87f4989281 12 * The AD7606BSTZ 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 2:1e367d82baff 20 AD7606::AD7606(PinName MISO, PinName SCLK, PinName CS, PinName CONVST, PinName BUSY, PinName RESET, int frequency) : _spi(NC, MISO, SCLK), _cs(CS), _convst(CONVST), _busy(BUSY), _reset(RESET) {
frada 0:e50a779f4f59 21 _spi.frequency(frequency);
frada 0:e50a779f4f59 22 _spi.format(8, 0);
frada 2:1e367d82baff 23 _cs = 1;
frada 2:1e367d82baff 24 _convst = 1;
frada 2:1e367d82baff 25 _reset = 0;
frada 2:1e367d82baff 26 _q = 0.0;
frada 2:1e367d82baff 27 reset();
frada 0:e50a779f4f59 28 };
frada 0:e50a779f4f59 29
frada 4:9341319c0d8e 30 // Resets the AD7606
frada 1:d6f1d3498d75 31 void AD7606::reset() {
frada 2:1e367d82baff 32 _reset = 1;
frada 2:1e367d82baff 33 _reset = 0;
frada 2:1e367d82baff 34 }
frada 4:9341319c0d8e 35
frada 4:9341319c0d8e 36 // Computes and stores the quantization step of the AD7606 as a function of its dynamic range (10 V or 20 V)
frada 2:1e367d82baff 37 void AD7606::setDR(double DR) {
frada 2:1e367d82baff 38 _q = (double) DR/65535.0; // Quantization step
frada 1:d6f1d3498d75 39 }
frada 1:d6f1d3498d75 40
frada 4:9341319c0d8e 41 // Read raw values from all 8 channels
frada 4:9341319c0d8e 42 // rawDataBuffer is a pointer to an array of 8 16-bit integers
frada 2:1e367d82baff 43 void AD7606::readRAW(int16_t *rawDataBuffer) {
frada 2:1e367d82baff 44 uint8_t lowByte, highByte;
frada 2:1e367d82baff 45
frada 2:1e367d82baff 46 _convst = 0; // Pulse CONVSTA/CONVSTB to start conversion
frada 2:1e367d82baff 47 _convst = 1;
frada 1:d6f1d3498d75 48 wait_us(5);
frada 2:1e367d82baff 49 //while (_busy) {
frada 2:1e367d82baff 50 // wait for conversions to be completed (low level on BUSY)
frada 2:1e367d82baff 51 //}
frada 2:1e367d82baff 52 _cs = 0; // Enable DOUTA/DOUTB lines and shift-out the conversion results
frada 1:d6f1d3498d75 53 for (char k = 0; k < 8; k++) {
frada 2:1e367d82baff 54 highByte = _spi.write(0x00);
frada 2:1e367d82baff 55 lowByte = _spi.write(0x00);
frada 2:1e367d82baff 56 *(rawDataBuffer + k) = (int16_t) ((highByte << 8) + lowByte);
frada 0:e50a779f4f59 57 }
frada 2:1e367d82baff 58 _cs = 1;
frada 0:e50a779f4f59 59 }
frada 0:e50a779f4f59 60
frada 4:9341319c0d8e 61 // Read analog values from all 8 channels
frada 4:9341319c0d8e 62 // analogDataBuffer is a pointer to an array of 8 doubles
frada 2:1e367d82baff 63 void AD7606::readAnalog(double *analogDataBuffer) {
frada 2:1e367d82baff 64 uint8_t lowByte, highByte;
frada 1:d6f1d3498d75 65
frada 2:1e367d82baff 66 _convst = 0; // Pulse CONVSTA/CONVSTB to start conversion
frada 2:1e367d82baff 67 wait_us(1);
frada 2:1e367d82baff 68 _convst = 1;
frada 2:1e367d82baff 69 wait_us(5);
frada 2:1e367d82baff 70 //while (_busy) {
frada 2:1e367d82baff 71 // wait for conversions to be completed (low level on BUSY)
frada 2:1e367d82baff 72 //}
frada 2:1e367d82baff 73 _cs = 0; // Enable DOUTA/DOUTB lines and shift-out the conversion results
frada 1:d6f1d3498d75 74 for (char k = 0; k < 8; k++) {
frada 2:1e367d82baff 75 highByte = _spi.write(0x00);
frada 2:1e367d82baff 76 lowByte = _spi.write(0x00);
frada 2:1e367d82baff 77 *(analogDataBuffer + k) = (double) ((int16_t) ((highByte << 8) + lowByte))*_q;
frada 1:d6f1d3498d75 78 }
frada 2:1e367d82baff 79 _cs = 1;
frada 0:e50a779f4f59 80 }