一、IC基本信息
ADS131A0x 双通道或四通道 24 位 128kSPS 同步采样 Δ-Σ ADC
•双通道或四通道同步采样差分输入
• 数据速率:高达 128kSPS
• 高性能: – 单通道精度:在 10,000:1 动态范围内优于 0.1% – 有效分辨率:20.6位 (8kSPS) – 总谐波失真 (THD):50Hz 和 60Hz 频率下为 -100dB
• 集成的负电荷泵 允许绝对输入电压低于接地值
• 灵活的模拟电源选项: – 采用负电荷泵:3.0V 至 3.45V – 单极电源:3.3V 至 5.5V – 双极电源:±2.5V
• 数字电源:1.65V 至 3.6V
晶振pinlv16.384MHz,fMOD = fICLK / 8 =2.048Mhz,fDATA = fMOD / 256 =8K 采样率
二、硬件电路
1、输入接口电路
R1、R2和C14形成了一个差分低通滤波器,通道1的-3dB截止频率为169.3 kHz。此外,R1和C15与R2和C16形成共模低通滤波器,截止频率-3dB为15.9 MHz。串联阻抗保持相对较低,以保持足够的总谐波失真(THD)性能。在所有输入上都存在类似的微分和通用模型低通滤波器。
M0M1M2引脚功能
手册推荐电源供电布局
官方评估开发板
SBAU353 User guide | 德州仪器 TI.com.cn
平板采用四层板设计,顶层、地层、电源层、底层,分别为以下图示
官方驱动示例代码如下,可能不能直接使用,但是可以了解大概得配置流程。
///
//
/**
*
* \copyright Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
*
* 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.
*
*/
#include "ads131a04.h"
//****************************************************************************
//
// Macros
//
//****************************************************************************
// Determine number of bytes per command based on WORD_LENGTH
#define WORD_LENGTH (WORD_LENGTH_BITS >> 3)
// Fetch the upper byte of a 16-bit word and return it as an 8-bit value
#define UPPER_BYTE(x) ((uint8_t) ((0xFF00 & x) >> 8))
// Fetch the lower byte of a 16-bit word and return it as an 8-bit value
#define LOWER_BYTE(x) ((uint8_t) (0x00FF & x))
// Combine two 8-bit values into a 16-bit word
#define COMBINE_BYTES(x, y) (((uint16_t) x << 8) | ((uint16_t) y & 0x00FF))
//****************************************************************************
//
// Internal variables
//
//****************************************************************************
// Array used to recall last known values of the device's register map settings */
static uint8_t registerMap[NUM_REGISTERS];
// Flag to keep track of device's register lock status
// NOTE: The device defaults to locked
static bool registersLocked = true;
// Arrays to store RX and TX data for SPI communication
static uint8_t dataTx[6 * WORD_LENGTH] = { 0 };
static uint8_t dataRx[6 * WORD_LENGTH] = { 0 };
// Variable to keep track of the number of words in an SPI frame
#ifdef SET_FIXED
static uint8_t cmdByteLength = 6 * WORD_LENGTH;
#else
static uint8_t cmdByteLength = WORD_LENGTH;
#endif
//****************************************************************************
//
// Internal function prototypes
//
//****************************************************************************
#ifdef SET_CRC_EN
static void updateCrcIn(void);
#endif
//*****************************************************************************
//
//! Getter function to access registerMap array from outside of this module.
//!
//! \fn uint16_t getRegisterValue(uint8_t address)
//!
//! NOTE: The internal registerMap arrays stores the last known register value,
//! since the last read or write operation to that register. This function
//! does not communicate with the device to retrieve the current register value.
//! For the most up-to-date register data or reading the value of a hardware
//! controlled register, it is recommend to use readSingleRegister() to read the
//! device register.
//!
//! \param address is the 8-bit address of the register value to recall.
//!
//! \return unsigned 8-bit register value.
//
//*****************************************************************************
uint8_t getRegisterValue(uint8_t address)
{
assert(address < NUM_REGISTERS);
return registerMap[address];
}
//*****************************************************************************
//
//! Example start up sequence for the ADS131A04.
//!
//! \fn void adcStartup(void)
//!
//! Before calling this function, the device must be powered,
//! the SPI/GPIO pins of the MCU must have already been configured,
//! and (if applicable) the external clock source should be provided to CLKIN.
//!
//! NOTE: You may want to modify this function to configure the ADC's initial
//! register settings to your application's requirements.
//!
//! \return None.
//
//*****************************************************************************
void adcStartup(void)
{
/* (OPTIONAL) Provide additional delay time for power supply settling */
delay_ms(50);
/* (REQUIRED) Set nRESET pin high for ADC operation */
setRESET(HIGH);
/* (INTERNAL) Initialize internal 'registerMap' array with device default settings */
restoreRegisterDefaults();
/* (OPTION #1) Wait ~5ms for POR to complete */
delay_ms(5);
/* (OPTION #2) Wait for nDRDY falling edge for indication that POR has completed */
// bool interruptedOccurred = waitForDRDYinterrupt(20);
// if (!interruptedOccurred)
// {
// // Error: Device appears to be unresponsive. Check the power supplies, clock,
// // and GPIO pins to make sure the device is active.
// assert(0);
// }
/* (REQUIRED) Always send a NULL command first to establish SPI communication */
sendCommand(OPCODE_NULL);
/* (OPTIONAL) Verify READY response */
uint16_t response = sendCommand(OPCODE_NULL);
if (0xFF04 != response)
{
// Error: Unexpected response
assert(0);
}
/* (REQUIRED) Send UNLOCK to exit 'READY' state */
unlockRegisters();
//
// Configure initial register settings here...
//
// Default value for D_SYS_CFG_ADDRESS register
uint8_t regVal = D_SYS_CFG_DEFAULT;
#ifdef SET_FIXED
regVal |= D_SYS_CFG_FIXED_MASK; // Set FIXED bit
#endif
#ifdef SET_CRC_EN
regVal |= D_SYS_CFG_CRC_EN_MASK; // Set CRC_EN bit
#endif
#ifdef SET_CRC_MODE
regVal |= D_SYS_CFG_CRC_MODE_MASK; // Set CRC_MODE bit
#endif
// Write to D_SYS_CFG_ADDRESS
writeSingleRegister(D_SYS_CFG_ADDRESS, regVal);
// Configure data rate
writeSingleRegister(CLK1_ADDRESS, CLK1_CLK_DIV_2);
writeSingleRegister(CLK2_ADDRESS, CLK2_ICLK_DIV_2 | CLK2_OSR_2048);
// Enable all ADC channels
writeSingleRegister(ADC_ENA_ADDRESS, ADC_ENA_ENA_ALL_CH_PWUP);
/* (REQUIRED) Always send a NULL command first to establish SPI communication */
sendCommand(OPCODE_WAKEUP);
// Ignore the first 3-4 conversion results to allow for the
// output buffers to fill-up and the SINC3 filter to settle
uint8_t ignore_counter = 4;
adc_data_struct dummy_data;
while (ignore_counter > 0)
{
waitForDRDYinterrupt(1000);
readData(&dummy_data);
ignore_counter--;
}
}
//*****************************************************************************
//
//! Reads the contents of a single register at the specified address.
//!
//! \fn uint8_t readSingleRegister(uint8_t address)
//!
//! \param address is the 8-bit address of the register to read.
//!
//! \return Returns the 8-bit register read result.
//
//*****************************************************************************
uint8_t readSingleRegister(uint8_t address)
{
/* Assert(s) */
assert(address < NUM_REGISTERS); // Register address must be in range
// Build TX array
dataTx[0] = UPPER_BYTE(OPCODE_RREG) | address;
dataTx[1] = 0x00;
#ifdef SET_CRC_EN
// Calculates the CRC IN word and adds it to the dataTx[] array
updateCrcIn();
#endif
// [FRAME 1] Send RREG command
spiSendReceiveArrays(dataTx, dataRx, cmdByteLength);
// [FRAME 2] Send NULL command to retrieve the register data
uint16_t response = sendCommand(OPCODE_NULL);
// Verify device response
if (UPPER_BYTE(response) == OPCODE_RREG | ((uint16_t) address))
{
// Update internal register array data
registerMap[address] = LOWER_BYTE(response);
}
return registerMap[address];
}
//*****************************************************************************
//
//! Writes data to a single register.
//!
//! \fn void writeSingleRegister(uint8_t address, uint8_t data)
//!
//! This command will be ignored if device registers are locked.
//!
//! NOTE: This functions also performs a NULL command frame after the register
//! write command to verify the new register value.
//!
//! \param address is the address of the register to write to.
//! \param data is the value to write.
//!
//! \return None.
//
//*****************************************************************************
void writeSingleRegister(uint8_t address, uint8_t data)
{
/* Assert(s) */
assert(address < NUM_REGISTERS); // Register address must be in range
// (OPTIONAL) Enforce certain register settings when writing to the D_SYS_CFG register
// to avoid having to write code that supports multiple device modes. For example...
// if (D_SYS_CFG_ADDRESS == address)
// {
// data = data | D_SYS_CFG_FIXED_MASK | D_SYS_CFG_CRC_EN_MASK;
// }
// Save current register value
uint8_t oldValue = registerMap[address];
// Build TX byte array
dataTx[0] = UPPER_BYTE(OPCODE_WREG) | address;
dataTx[1] = data;
#ifdef SET_CRC_EN
// Calculates the CRC IN word and adds it to the dataTx[] array
updateCrcIn();
#endif
// [FRAME 1] Send WREG command
spiSendReceiveArrays(dataTx, dataRx, cmdByteLength);
// Update register map array with new value
// NOTE: This ensures that the NULL command in the next frame is sent correctly.
registerMap[address] = data;
// [FRAME 2] Send NULL command to verify WREG response
uint16_t response = sendCommand(OPCODE_NULL);
// Verify device response
if (UPPER_BYTE(response) == (UPPER_BYTE(OPCODE_RREG) | address))
{
// Update internal register array data
registerMap[address] = LOWER_BYTE(response);
}
else
{
// Restore previous register value
registerMap[address] = oldValue;
}
}
//*****************************************************************************
//
//! Read ADC data
//!
//! \fn bool readData(adc_data_struct *dataStruct)
//!
//! \param dataStruct pointer to data structure where results from reading data will be placed
//!
//! NOTE: This is currently the only function in this example that verifies if the
//! CRC word on DOUT is correct.
//!
//! \return bool indicating if a CRC mismatch occurred (false = No error)
//
//*****************************************************************************
bool readData(adc_data_struct *dataStruct)
{
// Build TX array
dataTx[0] = 0x00;
dataTx[1] = 0x00;
#ifdef SET_CRC_EN
// NOTE: The following CRC words are hard-coded based on word length, fixed mode, and CRC mode...
#if defined SET_FIXED && !defined SET_CRC_MODE // Only the command word is included in CRC calculation
#ifdef WORD_LENGTH_24BIT
dataTx[5*WORD_LENGTH] = 0xCC;
dataTx[5*WORD_LENGTH + 1] = 0x9C;
#elif WORD_LENGTH_16BIT
dataTx[5*WORD_LENGTH] = 0x1D;
dataTx[5*WORD_LENGTH + 1] = 0x0F;
#elif WORD_LENGTH_32BIT
dataTx[5*WORD_LENGTH] = 0x84;
dataTx[5*WORD_LENGTH + 1] = 0xC0;
#endif
#else // FIXED = 0 OR (FIXED = 1 and CRC_MODE = 1) -> All device words are included in CRC calculation
#ifdef WORD_LENGTH_24BIT
dataTx[5*WORD_LENGTH] = 0x4E;
dataTx[5*WORD_LENGTH + 1] = 0xC3;
#elif WORD_LENGTH_16BIT
dataTx[5*WORD_LENGTH] = 0xE1;
dataTx[5*WORD_LENGTH + 1] = 0x39;
#elif WORD_LENGTH_32BIT
dataTx[5*WORD_LENGTH] = 0xF6;
dataTx[5*WORD_LENGTH + 1] = 0xB8;
#endif
#endif
#endif
/* Set the nCS pin LOW */
setCS(LOW);
// Send NULL word, receive response word
int i = 0;
while (i < 6*WORD_LENGTH)
{
dataRx[i] = spiSendReceiveByte(dataTx[i]);
++i;
}
dataStruct->response = COMBINE_BYTES(dataRx[0], dataRx[1]);
dataStruct->channel1 = signExtend(&dataRx[1*WORD_LENGTH]);
dataStruct->channel2 = signExtend(&dataRx[2*WORD_LENGTH]);
dataStruct->channel3 = signExtend(&dataRx[3*WORD_LENGTH]);
dataStruct->channel4 = signExtend(&dataRx[4*WORD_LENGTH]);
dataStruct->crc = COMBINE_BYTES(dataRx[5*WORD_LENGTH], dataRx[5*WORD_LENGTH + 1]);
#ifdef CRC_EN
uint16_t crcWordOut = calculateCRC(&dataRx[0], 6*WORD_LENGTH, 0xFFFF);
#else
// (OPTIONAL) Ignore CRC error checking (CRC = 0x00 -> indicates a valid SPI frame)
uint16_t crcWordOut = 0x00;
#endif
/* Set the nCS pin HIGH */
setCS(HIGH);
// Returns true when a CRC error occurs (any non-zero value for crcWordOut)
return ((bool) crcWordOut);
}
//*****************************************************************************
//
//! Sends the specified SPI command to the ADC (NULL, RESET, STANDBY, or WAKEUP).
//!
//! \fn uint16_t sendCommand(uint16_t opcode)
//!
//! \param opcode 16-bit SPI command.
//!
//! NOTE: Other ADC commands have their own dedicated functions to support
//! additional functionality. This function will raise an assert if used
//! with one of these commands (RREG, WREG, WREGS, LOCK,or UNLOCK).
//!
//! \return uint16_t response byte (typically the STATUS byte).
//
//*****************************************************************************
uint16_t sendCommand(uint16_t opcode)
{
/* Assert if this function is used to send any of the following opcodes */
assert(OPCODE_RREG != opcode); /* Use "readSingleRegister()" */
assert(OPCODE_WREG != opcode); /* Use "writeSingleRegister()" */
assert(OPCODE_LOCK != opcode); /* Use "lockRegisters()" */
assert(OPCODE_UNLOCK != opcode); /* Use "unlockRegisters()" */
//assert(OPCODE_WREGS != opcode);
// Build TX byte array
dataTx[0] = UPPER_BYTE(opcode);
dataTx[1] = LOWER_BYTE(opcode);
#ifdef SET_CRC_EN
// Calculates the CRC IN word and adds it to the dataTx[] array
updateCrcIn();
#endif
// Set the nCS pin LOW
setCS(LOW);
// Send the opcode (and crc word, if enabled)
int i;
for (i = 0; i < cmdByteLength; i++)
{
dataRx[i] = spiSendReceiveByte(dataTx[i]);
}
// Set the nCS pin HIGH
setCS(HIGH);
// If OPCODE_RESET, then recall default register settings
if (OPCODE_RESET == opcode) { restoreRegisterDefaults(); }
// Combine response bytes and return as a 16-bit word
uint16_t response = COMBINE_BYTES(dataRx[0], dataRx[1]);
return response;
}
//*****************************************************************************
//
//! Sends the LOCK command and then verifies that registers are locked.
//!
//! \fn bool lockRegisters(void)
//!
//! \return boolean to indicate if registers are locked (0 = unlocked; 1 = locked)
//
//*****************************************************************************
bool lockRegisters(void)
{
// Build TX array
dataTx[0] = UPPER_BYTE(OPCODE_LOCK);
dataTx[1] = LOWER_BYTE(OPCODE_LOCK);
#ifdef SET_CRC_EN
// Calculates the CRC IN word and adds it to the dataTx[] array
updateCrcIn();
#endif
// [FRAME 1] Send WREG command
spiSendReceiveArrays(dataTx, dataRx, cmdByteLength);
// [FRAME 2] Send NULL command to verify response
uint16_t response = sendCommand(OPCODE_NULL);
// Verify device response and update internal flag
if (OPCODE_LOCK == response) { registersLocked = true; }
return registersLocked;
}
//*****************************************************************************
//
//! Sends the UNLOCK command and then verifies that registers are unlocked
//!
//! \fn bool unlockRegisters(void)
//!
//! \return boolean to indicate if registers are locked (0 = unlocked; 1 = locked)
//
//*****************************************************************************
bool unlockRegisters(void)
{
// Build TX array
dataTx[0] = UPPER_BYTE(OPCODE_UNLOCK);
dataTx[1] = LOWER_BYTE(OPCODE_UNLOCK);
#ifdef SET_CRC_EN
// Calculates the CRC IN word and adds it to the dataTx[] array
updateCrcIn();
#endif
// [FRAME 1] Send WREG command
spiSendReceiveArrays(dataTx, dataRx, cmdByteLength);
// [FRAME 2] Send NULL command to verify response
uint16_t response = sendCommand(OPCODE_NULL);
// Verify device response and update internal flag
if (OPCODE_UNLOCK == response) { registersLocked = false; }
// Return lock status
return registersLocked;
}
//*****************************************************************************
//
//! Calculates the 16-bit CRC for the selected CRC polynomial.
//!
//! \fn uint16_t calculateCRC(const uint8_t dataBytes[], uint8_t numberBytes, uint16_t initialValue)
//!
//! \param dataBytes[] pointer to first element in the data byte array
//! \param numberBytes length of data byte array to include in the CRC calculation
//! \param initialValue the seed value (or partial crc calculation), use 0xFFFF when beginning a new CRC computation
//!
//! NOTE: This calculation is shown as an example and has not been optimized for speed.
//!
//! \return uint16_t calculated CRC word. When performing a partial CRC computation, provide this
//! value as the input to initialValue to resume computing the CRC for additional input bytes.
//
//*****************************************************************************
uint16_t calculateCRC(const uint8_t dataBytes[], uint8_t numberBytes, uint16_t initialValue)
{
/* Assert(s) */
assert(dataBytes != 0x00); // "dataBytes" must not be a NULL pointer
assert(numberBytes != 0x00); // "numberBytes" must be greater than zero
int bitIndex, byteIndex;
bool dataMSb; // Most significant bit of data byte
bool crcMSb; // Most significant bit of crc byte
// Initial value of crc register
uint16_t crc = initialValue;
// CRC16-CCITT polynomial
// NOTE: The polynomial's MSB is generally assumed to be high (and is handled by
// the "dataMSb ^ crcMSb" operation below) and so it is excluded from this value.
const uint16_t poly = 0x1021;
//
// CRC algorithm...
//
// Loop through all bytes in the dataBytes[] array
for (byteIndex = 0; byteIndex < numberBytes; byteIndex++)
{
// Point to MSb in byte
bitIndex = 0x80u;
// Loop through all bits in the current byte
while (bitIndex > 0)
{
// Check MSB's of data and crc
dataMSb = (bool) (dataBytes[byteIndex] & bitIndex);
crcMSb = (bool) (crc & 0x8000u);
// Left-shift CRC register
crc <<= 1;
// Check if XOR operation of MSBs results in additional XOR operations
if (dataMSb ^ crcMSb)
{
// XOR crc with polynomial
crc ^= poly;
}
// Shift MSb pointer to the next data bit
bitIndex >>= 1;
}
}
return crc;
}
#ifdef SET_CRC_EN
//*****************************************************************************
//
//! Calculates the 16-bit CRC word for dataTx[] array
//!
//! \fn static void updateCrcIn(void)
//!
//! \return none - the resulting CRC value is added to the dataTx[] array
//
//*****************************************************************************
static void updateCrcIn(void)
{
// Calculate CRC word
// NOTE: To save time, use a lookup table instead of calculating the CRC value each time this function is called.
uint16_t crcWordIn = calculateCRC(dataTx, ((FIXED & !CRC_MODE) ? 1 : 5) * WORD_LENGTH, 0xFFFF);
dataTx[5*WORD_LENGTH] = UPPER_BYTE(crcWordIn);
dataTx[5*WORD_LENGTH + 1] = LOWER_BYTE(crcWordIn);
}
#endif
//*****************************************************************************
//
//! Updates the registerMap[] array to its default values.
//!
//! \fn void restoreRegisterDefaults(void)
//!
//! NOTES:
//! - If the MCU keeps a copy of the ADC's register settings in memory,
//! then it is important to ensure that these values remain in sync with the
//! actual hardware settings. In order to help facilitate this, this function
//! should be called after powering up or resetting the device (either by
//! hardware pin control or SPI software command), as is shown in this example.
//!
//! \return None.
//
//*****************************************************************************
void restoreRegisterDefaults(void)
{
registerMap[ID_MSB_ADDRESS] = ID_MSB_NU_CH_4; /* NOTE: This a read-only register */
registerMap[ID_LSB_ADDRESS] = 0x00; /* NOTE: REV_ID value is unknown until read */
registerMap[STAT_1_ADDRESS] = STAT_1_DEFAULT;
registerMap[STAT_P_ADDRESS] = STAT_P_DEFAULT;
registerMap[STAT_N_ADDRESS] = STAT_N_DEFAULT;
registerMap[STAT_S_ADDRESS] = STAT_S_DEFAULT;
registerMap[ERROR_CNT_ADDRESS] = ERROR_CNT_DEFAULT;
registerMap[STAT_M2_ADDRESS] = STAT_M2_DEFAULT & STAT_M2_DEFAULT_MASK;
registerMap[A_SYS_CFG_ADDRESS] = A_SYS_CFG_DEFAULT;
registerMap[D_SYS_CFG_ADDRESS] = D_SYS_CFG_DEFAULT;
registerMap[CLK1_ADDRESS] = CLK1_DEFAULT;
registerMap[CLK2_ADDRESS] = CLK2_DEFAULT;
registerMap[ADC_ENA_ADDRESS] = ADC_ENA_DEFAULT;
registerMap[ADC1_ADDRESS] = ADC1_DEFAULT;
registerMap[ADC2_ADDRESS] = ADC2_DEFAULT;
registerMap[ADC3_ADDRESS] = ADC3_DEFAULT;
registerMap[ADC4_ADDRESS] = ADC4_DEFAULT;
}
//****************************************************************************
//
// Helper functions
//
//****************************************************************************
//*****************************************************************************
//
//! Internal function used by readData() to convert ADC data from multiple unsigned
//! bytes into a single signed 32-bit word.
//!
//! \fn int32_t signExtend(const uint8_t dataBytes[])
//!
//! \param dataBytes is a pointer to uint8_t[] where the first element is the MSB.
//!
//! \return Returns the signed-extend 32-bit result.
//
//*****************************************************************************
int32_t signExtend(const uint8_t dataBytes[])
{
#ifdef WORD_LENGTH_24BIT
int32_t upperByte = ((int32_t) dataBytes[0] << 24);
int32_t middleByte = ((int32_t) dataBytes[1] << 16);
int32_t lowerByte = ((int32_t) dataBytes[2] << 8);
// NOTE: This right-shift operation on signed data maintains the signed bit,
// and provides for the sign-extension from 24 to 32 bits.
return (((int32_t) (upperByte | middleByte | lowerByte)) >> 8);
#elif defined WORD_LENGTH_32BIT_SIGN_EXTEND
int32_t signByte = ((int32_t) dataBytes[0] << 24);
int32_t upperByte = ((int32_t) dataBytes[1] << 16);
int32_t middleByte = ((int32_t) dataBytes[2] << 8);
int32_t lowerByte = ((int32_t) dataBytes[3] << 0);
return (signByte | upperByte | middleByte | lowerByte);
#elif defined WORD_LENGTH_32BIT_ZERO_PADDED
int32_t upperByte = ((int32_t) dataBytes[0] << 24);
int32_t middleByte = ((int32_t) dataBytes[1] << 16);
int32_t lowerByte = ((int32_t) dataBytes[2] << 8);
// NOTE: This right-shift operation on signed data maintains the signed bit,
// and provides for the sign-extension from 24 to 32 bits.
return (((int32_t) (upperByte | middleByte | lowerByte)) >> 8); // Right-shift of signed data maintains signed bit
#elif defined WORD_LENGTH_16BIT_TRUNCATED
int32_t upperByte = ((int32_t) dataBytes[0] << 24);
int32_t lowerByte = ((int32_t) dataBytes[1] << 16);
// NOTE: This right-shift operation on signed data maintains the signed bit,
// and provides for the sign-extension from 16 to 32 bits.
return (((int32_t) (upperByte | lowerByte)) >> 16);
#endif
}
/**/
/**
*
* \copyright Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
*
* 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.
*
*/
#ifndef ADS131A04_H_
#define ADS131A04_H_
// Standard libraries
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
// Custom libraries
#include "hal.h"
//
// Configure Register settings - NOTE: These values can be change, but FIXED mode is recommended!
//
// Fixed SPI Frame Mode - NOTE: Dynamic frame mode requires additional logic
// (not provided in this example code) to prevent the F_SPI error flag.
#define SET_FIXED
// CRC Enable - NOTE: In this example enabling CRC will increase the amount
// of time it takes the MCU to construct and send an SPI frame!
//#define SET_CRC_EN
// CRC Mode - Selects which SPI words get included in the CRC computation
//#define SET_CRC_MODE
//
// Pin settings - NOTE: These values are NOT configurable in this example!
// This example code is only targeted at asynchronous slave mode with hamming validation turned off.
//
// M0 -> Tied to IOVDD
#define ASYNC_SLAVE_MODE
// M1 -> Tied to GND
#define WORD_LENGTH_BITS ((uint8_t) 24)
#define WORD_LENGTH_24BIT
//#define WORD_LENGTH_16BIT
//#define WORD_LENGTH_32BIT
// M2 -> Tied to GND
//#define HAMMING_ENABLED
//****************************************************************************
//
// Channel data structure
//
//****************************************************************************
typedef struct
{
int32_t channel1;
int32_t channel2;
int32_t channel3;
int32_t channel4;
uint16_t response;
uint16_t crc;
} adc_data_struct;
//**********************************************************************************
//
// Function prototypes
//
//**********************************************************************************
uint8_t getRegisterValue(uint8_t address);
void adcStartup(void);
uint8_t readSingleRegister(uint8_t address);
void writeSingleRegister(uint8_t address, uint8_t data);
bool readData(adc_data_struct *dataStruct);
uint16_t sendCommand(uint16_t opcode);
bool lockRegisters(void);
bool unlockRegisters(void);
uint16_t calculateCRC(const uint8_t dataBytes[], uint8_t numberBytes, uint16_t initialValue);
// Helper functions
void restoreRegisterDefaults(void);
int32_t signExtend(const uint8_t dataBytes[]);
//**********************************************************************************
//
// Device commands
//
//**********************************************************************************
#define OPCODE_NULL ((uint16_t) 0x0000)
#define OPCODE_RESET ((uint16_t) 0x0011)
#define OPCODE_STANDBY ((uint16_t) 0x0022)
#define OPCODE_WAKEUP ((uint16_t) 0x0033)
#define OPCODE_LOCK ((uint16_t) 0x0555)
#define OPCODE_UNLOCK ((uint16_t) 0x0655)
#define OPCODE_RREG ((uint16_t) 0x2000)
#define OPCODE_WREG ((uint16_t) 0x4000)
// NOTE: The following command(s) are not implemented in this example...
//#define OPCODE_WREGS ((uint16_t) 0x6000)
//**********************************************************************************
//
// Register definitions
//
//**********************************************************************************
#define NUM_REGISTERS ((uint8_t) 21)
/* Register 0x00 (ID_MSB) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | NU_CH[7:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ID_MSB register address */
#define ID_MSB_ADDRESS ((uint8_t) 0x00)
/* ID_MSB register field masks */
#define ID_MSB_NU_CH_MASK ((uint8_t) 0xFF)
/* NU_CH field values */
#define ID_MSB_NU_CH_2 ((uint8_t) 0x02)
#define ID_MSB_NU_CH_4 ((uint8_t) 0x04)
/* Register 0x01 (ID_LSB) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | REV_ID[7:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ID_LSB register address */
#define ID_LSB_ADDRESS ((uint8_t) 0x01)
/* ID_LSB register field masks */
#define ID_LSB_REV_ID_MASK ((uint8_t) 0xFF)
/* Register 0x02 (STAT_1) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | F_OPC | F_SPI | F_ADCIN | F_WDT | F_RESYNC | F_DRDY | F_CHECK |
* -------------------------------------------------------------------------------------------------
*/
/* STAT_1 register address */
#define STAT_1_ADDRESS ((uint8_t) 0x02)
/* STAT_1 default (reset) value */
#define STAT_1_DEFAULT ((uint8_t) 0x00)
/* STAT_1 register field masks */
#define STAT_1_F_OPC_MASK ((uint8_t) 0x40)
#define STAT_1_F_SPI_MASK ((uint8_t) 0x20)
#define STAT_1_F_ADCIN_MASK ((uint8_t) 0x10)
#define STAT_1_F_WDT_MASK ((uint8_t) 0x08)
#define STAT_1_F_RESYNC_MASK ((uint8_t) 0x04)
#define STAT_1_F_DRDY_MASK ((uint8_t) 0x02)
#define STAT_1_F_CHECK_MASK ((uint8_t) 0x01)
/* Register 0x03 (STAT_P) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | F_IN4P | F_IN3P | F_IN2P | F_IN1P |
* -------------------------------------------------------------------------------------------------
*/
/* STAT_P register address */
#define STAT_P_ADDRESS ((uint8_t) 0x03)
/* STAT_P default (reset) value */
#define STAT_P_DEFAULT ((uint8_t) 0x00)
/* STAT_P register field masks */
#define STAT_P_F_IN4P_MASK ((uint8_t) 0x08)
#define STAT_P_F_IN3P_MASK ((uint8_t) 0x04)
#define STAT_P_F_IN2P_MASK ((uint8_t) 0x02)
#define STAT_P_F_IN1P_MASK ((uint8_t) 0x01)
/* Register 0x04 (STAT_N) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | F_IN4N | F_IN3N | F_IN2N | F_IN1N |
* -------------------------------------------------------------------------------------------------
*/
/* STAT_N register address */
#define STAT_N_ADDRESS ((uint8_t) 0x04)
/* STAT_N default (reset) value */
#define STAT_N_DEFAULT ((uint8_t) 0x00)
/* STAT_N register field masks */
#define STAT_N_F_IN4N_MASK ((uint8_t) 0x08)
#define STAT_N_F_IN3N_MASK ((uint8_t) 0x04)
#define STAT_N_F_IN2N_MASK ((uint8_t) 0x02)
#define STAT_N_F_IN1N_MASK ((uint8_t) 0x01)
/* Register 0x05 (STAT_S) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | F_STARTUP | F_CS | F_FRAME |
* -------------------------------------------------------------------------------------------------
*/
/* STAT_S register address */
#define STAT_S_ADDRESS ((uint8_t) 0x05)
/* STAT_S default (reset) value */
#define STAT_S_DEFAULT ((uint8_t) 0x00)
/* STAT_S register field masks */
#define STAT_S_F_STARTUP_MASK ((uint8_t) 0x04)
#define STAT_S_F_CS_MASK ((uint8_t) 0x02)
#define STAT_S_F_FRAME_MASK ((uint8_t) 0x01)
/* Register 0x06 (ERROR_CNT) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | ER[7:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ERROR_CNT register address */
#define ERROR_CNT_ADDRESS ((uint8_t) 0x06)
/* ERROR_CNT default (reset) value */
#define ERROR_CNT_DEFAULT ((uint8_t) 0x00)
/* ERROR_CNT register field masks */
#define ERROR_CNT_ER_MASK ((uint8_t) 0xFF)
/* Register 0x07 (STAT_M2) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | M2PIN[1:0] | M1PIN[1:0] | M0PIN[1:0] |
* -------------------------------------------------------------------------------------------------
*/
/* STAT_M2 register address */
#define STAT_M2_ADDRESS ((uint8_t) 0x07)
/* STAT_M2 default (reset) value */
#define STAT_M2_DEFAULT ((uint8_t) 0x00)
#define STAT_M2_DEFAULT_MASK ((uint8_t) 0xC0)
/* STAT_M2 register field masks */
#define STAT_M2_M2PIN_MASK ((uint8_t) 0x30)
#define STAT_M2_M1PIN_MASK ((uint8_t) 0x0C)
#define STAT_M2_M0PIN_MASK ((uint8_t) 0x03)
/* M2PIN field values */
#define STAT_M2_M2PIN_M2_HAMMING_OFF ((uint8_t) 0x00)
#define STAT_M2_M2PIN_M2_HAMMING_ON ((uint8_t) 0x10)
#define STAT_M2_M2PIN_M2_NC ((uint8_t) 0x20)
/* M1PIN field values */
#define STAT_M2_M1PIN_M1_24BIT ((uint8_t) 0x00)
#define STAT_M2_M1PIN_M1_32BIT ((uint8_t) 0x04)
#define STAT_M2_M1PIN_M1_16BIT ((uint8_t) 0x08)
/* M0PIN field values */
#define STAT_M2_M0PIN_M0_SYNC_MASTER ((uint8_t) 0x00)
#define STAT_M2_M0PIN_M0_ASYNC_SLAVE ((uint8_t) 0x01)
#define STAT_M2_M0PIN_M0_SYNC_SLAVE ((uint8_t) 0x02)
/* Register 0x08 (RESERVED0) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
* -------------------------------------------------------------------------------------------------
*/
/* Register 0x09 (RESERVED1) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
* -------------------------------------------------------------------------------------------------
*/
/* Register 0x0A (RESERVED2) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
* -------------------------------------------------------------------------------------------------
*/
/* Register 0x0B (A_SYS_CFG) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | VNCPEN | HRM | 0 | VREF_4V | INT_REFEN | COMP_TH[2:0] |
* -------------------------------------------------------------------------------------------------
*/
/* A_SYS_CFG register address */
#define A_SYS_CFG_ADDRESS ((uint8_t) 0x0B)
/* A_SYS_CFG default (reset) value */
#define A_SYS_CFG_DEFAULT ((uint8_t) 0x60)
/* A_SYS_CFG register field masks */
#define A_SYS_CFG_VNCPEN_MASK ((uint8_t) 0x80)
#define A_SYS_CFG_HRM_MASK ((uint8_t) 0x40)
#define A_SYS_CFG_VREF_4V_MASK ((uint8_t) 0x10)
#define A_SYS_CFG_INT_REFEN_MASK ((uint8_t) 0x08)
#define A_SYS_CFG_COMP_TH_MASK ((uint8_t) 0x07)
/* COMP_TH field values */
#define A_SYS_CFG_COMP_TH_HIGH_95_LOW_5 ((uint8_t) 0x00)
#define A_SYS_CFG_COMP_TH_HIGH_92p5_LOW_7p5 ((uint8_t) 0x01)
#define A_SYS_CFG_COMP_TH_HIGH_90_LOW_10 ((uint8_t) 0x02)
#define A_SYS_CFG_COMP_TH_HIGH_87p5_LOW_12p5 ((uint8_t) 0x03)
#define A_SYS_CFG_COMP_TH_HIGH_85_LOW_15 ((uint8_t) 0x04)
#define A_SYS_CFG_COMP_TH_HIGH_80_LOW_20 ((uint8_t) 0x05)
#define A_SYS_CFG_COMP_TH_HIGH_75_LOW_25 ((uint8_t) 0x06)
#define A_SYS_CFG_COMP_TH_HIGH_70_LOW_30 ((uint8_t) 0x07)
/* Register 0x0C (D_SYS_CFG) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | WDT_EN | CRC_MODE | DNDLY[1:0] | HIZDLY[1:0] | FIXED | CRC_EN |
* -------------------------------------------------------------------------------------------------
*/
/* D_SYS_CFG register address */
#define D_SYS_CFG_ADDRESS ((uint8_t) 0x0C)
/* D_SYS_CFG default (reset) value */
#define D_SYS_CFG_DEFAULT ((uint8_t) 0x3C)
/* D_SYS_CFG register field masks */
#define D_SYS_CFG_WDT_EN_MASK ((uint8_t) 0x80)
#define D_SYS_CFG_CRC_MODE_MASK ((uint8_t) 0x40)
#define D_SYS_CFG_DNDLY_MASK ((uint8_t) 0x30)
#define D_SYS_CFG_HIZDLY_MASK ((uint8_t) 0x0C)
#define D_SYS_CFG_FIXED_MASK ((uint8_t) 0x02)
#define D_SYS_CFG_CRC_EN_MASK ((uint8_t) 0x01)
/* DNDLY field values */
#define D_SYS_CFG_DNDLY_6ns ((uint8_t) 0x00)
#define D_SYS_CFG_DNDLY_8ns ((uint8_t) 0x10)
#define D_SYS_CFG_DNDLY_10ns ((uint8_t) 0x20)
#define D_SYS_CFG_DNDLY_12ns ((uint8_t) 0x30)
/* HIZDLY field values */
#define D_SYS_CFG_HIZDLY_6ns ((uint8_t) 0x00)
#define D_SYS_CFG_HIZDLY_8ns ((uint8_t) 0x04)
#define D_SYS_CFG_HIZDLY_10ns ((uint8_t) 0x08)
#define D_SYS_CFG_HIZDLY_12ns ((uint8_t) 0x0C)
/* Register 0x0D (CLK1) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | CLKSRC | 0 | 0 | 0 | CLK_DIV[2:0] | 0 |
* -------------------------------------------------------------------------------------------------
*/
/* CLK1 register address */
#define CLK1_ADDRESS ((uint8_t) 0x0D)
/* CLK1 default (reset) value */
#define CLK1_DEFAULT ((uint8_t) 0x08)
/* CLK1 register field masks */
#define CLK1_CLKSRC_MASK ((uint8_t) 0x80)
#define CLK1_CLK_DIV_MASK ((uint8_t) 0x0E)
/* CLK_DIV field values */
#define CLK1_CLK_DIV_2 ((uint8_t) 0x02)
#define CLK1_CLK_DIV_4 ((uint8_t) 0x04)
#define CLK1_CLK_DIV_6 ((uint8_t) 0x06)
#define CLK1_CLK_DIV_8 ((uint8_t) 0x08)
#define CLK1_CLK_DIV_10 ((uint8_t) 0x0A)
#define CLK1_CLK_DIV_12 ((uint8_t) 0x0C)
#define CLK1_CLK_DIV_14 ((uint8_t) 0x0E)
/* Register 0x0E (CLK2) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | ICLK_DIV[2:0] | 0 | OSR[3:0] |
* -------------------------------------------------------------------------------------------------
*/
/* CLK2 register address */
#define CLK2_ADDRESS ((uint8_t) 0x0E)
/* CLK2 default (reset) value */
#define CLK2_DEFAULT ((uint8_t) 0x86)
/* CLK2 register field masks */
#define CLK2_ICLK_DIV_MASK ((uint8_t) 0xE0)
#define CLK2_OSR_MASK ((uint8_t) 0x0F)
/* ICLK_DIV field values */
#define CLK2_ICLK_DIV_2 ((uint8_t) 0x20)
#define CLK2_ICLK_DIV_4 ((uint8_t) 0x40)
#define CLK2_ICLK_DIV_6 ((uint8_t) 0x60)
#define CLK2_ICLK_DIV_8 ((uint8_t) 0x80)
#define CLK2_ICLK_DIV_10 ((uint8_t) 0xA0)
#define CLK2_ICLK_DIV_12 ((uint8_t) 0xC0)
#define CLK2_ICLK_DIV_14 ((uint8_t) 0xE0)
/* OSR field values */
#define CLK2_OSR_4096 ((uint8_t) 0x00)
#define CLK2_OSR_2048 ((uint8_t) 0x01)
#define CLK2_OSR_1024 ((uint8_t) 0x02)
#define CLK2_OSR_800 ((uint8_t) 0x03)
#define CLK2_OSR_768 ((uint8_t) 0x04)
#define CLK2_OSR_512 ((uint8_t) 0x05)
#define CLK2_OSR_400 ((uint8_t) 0x06)
#define CLK2_OSR_384 ((uint8_t) 0x07)
#define CLK2_OSR_256 ((uint8_t) 0x08)
#define CLK2_OSR_200 ((uint8_t) 0x09)
#define CLK2_OSR_192 ((uint8_t) 0x0A)
#define CLK2_OSR_128 ((uint8_t) 0x0B)
#define CLK2_OSR_96 ((uint8_t) 0x0C)
#define CLK2_OSR_64 ((uint8_t) 0x0D)
#define CLK2_OSR_48 ((uint8_t) 0x0E)
#define CLK2_OSR_32 ((uint8_t) 0x0F)
/* Register 0x0F (ADC_ENA) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | ENA[3:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ADC_ENA register address */
#define ADC_ENA_ADDRESS ((uint8_t) 0x0F)
/* ADC_ENA default (reset) value */
#define ADC_ENA_DEFAULT ((uint8_t) 0x00)
/* ADC_ENA register field masks */
#define ADC_ENA_ENA_MASK ((uint8_t) 0x0F)
/* ENA field values */
#define ADC_ENA_ENA_ALL_CH_PWDN ((uint8_t) 0x00)
#define ADC_ENA_ENA_ALL_CH_PWUP ((uint8_t) 0x0F)
/* Register 0x10 (RESERVED3) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
* -------------------------------------------------------------------------------------------------
*/
/* Register 0x11 (ADC1) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | GAIN1[2:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ADC1 register address */
#define ADC1_ADDRESS ((uint8_t) 0x11)
/* ADC1 default (reset) value */
#define ADC1_DEFAULT ((uint8_t) 0x00)
/* ADC1 register field masks */
#define ADC1_GAIN1_MASK ((uint8_t) 0x07)
/* GAIN1 field values */
#define ADC1_GAIN1_1 ((uint8_t) 0x00)
#define ADC1_GAIN1_2 ((uint8_t) 0x01)
#define ADC1_GAIN1_4 ((uint8_t) 0x02)
#define ADC1_GAIN1_8 ((uint8_t) 0x03)
#define ADC1_GAIN1_16 ((uint8_t) 0x04)
/* Register 0x12 (ADC2) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | GAIN2[2:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ADC2 register address */
#define ADC2_ADDRESS ((uint8_t) 0x12)
/* ADC2 default (reset) value */
#define ADC2_DEFAULT ((uint8_t) 0x00)
/* ADC2 register field masks */
#define ADC2_GAIN2_MASK ((uint8_t) 0x07)
/* GAIN2 field values */
#define ADC2_GAIN2_1 ((uint8_t) 0x00)
#define ADC2_GAIN2_2 ((uint8_t) 0x01)
#define ADC2_GAIN2_4 ((uint8_t) 0x02)
#define ADC2_GAIN2_8 ((uint8_t) 0x03)
#define ADC2_GAIN2_16 ((uint8_t) 0x04)
/* Register 0x13 (ADC3) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | GAIN3[2:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ADC3 register address */
#define ADC3_ADDRESS ((uint8_t) 0x13)
/* ADC3 default (reset) value */
#define ADC3_DEFAULT ((uint8_t) 0x00)
/* ADC3 register field masks */
#define ADC3_GAIN3_MASK ((uint8_t) 0x07)
/* GAIN3 field values */
#define ADC3_GAIN3_1 ((uint8_t) 0x00)
#define ADC3_GAIN3_2 ((uint8_t) 0x01)
#define ADC3_GAIN3_4 ((uint8_t) 0x02)
#define ADC3_GAIN3_8 ((uint8_t) 0x03)
#define ADC3_GAIN3_16 ((uint8_t) 0x04)
/* Register 0x14 (ADC4) definition
* -------------------------------------------------------------------------------------------------
* | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
* -------------------------------------------------------------------------------------------------
* | 0 | 0 | 0 | 0 | 0 | GAIN4[2:0] |
* -------------------------------------------------------------------------------------------------
*/
/* ADC4 register address */
#define ADC4_ADDRESS ((uint8_t) 0x14)
/* ADC4 default (reset) value */
#define ADC4_DEFAULT ((uint8_t) 0x00)
/* ADC4 register field masks */
#define ADC4_GAIN4_MASK ((uint8_t) 0x07)
/* GAIN4 field values */
#define ADC4_GAIN4_1 ((uint8_t) 0x00)
#define ADC4_GAIN4_2 ((uint8_t) 0x01)
#define ADC4_GAIN4_4 ((uint8_t) 0x02)
#define ADC4_GAIN4_8 ((uint8_t) 0x03)
#define ADC4_GAIN4_16 ((uint8_t) 0x04)
//****************************************************************************
//
// Register settings macros
//
//****************************************************************************
// NOTE: These macros can be used in logical expressions for checking known register values.
// These macros will take on the value from the last register read/write operation, or the
// default register value if no register operations have occurred or the device is reset.
#define CRC_EN ((bool) (getRegisterValue(D_SYS_CFG_ADDRESS) & D_SYS_CFG_CRC_EN_MASK))
#define CRC_MODE ((bool) (getRegisterValue(D_SYS_CFG_ADDRESS) & D_SYS_CFG_CRC_MODE_MASK))
#define FIXED ((bool) (getRegisterValue(D_SYS_CFG_ADDRESS) & D_SYS_CFG_FIXED_MASK))
#endif /* ADS131A04_H_ */