main file
/*
* Project ADCTEST
* Description: Simple example for ratiometric reading of a 4-wire PT100 sensor connected to AIN0, AIN1, AIN2 (according to TI app note SBAA180B)
* Author: Jensa
* Date: 23 Nov 2017
*/
#include "ADS124S08.h"
float ohmTable[501] = {100,100.39,100.78,101.17,101.56,101.95,102.34,102.73,103.12,103.51,103.9,104.29,104.68,105.07,105.46,105.85,106.24,106.63,107.02,107.4,107.79,108.18,108.57,108.96,109.35,109.73,110.12,110.51,110.9,111.28,111.67,112.06,112.45,112.83,113.22,113.61,113.99,114.38,114.77,115.15,115.54,115.93,116.31,116.7,117.08,117.47,117.85,118.24,118.62,119.01,119.4,119.78,120.16,120.55,120.93,121.32,121.7,122.09,122.47,122.86,123.24,123.62,124.01,124.39,124.77,125.17,125.55,125.93,126.32,126.7,127.08,127.46,127.85,128.23,128.61,128.99,129.38,129.76,130.14,130.52,130.9,131.28,131.67,132.05,132.43,132.81,133.19,133.57,133.95,134.33,134.71,135.09,135.47,135.85,136.23,136.61,136.99,137.37,137.75,138.13,138.51,138.89,139.27,139.65,140.03,140.39,140.77,141.15,141.53,141.91,142.29,142.66,143.04,143.42,143.8,144.18,144.56,144.94,145.32,145.69,146.07,146.45,146.82,147.2,147.58,147.95,148.33,148.71,149.08,149.46,149.83,150.21,150.58,150.96,151.34,151.71,152.09,152.46,152.84,153.21,153.58,153.95,154.32,154.71,155.08,155.46,155.83,156.21,156.58,156.96,157.33,157.71,158.08,158.45,158.83,159.2,159.56,159.94,160.31,160.68,161.05,161.43,161.8,162.17,162.54,162.91,163.28,163.66,164.03,164.4,164.77,165.14,165.51,165.88,166.25,166.62,167,167.37,167.74,168.11,168.48,168.85,169.22,169.59,169.96,170.33,170.69,171.06,171.43,171.8,172.17,172.54,172.91,173.27,173.64,174.01,174.39,174.75,175.12,175.49,175.86,176.23,176.59,176.96,177.33,177.7,178.06,178.43,178.8,179.16,179.53,179.9,180.26,180.63,180.99,181.36,181.73,182.09,182.46,182.82,183.19,183.55,183.92,184.28,184.65,185.01,185.38,185.74,186.11,186.47,186.84,187.2,187.56,187.93,188.29,188.65,189.02,189.38,189.74,190.11,190.47,190.83,191.2,191.56,191.92,192.28,192.66,193.02,193.38,193.74,194.1,194.47,194.83,195.19,195.55,195.9,196.26,196.62,196.98,197.35,197.71,198.07,198.43,198.79,199.15,199.51,199.87,200.23,200.59,200.95,201.31,201.67,202.03,202.38,202.74,203.1,203.46,203.82,204.18,204.54,204.9,205.25,205.61,205.97,206.33,206.7,207.05,207.41,207.77,208.13,208.48,208.84,209.2,209.55,209.91,210.27,210.62,210.98,211.34,211.69,212.05,212.4,212.76,213.12,213.47,213.83,214.19,214.55,214.9,215.26,215.61,215.97,216.32,216.68,217.03,217.39,217.73,218.08,218.44,218.79,219.15,219.5,219.85,220.21,220.56,220.91,221.27,221.62,221.97,222.32,222.68,223.03,223.38,223.73,224.09,224.45,224.8,225.15,225.5,225.85,226.21,226.56,226.91,227.26,227.61,227.96,228.31,228.66,229.01,229.36,229.72,230.07,230.42,230.77,231.12,231.47,231.81,232.16,232.51,232.86,233.21,233.56,233.91,234.26,234.6,234.95,235.3,235.65,236,236.35,236.7,237.05,237.4,237.75,238.09,238.44,238.79,239.14,239.48,239.83,240.18,240.52,240.87,241.22,241.56,241.91,242.25,242.6,242.95,243.29,243.64,243.98,244.33,244.67,245.02,245.36,245.71,246.05,246.4,246.74,247.09,247.43,247.78,248.12,248.46,248.81,249.15,249.5,249.84,250.18,250.53,250.89,251.21,251.55,251.9,252.24,252.59,252.94,253.28,253.62,253.96,254.3,254.65,254.99,255.33,255.67,256.01,256.35,256.7,257.04,257.38,257.72,258.06,258.4,258.74,259.08,259.42,259.76,260.1,260.44,260.78,261.12,261.46,261.8,262.14,262.48,262.83,263.17,263.5,263.84,264.18,264.52,264.86,265.2,265.54,265.87,266.21,266.55,266.89,267.22,267.56,267.9,268.24,268.57,268.91,269.25,269.58,269.92,270.26,270.59,270.93,271.27,271.6,271.94,272.27,272.61,272.95,273.28,273.62,273.95,274.29,274.62,274.96,275.29,275.63,275.96,276.31,276.64,276.97,277.31,277.64,277.98,278.31,278.64,278.98,279.31,279.64,279.98,280.31,280.64,280.98};
ADS124S08 adc;
uint8_t statusOld = -1;
long lastSample;
int counter;
int sampleNumber = 1;
int lastButtonStatus = 0;
int useIDAC = 0;
// setup() runs once, when the device is first turned on.
void setup() {
Serial.begin(115200);
delay(100);
adc.begin();
delay(100);
adc.sendCommand(RESET_OPCODE_MASK);
delay(100);
/* print out the chip name */
if( adc.regRead(ID_ADDR_MASK) == 0x01 )
{
Serial.println("You have an ADS124S06\n");
}
else
{
Serial.println("You have an ADS124S08\n");
}
delay(10);
configureAdc();
}
void loop() {
Serial.println("...............................");
long now = millis();
uint8_t status;
// Check if it's X seconds since last conversion
if( now - lastSample > 25 ){
//Serial.print(sampleNumber);
//Serial.print(" ");
lastSample = now;
status = readData();
uint8_t rdy = bitRead(status, 6);
uint8_t por = bitRead(status, 7);
if( statusOld != status )
{
statusOld = status;
Serial.print("status: ");
Serial.print( status,BIN );
Serial.print(" POR: ");
Serial.print( bitRead(status, 7) );
Serial.print(" RDY: ");
Serial.println( rdy );
// the chip restarted (for some reason) so clear the POR flag, but only when ready
if( por == 1 && rdy == 0){
// clear the POR flag and reconfigure
bitWrite(status, 7, 0);
adc.regWrite(STATUS_ADDR_MASK, status);
configureAdc();
// print debug info so we can see if this worked
status = adc.regRead( STATUS_ADDR_MASK );
Serial.print( "POR cleared? " );
Serial.println(status,BIN);
}
}
sampleNumber++;
}
delay(100);
}
void configureAdc()
{
// Make sure the device is awake
adc.sendCommand( WAKE_OPCODE_MASK );
// use channel 1 as positive and channel 2 as negative input
adc.regWrite( INPMUX_ADDR_MASK, ADS_P_AIN1 + ADS_N_AIN2 );
// set PGA to 8x
adc.regWrite( PGA_ADDR_MASK, ADS_PGA_ENABLED + ADS_GAIN_4 );
// The IDAC will only work if we enable the internal reference (ref Datasheet 9.3.7)
adc.regWrite( REF_ADDR_MASK, ADS_REFINT_ON_ALWAYS + ADS_REFSEL_P0 );
// use channel 3 as IDAC 1 (excitation current source)
adc.regWrite( IDACMUX_ADDR_MASK, ADS_IDAC1_A0 + ADS_IDAC2_OFF );
// set IDAC 1 to output 500uA
adc.regWrite( IDACMAG_ADDR_MASK, ADS_IDACMAG_1000 );
// Turn on status for debugging
adc.regWrite( SYS_ADDR_MASK, ADS_SENDSTATUS_ENABLE );
adc.reStart();
delay(10);
regMap2();
}
uint8_t readData()
{
uint8_t dStatus = 0;
uint8_t dData;
uint8_t dCRC = 0;
int data = 0;
/* Read out the results */
data = adc.dataRead(&dStatus, &dData, &dCRC);
/*
* Need to determine if Status and/or CRC is enabled to transmit as desired
*/
if((adc.registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS)
{
if((adc.registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
{
// Serial.printlnf("Conversion Data 0x%06x with Status 0x%02x and CRC 0x%02x.", data, dStatus, dCRC);
}
else
{
//sSerial.printlnf("Conversion Data 0x%06x with Status 0x%02x. DEC %02d", data, dStatus,data);
}
}
else if((adc.registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
{
// Serial.printlnf("Conversion Data 0x%06x with CRC 0x%02x.", data, dCRC);
}
else
{
// Serial.printlnf("Conversion Data 0x%06x.", data);
}
float ADC_fullscale = 67108864;// (ADC_fullscale = 2^23 * PGA_Value)
float resistance = ((float)data*3300)/ADC_fullscale;
Serial.print("data: ");
Serial.println((float)data);Serial.print("resistance: ");
Serial.println(resistance);
resistance=(resistance/100)-1;
float temp= (resistance * (255.8723 + resistance * (9.6 + resistance * 0.878)));
/* Set ADC back to the previous configuration */
//adc.sendCommand(STOP_OPCODE_MASK);
//adc.sendCommand(SLEEP_OPCODE_MASK);
return dStatus;
}
void regMap(void)
{
unsigned int index;
char cTemp;
Serial.println("Register Contents");
Serial.println("---------------------");
for(index=0; index < 18 ; index++)
{
cTemp = adc.regRead(index);
//Serial.printlnf("Register 0x%02x = 0x%02x", index, cTemp);
}
}
void regMap2(void)
{
unsigned int index;
uint8_t cTemp[18];
adc.readRegs(0,18,cTemp);
Serial.println("Register Contents");
Serial.println("---------------------");
for(index=0; index < 18 ; index++)
{
//Serial.printlnf("Register 0x%02x = 0x%02x", index, cTemp[index] );
}
}
float getCelcius( float ohmMeasured )
{
float below, above, interpol;
int i;
for( i=0; i<501; i++ )
{
if( ohmMeasured < ohmTable[i] )
{
above = ohmTable[i];
below = ohmTable[i-1];
break;
}
}
float range = above-below;
float remain = ohmMeasured-below;
float percent = (remain / range);
interpol = i - 1 + percent;
return interpol;
}
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
.cpp file
/* --COPYRIGHT--,BSD
* Copyright (c) 2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --/COPYRIGHT--*/
/*
* This class is based on the ADS124S08.c provided by TI and adapted for use with
* Particle Photon and other Arduino-like MCU's.
*
* Note that the confusingly named "selectDeviceCSLow"
* actually selects the device and that "releaseChipSelect" deselects it. Not obvious
* from the naming, but according to the datasheet CS is active LOW.
*/
#include "ADS124S08.h"
/*
* Writes the nCS pin low and waits a while for the device to finish working before
* handing control back to the caller for a SPI transfer.
*/
void ADS124S08::selectDeviceCSLow(void){
digitalWrite( CS_PIN, LOW );
}
/*
* Pulls the nCS pin high. Performs no waiting.
*/
void ADS124S08::releaseChipSelect(void){
digitalWrite( CS_PIN, HIGH );
}
/*
* Initializes device for use in the ADS124S08 EVM.
*
* \return True if device is in correct hardware defaults and is connected
*
*/
ADS124S08::ADS124S08(void)
{
pinMode( CS_PIN, OUTPUT );
pinMode( START_PIN, OUTPUT );
pinMode( RESET_PIN, OUTPUT );
pinMode( CKEN_PIN, OUTPUT );
pinMode( DRDY_PIN, INPUT );
digitalWrite( START_PIN, LOW );
digitalWrite( RESET_PIN, HIGH );
digitalWrite( CKEN_PIN, LOW );
/* Default register settings */
registers[ID_ADDR_MASK] = 0x08;
registers[STATUS_ADDR_MASK] = 0x80;
registers[INPMUX_ADDR_MASK] = 0x01;
registers[PGA_ADDR_MASK] = 0x00;
registers[DATARATE_ADDR_MASK] = 0x14;
registers[REF_ADDR_MASK] = 0x10;
registers[IDACMAG_ADDR_MASK] = 0x00;
registers[IDACMUX_ADDR_MASK] = 0xFF;
registers[VBIAS_ADDR_MASK] = 0x00;
registers[SYS_ADDR_MASK] = 0x10;
registers[OFCAL0_ADDR_MASK] = 0x00;
registers[OFCAL1_ADDR_MASK] = 0x00;
registers[OFCAL2_ADDR_MASK] = 0x00;
registers[FSCAL0_ADDR_MASK] = 0x00;
registers[FSCAL1_ADDR_MASK] = 0x00;
registers[FSCAL2_ADDR_MASK] = 0x40;
registers[GPIODAT_ADDR_MASK] = 0x00;
registers[GPIOCON_ADDR_MASK] = 0x00;
fStart = false;
releaseChipSelect();
deassertStart();
}
void ADS124S08::begin()
{
SPI.begin();
// SPI.setBitOrder(MSBFIRST);
// SPI.setDataMode( SPI_MODE1 );
// SPI.setClockSpeed( 1000000 );
#if defined (SPI_HAS_TRANSACTION)
mySPISettings = SPISettings(1000000, MSBFIRST, SPI_MODE1);
#endif
}
/*
* Reads a single register contents from the specified address
*
* \param regnum identifies which address to read
*
*/
char ADS124S08::regRead(unsigned int regnum)
{
int i;
uint8_t ulDataTx[3];
uint8_t ulDataRx[3];
ulDataTx[0] = REGRD_OPCODE_MASK + (regnum & 0x1f);
ulDataTx[1] = 0x00;
ulDataTx[2] = 0x00;
selectDeviceCSLow();
#if defined (SPI_HAS_TRANSACTION)
SPI.beginTransaction(mySPISettings);
#endif
for(i = 0; i < 3; i++)
ulDataRx[i] = SPI.transfer(ulDataTx[i]);
if(regnum < NUM_REGISTERS)
registers[regnum] = ulDataRx[2];
#if defined (SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
releaseChipSelect();
//Serial.printlnf("regRead tx: %02x %02x %02x",ulDataTx[0],ulDataTx[1],ulDataTx[2]);
//Serial.printlnf("regRead rx: %02x %02x %02x",ulDataRx[0],ulDataRx[1],ulDataRx[2]);
return ulDataRx[2];
}
/*
* Reads a group of registers starting at the specified address
*
* \param regnum is addr_mask 8-bit mask of the register from which we start reading
* \param count The number of registers we wish to read
* \param *location pointer to the location in memory to write the data
*
*/
void ADS124S08::readRegs(unsigned int regnum, unsigned int count, uint8_t *data)
{
int i;
uint8_t ulDataTx[2];
ulDataTx[0] = REGRD_OPCODE_MASK + (regnum & 0x1f);
ulDataTx[1] = count-1;
selectDeviceCSLow();
SPI.transfer(ulDataTx[0]);
SPI.transfer(ulDataTx[1]);
for(i = 0; i < count; i++)
{
data[i] = SPI.transfer(0);
if(regnum+i < NUM_REGISTERS)
registers[regnum+i] = data[i];
}
releaseChipSelect();
}
/*
* Writes a single of register with the specified data
*
* \param regnum addr_mask 8-bit mask of the register to which we start writing
* \param data to be written
*
*/
void ADS124S08::regWrite(unsigned int regnum, unsigned char data)
{
uint8_t ulDataTx[3];
ulDataTx[0] = REGWR_OPCODE_MASK + (regnum & 0x1f);
ulDataTx[1] = 0x00;
ulDataTx[2] = data;
selectDeviceCSLow();
SPI.transfer(ulDataTx[0]);
SPI.transfer(ulDataTx[1]);
SPI.transfer(ulDataTx[2]);
releaseChipSelect();
//Serial.printlnf("regWrite tx: %02x %02x %02x",ulDataTx[0],ulDataTx[1],ulDataTx[2]);
return;
}
/*
* Writes a group of registers starting at the specified address
*
* \param regnum is addr_mask 8-bit mask of the register from which we start writing
* \param count The number of registers we wish to write
* \param *location pointer to the location in memory to read the data
*
*/
void ADS124S08::writeRegs(unsigned int regnum, unsigned int howmuch, unsigned char *data)
{
unsigned int i;
uint8_t ulDataTx[2];
ulDataTx[0] = REGWR_OPCODE_MASK + (regnum & 0x1f);
ulDataTx[1] = howmuch-1;
selectDeviceCSLow();
SPI.transfer(ulDataTx[0]);
SPI.transfer(ulDataTx[1]);
for(i=0; i < howmuch; i++)
{
SPI.transfer( data[i] );
if(regnum+i < NUM_REGISTERS)
registers[regnum+i] = data[i];
}
releaseChipSelect();
return;
}
/*
* Sends a command to the ADS124S08
*
* \param op_code is the command being issued
*
*/
void ADS124S08::sendCommand(uint8_t op_code)
{
selectDeviceCSLow();
SPI.transfer(op_code);
releaseChipSelect();
return;
}
/*
* Sends a STOP/START command sequence to the ADS124S08 to restart conversions (SYNC)
*
*/
void ADS124S08::reStart(void)
{
sendCommand(STOP_OPCODE_MASK);
sendCommand(START_OPCODE_MASK);
return;
}
/*
* Sets the GPIO hardware START pin high (red LED)
*
*/
void ADS124S08::assertStart()
{
fStart = true;
digitalWrite(START_PIN ,HIGH);
}
/*
* Sets the GPIO hardware START pin low
*
*/
void ADS124S08::deassertStart()
{
fStart = false;
digitalWrite(START_PIN, LOW);
}
/*
* Sets the GPIO hardware external oscillator enable pin high
*
*/
void ADS124S08::assertClock()
{
digitalWrite(CKEN_PIN, 1);
}
/*
* Sets the GPIO hardware external oscillator enable pin low
*
*/
void ADS124S08::deassertClock()
{
digitalWrite(CKEN_PIN, LOW);
}
int ADS124S08::rData(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC)
{
int result = -1;
selectDeviceCSLow();
// according to datasheet chapter 9.5.4.2 Read Data by RDATA Command
sendCommand(RDATA_OPCODE_MASK);
// if the Status byte is set - grab it
uint8_t shouldWeReceiveTheStatusByte = (registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS;
if( shouldWeReceiveTheStatusByte )
{
dStatus[0] = SPI.transfer(0x00);
//Serial.print("status: ");
//Serial.print(dStatus[0]);
}
// get the conversion data (3 bytes)
uint8_t data[3];
data[0] = SPI.transfer(0x00);
data[1] = SPI.transfer(0x00);
data[2] = SPI.transfer(0x00);
result = data[0];
result = (result<<8) + data[1];
result = (result<<8) + data[2];
//Serial.printlnf(" 1: %02x 2: %02x, 3: %02x = %d", data[0], data[1], data[2], result);
// is CRC enabled?
uint8_t isCrcEnabled = (registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC;
if( isCrcEnabled )
{
dCRC[0] = SPI.transfer(0x00);
}
releaseChipSelect();
return result;
}
/*
*
* Read the last conversion result
*
*/
int ADS124S08::dataRead(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC)
{
uint8_t xcrc;
uint8_t xstatus;
int iData;
selectDeviceCSLow();
if((registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS)
{
xstatus = SPI.transfer(0x00);
//Serial.print("0:");
//Serial.print(xstatus);
dStatus[0] = (uint8_t)xstatus;
}
// get the conversion data (3 bytes)
uint8_t data[3];
data[0] = SPI.transfer(0x00);
data[1] = SPI.transfer(0x00);
data[2] = SPI.transfer(0x00);
/*
Serial.print(" 1:");
Serial.print(data[0]);
Serial.print(" 2:");
Serial.print(data[1]);
Serial.print(" 3:");
Serial.println(data[2]);
*/
iData = data[0];
iData = (iData<<8) + data[1];
iData = (iData<<8) + data[2];
if((registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
{
xcrc = SPI.transfer(0x00);
dCRC[0] = (uint8_t)xcrc;
}
releaseChipSelect();
return iData ;
}
.h file
/* --COPYRIGHT--,BSD
* Copyright (c) 2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --/COPYRIGHT--*/
/*
* ADS124S08.h
*
*/
#ifndef ADS124S08_H_
#define ADS124S08_H_
#include <SPI.h>
/* Start definitions */
#define NUM_REGISTERS 18
/*
* Address masks used for register addressing with
* either a REGRD of REGWR mask
*
*/
#define ID_ADDR_MASK 0x00
#define STATUS_ADDR_MASK 0x01
#define INPMUX_ADDR_MASK 0x02
#define PGA_ADDR_MASK 0x03
#define DATARATE_ADDR_MASK 0x04
#define REF_ADDR_MASK 0x05
#define IDACMAG_ADDR_MASK 0x06
#define IDACMUX_ADDR_MASK 0x07
#define VBIAS_ADDR_MASK 0x08
#define SYS_ADDR_MASK 0x09
#define OFCAL0_ADDR_MASK 0x0A
#define OFCAL1_ADDR_MASK 0x0B
#define OFCAL2_ADDR_MASK 0x0C
#define FSCAL0_ADDR_MASK 0x0D
#define FSCAL1_ADDR_MASK 0x0E
#define FSCAL2_ADDR_MASK 0x0F
#define GPIODAT_ADDR_MASK 0x10
#define GPIOCON_ADDR_MASK 0x11
/* Opcode masks (or "Commands" if you will...) */
#define NOP_OPCODE_MASK 0x00
#define WAKE_OPCODE_MASK 0x02
#define SLEEP_OPCODE_MASK 0x04
#define RESET_OPCODE_MASK 0x06
#define START_OPCODE_MASK 0x08
#define STOP_OPCODE_MASK 0x0A
#define SFOCAL_OPCODE_MASK 0x19
#define SYOCAL_OPCODE_MASK 0x16
#define SYGCAL_OPCODE_MASK 0x17
#define RDATA_OPCODE_MASK 0x12
#define REGRD_OPCODE_MASK 0x20
#define REGWR_OPCODE_MASK 0x40
/* Register sub masks */
/* ADS124S08 Register 0 (ID) Definition
* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* RESERVED[4:0] | DEV_ID[2:0]
*
*/
/* Define ID (revision) */
#define ADS_ID_A 0x00
#define ADS_ID_B 0x80
/* Define VER (device version) */
#define ADS_124S08 0x00
#define ADS_124S06 0x01
#define ADS_114S08 0x04
#define ADS_114S06 0x05
/* ADS124S08 Register 1 (STATUS) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* FL_POR | nRDY | FL_P_RAILP| FL_P_RAILN| FL_N_RAILP| FL_N_RAILN| FL_REF_L1 | FL_REF_L0
*
*/
#define ADS_FL_POR 0x80
#define ADS_RDY 0x40
#define ADS_FL_P_RAILP 0x20
#define ADS_FL_P_RAILN 0x10
#define ADS_FL_N_RAILP 0x08
#define ADS_FL_N_RAILN 0x04
#define ADS_FL_REF_L1 0x02
#define ADS_FL_REF_L0 0x10
/* ADS124S08 Register 2 (INPMUX) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* MUXP[3:0] | MUXN[3:0]
*
*/
/* Define the ADC positive input channels (MUXP) */
#define ADS_P_AIN0 0x00
#define ADS_P_AIN1 0x10
#define ADS_P_AIN2 0x20
#define ADS_P_AIN3 0x30
#define ADS_P_AIN4 0x40
#define ADS_P_AIN5 0x50
#define ADS_P_AIN6 0x60
#define ADS_P_AIN7 0x70
#define ADS_P_AIN8 0x80
#define ADS_P_AIN9 0x90
#define ADS_P_AIN10 0xA0
#define ADS_P_AIN11 0xB0
#define ADS_P_AINCOM 0xC0
/* Define the ADC negative input channels (MUXN)*/
#define ADS_N_AIN0 0x00
#define ADS_N_AIN1 0x01
#define ADS_N_AIN2 0x02
#define ADS_N_AIN3 0x03
#define ADS_N_AIN4 0x04
#define ADS_N_AIN5 0x05
#define ADS_N_AIN6 0x06
#define ADS_N_AIN7 0x07
#define ADS_N_AIN8 0x08
#define ADS_N_AIN9 0x09
#define ADS_N_AIN10 0x0A
#define ADS_N_AIN11 0x0B
#define ADS_N_AINCOM 0x0C
/* ADS124S08 Register 3 (PGA) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* DELAY[2:0] | PGA_EN[1:0] | GAIN[2:0]
*
*/
/* Define conversion delay in tmod clock periods */
#define ADS_DELAY_14 0x00
#define ADS_DELAY_25 0x20
#define ADS_DELAY_64 0x40
#define ADS_DELAY_256 0x60
#define ADS_DELAY_1024 0x80
#define ADS_DELAY_2048 0xA0
#define ADS_DELAY_4096 0xC0
#define ADS_DELAY_1 0xE0
/* Define PGA control */
#define ADS_PGA_BYPASS 0x00
#define ADS_PGA_ENABLED 0x08
/* Define Gain */
#define ADS_GAIN_1 0x00
#define ADS_GAIN_2 0x01
#define ADS_GAIN_4 0x02
#define ADS_GAIN_8 0x03
#define ADS_GAIN_16 0x04
#define ADS_GAIN_32 0x05
#define ADS_GAIN_64 0x06
#define ADS_GAIN_128 0x07
/* ADS124S08 Register 4 (DATARATE) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* G_CHOP | CLK | MODE | FILTER | DR[3:0]
*
*/
#define ADS_GLOBALCHOP 0x80
#define ADS_CLKSEL_EXT 0x40
#define ADS_CONVMODE_SS 0x20
#define ADS_FILTERTYPE_LL 0x10
/* Define the data rate */
#define ADS_DR_2_5 0x00
#define ADS_DR_5 0x01
#define ADS_DR_10 0x02
#define ADS_DR_16 0x03
#define ADS_DR_20 0x04
#define ADS_DR_50 0x05
#define ADS_DR_60 0x06
#define ADS_DR_100 0x07
#define ADS_DR_200 0x08
#define ADS_DR_400 0x09
#define ADS_DR_800 0x0A
#define ADS_DR_1000 0x0B
#define ADS_DR_2000 0x0C
#define ADS_DR_4000 0x0D
/* ADS124S08 Register 5 (REF) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* FL_REF_EN[1:0] | nREFP_BUF | nREFN_BUF | REFSEL[1:0] | REFCON[1:0]
*
*/
#define ADS_FLAG_REF_DISABLE 0x00
#define ADS_FLAG_REF_EN_L0 0x40
#define ADS_FLAG_REF_EN_BOTH 0x80
#define ADS_FLAG_REF_EN_10M 0xC0
#define ADS_REFP_BYP_DISABLE 0x20
#define ADS_REFP_BYP_ENABLE 0x00
#define ADS_REFN_BYP_DISABLE 0x10
#define ADS_REFN_BYP_ENABLE 0x00
#define ADS_REFSEL_P0 0x00
#define ADS_REFSEL_P1 0x04
#define ADS_REFSEL_INT 0x08
#define ADS_REFINT_OFF 0x00
#define ADS_REFINT_ON_PDWN 0x01
#define ADS_REFINT_ON_ALWAYS 0x02
/* ADS124S08 Register 6 (IDACMAG) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* FL_RAIL_EN| PSW | 0 | 0 | IMAG[3:0]
*
*/
#define ADS_FLAG_RAIL_ENABLE 0x80
#define ADS_FLAG_RAIL_DISABLE 0x00
#define ADS_PSW_OPEN 0x00
#define ADS_PSW_CLOSED 0x40
#define ADS_IDACMAG_OFF 0x00
#define ADS_IDACMAG_10 0x01
#define ADS_IDACMAG_50 0x02
#define ADS_IDACMAG_100 0x03
#define ADS_IDACMAG_250 0x04
#define ADS_IDACMAG_500 0x05
#define ADS_IDACMAG_750 0x06
#define ADS_IDACMAG_1000 0x07
#define ADS_IDACMAG_1500 0x08
#define ADS_IDACMAG_2000 0x09
/* ADS124S08 Register 7 (IDACMUX) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* I2MUX[3:0] | I1MUX[3:0]
*
*/
/* Define IDAC2 Output */
#define ADS_IDAC2_A0 0x00
#define ADS_IDAC2_A1 0x10
#define ADS_IDAC2_A2 0x20
#define ADS_IDAC2_A3 0x30
#define ADS_IDAC2_A4 0x40
#define ADS_IDAC2_A5 0x50
#define ADS_IDAC2_A6 0x60
#define ADS_IDAC2_A7 0x70
#define ADS_IDAC2_A8 0x80
#define ADS_IDAC2_A9 0x90
#define ADS_IDAC2_A10 0xA0
#define ADS_IDAC2_A11 0xB0
#define ADS_IDAC2_AINCOM 0xC0
#define ADS_IDAC2_OFF 0xF0
/* Define IDAC1 Output */
#define ADS_IDAC1_A0 0x00
#define ADS_IDAC1_A1 0x01
#define ADS_IDAC1_A2 0x02
#define ADS_IDAC1_A3 0x03
#define ADS_IDAC1_A4 0x04
#define ADS_IDAC1_A5 0x05
#define ADS_IDAC1_A6 0x06
#define ADS_IDAC1_A7 0x07
#define ADS_IDAC1_A8 0x08
#define ADS_IDAC1_A9 0x09
#define ADS_IDAC1_A10 0x0A
#define ADS_IDAC1_A11 0x0B
#define ADS_IDAC1_AINCOM 0x0C
#define ADS_IDAC1_OFF 0x0F
/* ADS124S08 Register 8 (VBIAS) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* VB_LEVEL | VB_AINC | VB_AIN5 | VB_AIN4 | VB_AIN3 | VB_AIN2 | VB_AIN1 | VB_AIN0
*
*/
#define ADS_VBIAS_LVL_DIV2 0x00
#define ADS_VBIAS_LVL_DIV12 0x80
/* Define VBIAS here */
#define ADS_VB_AINC 0x40
#define ADS_VB_AIN5 0x20
#define ADS_VB_AIN4 0x10
#define ADS_VB_AIN3 0x08
#define ADS_VB_AIN2 0x04
#define ADS_VB_AIN1 0x02
#define ADS_VB_AIN0 0x01
/* ADS124S08 Register 9 (SYS) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* SYS_MON[2:0] | CAL_SAMP[1:0] | TIMEOUT | CRC | SENDSTAT
*
*/
#define ADS_SYS_MON_OFF 0x00
#define ADS_SYS_MON_SHORT 0x20
#define ADS_SYS_MON_TEMP 0x40
#define ADS_SYS_MON_ADIV4 0x60
#define ADS_SYS_MON_DDIV4 0x80
#define ADS_SYS_MON_BCS_2 0xA0
#define ADS_SYS_MON_BCS_1 0xC0
#define ADS_SYS_MON_BCS_10 0xE0
#define ADS_CALSAMPLE_1 0x00
#define ADS_CALSAMPLE_4 0x08
#define ADS_CALSAMPLE_8 0x10
#define ADS_CALSAMPLE_16 0x18
#define ADS_TIMEOUT_DISABLE 0x00
#define ADS_TIMEOUT_ENABLE 0x04
#define ADS_CRC_DISABLE 0x00
#define ADS_CRC_ENABLE 0x02
#define ADS_SENDSTATUS_DISABLE 0x00
#define ADS_SENDSTATUS_ENABLE 0x01
/* ADS124S08 Register A (OFCAL0) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* OFC[7:0]
*
*/
/* ADS124S08 Register B (OFCAL1) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* OFC[15:8]
*
*/
/* ADS124S08 Register C (OFCAL2) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* OFC[23:16]
*
*/
/* ADS124S08 Register D (FSCAL0) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* FSC[7:0]
*
*/
/* ADS124S08 Register E (FSCAL1) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* FSC[15:8]
*
*/
/* ADS124S08 Register F (FSCAL2) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* FSC[23:16]
*
*/
/* ADS124S08 Register 10 (GPIODAT) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* DIR[3:0] | DAT[3:0]
*
*/
/* Define GPIO direction (0-Output; 1-Input) here */
#define ADS_GPIO0_DIR_INPUT 0x10
#define ADS_GPIO1_DIR_INPUT 0x20
#define ADS_GPIO2_DIR_INPUT 0x40
#define ADS_GPIO3_DIR_INPUT 0x80
/*
*
*/
/* Define GPIO data here */
/*
*
*/
/* ADS124S08 Register 11 (GPIOCON) Definition */
/* Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
*--------------------------------------------------------------------------------------------
* 0 | 0 | 0 | 0 | CON[3:0]
*
*/
/* Define GPIO configuration (0-Analog Input; 1-GPIO) here */
#define ADS_GPIO0_DIR_INPUT 0x10
#define ADS_GPIO1_DIR_INPUT 0x20
#define ADS_GPIO2_DIR_INPUT 0x40
#define ADS_GPIO3_DIR_INPUT 0x80
/*
*
*/
/* Lengths of conversion data components */
#define DATA_LENGTH 3
#define STATUS_LENGTH 1
#define CRC_LENGTH 1
/*
* The time we have to wait for the CS GPIO to actually
* pull down before we start sending SCLKs
*
*/
#define CHIP_SELECT_WAIT_TIME 0
/* Flag to signal that we are in the process of collecting data */
#define DATA_MODE_NORMAL 0x00
#define DATA_MODE_STATUS 0x01
#define DATA_MODE_CRC 0x02
/* The clock rate of the internal XTAL... */
#define DEVICE_ICLK 16384000
/* Set the SPI SCLK speed */
#define SPI_SPEED 1000000
// 5000000
/*
* The TIVA has a 4 to 16 bit word size, to handle 32 bit words the TIVA needs to assemble
* two groups of words together. 32 bits comprises of 2x16 words (or 4x8 words).
*/
#define SPI_WORD_SIZE 8
/* Chip select feedthrough GPIO - we hand feed chip select so overages may be pumped out. */
#define CS_PIN 6
#define DRDY_PIN -1
/* GPIO definitions. */
#define START_PIN A1
#define RESET_PIN A0
#define CKEN_PIN -1
#define SPI_HAS_TRANSACTION 0
#if defined (SPI_HAS_TRANSACTION)
static SPISettings mySPISettings;
#endif
class ADS124S08
{
// Device command prototypes
public:
ADS124S08(void);
void begin();
char regRead(unsigned int regnum);
void readRegs(unsigned int regnum, unsigned int count, uint8_t *data);
void regWrite(unsigned int regnum, unsigned char data);
void writeRegs(unsigned int regnum, unsigned int howmuch, unsigned char *data);
void reStart(void);
void sendCommand(uint8_t op_code);
int rData(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC);
int dataRead(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC);
void selectDeviceCSLow(void);
void releaseChipSelect(void);
void assertStart(void);
void deassertStart(void);
void assertClock(void);
void deassertClock(void);
bool converting;
uint8_t registers[NUM_REGISTERS];
private:
bool fStart;
void DRDY_int(void);
uint8_t _drdy_pin;
uint8_t _start_pin;
uint8_t _reset_pin;
};
#endif /* ADS124S08_H_ */