Other Parts Discussed in Thread: ADS1296, ADS1294, , ADS1296R, , ADS1294R
Hi there,
Background
Following some changes made in this thread: https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1018492/ads1298-cannot-establish-spi-communications, we've made some progress with the SPI comms.
The voltage lines are stable now after tieing RESV1 to DGND, and we scoped the MOSI and MISO signals and they look ok.
However, we are seeing discrepancies in values for test signal on our design as compared to the dev kit.
The issue
We are trying to baseline the ADSx98 FE Rev C deg kit against our design which is almost identical with a few deviations.
We are attempting to perform an internally generated signal to read values from the internal registers. Below is a header file with more details of the register settings:
#ifndef ADS1298_H
#define ADS1298_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../common.h"
typedef enum {
// system commands
ADS_CMND_WAKEUP = 0x02, // wake-up from standby mode
ADS_CMND_STANDBY = 0x04, // enter standby mode
ADS_CMND_RESET = 0x06, // reset the device registers
ADS_CMND_START = 0x08, // start/restart (synchronize) conversions
ADS_CMND_STOP = 0x0A, // stop conversion
// data read commands
ADS_CMND_RDATAC = 0x10, // enable Read Data Continuous mode.
// - this mode is the default mode at power-up.
ADS_CMND_SDATAC = 0x11, // stop Read Data Continuously mode
ADS_CMND_RDATA = 0x12, // read data by command; supports multiple read back.
// register read/write commands
ADS_CMND_RREG = 0x20, // read n nnnn registers starting at address r rrrr
// - first byte 001r rrrr (2xh)(2) - second byte 000n nnnn(2)
ADS_CMND_WREG = 0x40 // write n nnnn registers starting at address r rrrr
// - first byte 010r rrrr (2xh)(2) - second byte 000n nnnn(2)
} ADS1298Command_t;
typedef enum {
// device settings
ADS_REG_ID = 0x00, // device ID information
// global settings
ADS_REG_CONFIG1 = 0x01,
ADS_REG_CONFIG2 = 0x02,
ADS_REG_CONFIG3 = 0x03,
ADS_REG_LOFF = 0x04,
// channel specific settings
ADS_REG_CH1SET = 0x05,
ADS_REG_CH2SET = 0x06,
ADS_REG_CH3SET = 0x07,
ADS_REG_CH4SET = 0x08,
ADS_REG_CH5SET = 0x09,
ADS_REG_CH6SET = 0x0A,
ADS_REG_CH7SET = 0x0B,
ADS_REG_CH8SET = 0x0C,
ADS_REG_RLD_SENSP = 0x0D,
ADS_REG_RLD_SENSN = 0x0E,
ADS_REG_LOFF_SENSP = 0x0F,
ADS_REG_LOFF_SENSN = 0x10,
ADS_REG_LOFF_FLIP = 0x11,
// lead off status
ADS_REG_LOFF_STATP = 0x12,
ADS_REG_LOFF_STATN = 0x13,
// others
ADS_REG_GPIO = 0x14,
ADS_REG_PACE = 0x15,
ADS_REG_RESP = 0x16,
ADS_REG_CONFIG4 = 0x17,
ADS_REG_WCT1 = 0x18,
ADS_REG_WCT2 = 0x19
} ADS1298Register_t;
typedef enum {
// ID control register bits
DEV_ID7 = 0x80,
DEV_ID6 = 0x40,
DEV_ID5 = 0x20,
DEV_ID2 = 0x04,
DEV_ID1 = 0x02,
DEV_ID0 = 0x01,
ID_ADS129x = DEV_ID7,
ID_ADS129xR = (DEV_ID7 | DEV_ID6),
ID_4CHAN = 0,
ID_6CHAN = DEV_ID0,
ID_8CHAN = DEV_ID1,
ID_ADS1294 = (ID_ADS129x | ID_4CHAN),
ID_ADS1296 = (ID_ADS129x | ID_6CHAN),
ID_ADS1298 = (ID_ADS129x | ID_8CHAN),
ID_ADS1294R = (ID_ADS129xR | ID_4CHAN),
ID_ADS1296R = (ID_ADS129xR | ID_6CHAN),
ID_ADS1298R = (ID_ADS129xR | ID_8CHAN),
ID_const = ID_ADS1298
} ID_bits_t;
typedef enum {
// config1 register bits
HR = 0x80,
DAISY_EN = 0x40,
CLK_EN = 0x20,
DR2 = 0x04,
DR1 = 0x02,
DR0 = 0x01,
// ADS1298
HIGH_RES_32k_SPS = (HR),
HIGH_RES_16k_SPS = (HR | DR0),
HIGH_RES_8k_SPS = (HR | DR1),
HIGH_RES_4k_SPS = (HR | DR1 | DR0),
HIGH_RES_2k_SPS = (HR | DR2),
HIGH_RES_1k_SPS = (HR | DR2 | DR0),
HIGH_RES_500_SPS = (HR | DR2 | DR1),
CONFIG1_const = HIGH_RES_500_SPS
} CONFIG1_bits_t;
typedef enum {
// config2 register bits
WCT_CHOP = 0x20,
INT_TEST = 0x10,
TEST_AMP = 0x04,
TEST_FREQ1 = 0x02,
TEST_FREQ0 = 0x01,
// ADS1298
INT_TEST_4HZ = INT_TEST,
INT_TEST_8HZ = (INT_TEST | TEST_FREQ0),
INT_TEST_DC = (INT_TEST | TEST_FREQ1 | TEST_FREQ0),
CONFIG2_const = INT_TEST_DC
} CONFIG2_bits_t;
typedef enum {
// config3 register bits
PD_REFBUF = 0x80,
Bit7 = 0x40,
VREF_4V = 0x20,
RLD_MEAS = 0x10,
RLDREF_INT = 0x08,
PD_RLD = 0x04,
RLD_LOFF_SENS = 0x02,
RLD_STAT = 0x01,
// ADS1298
CONFIG3_const = PD_REFBUF | RLD_MEAS | RLDREF_INT | PD_RLD | Bit7
} CONFIG3_bits_t;
typedef enum {
// Lead-off control register bits
COMP_TH2 = 0x80,
COMP_TH1 = 0x40,
COMP_TH0 = 0x20,
VLEAD_OFF_EN = 0x10,
ILEAD_OFF1 = 0x08,
ILEAD_OFF0 = 0x04,
FLEAD_OFF1 = 0x02,
FLEAD_OFF0 = 0x01,
// ADS1298
LOFF_const = FLEAD_OFF1 | FLEAD_OFF0
} LOFF_bits_t;
typedef enum {
// n-th channel setting register bits
PDn = 0x80,
GAINn2 = 0x40,
GAINn1 = 0x20,
GAINn0 = 0x10,
MUXn2 = 0x04,
MUXn1 = 0x02,
MUXn0 = 0x01,
// ADS1298
ADS1298_GAIN_1X = GAINn0,
ADS1298_GAIN_2X = GAINn1,
ADS1298_GAIN_3X = (GAINn1 | GAINn0),
ADS1298_GAIN_4X = GAINn2,
ADS1298_GAIN_6X = 0x00,
ADS1298_GAIN_8X = (GAINn2 | GAINn0),
ADS1298_GAIN_12X = (GAINn2 | GAINn1),
ELECTRODE_INPUT = 0x00,
SHORTED = MUXn0,
RLD_INPUT = MUXn1,
MVDD = (MUXn1 | MUXn0),
TEMP = MUXn2,
TEST_SIGNAL = (MUXn2 | MUXn0),
RLD_DRP = (MUXn2 | MUXn1),
RLD_DRN = (MUXn2 | MUXn1 | MUXn0),
//CHnSET_const = ELECTRODE_INPUT
CHnSET_const = MVDD | ADS1298_GAIN_1X
} CHnSET_bits_t;
typedef enum {
// RLD positive signal derivation register bits
RLD8P = 0x80,
RLD7P = 0x40,
RLD6P = 0x20,
RLD5P = 0x10,
RLD4P = 0x08,
RLD3P = 0x04,
RLD2P = 0x02,
RLD1P = 0x01,
// ADS1298
RLD_SENSP_const = 0x00
} RLD_SENSP_bits_t;
typedef enum {
// RLD negative signal derivation register bits
RLD8N = 0x80,
RLD7N = 0x40,
RLD6N = 0x20,
RLD5N = 0x10,
RLD4N = 0x08,
RLD3N = 0x04,
RLD2N = 0x02,
RLD1N = 0x01,
// ADS1298
RLD_SENSN_const = 0x00
} RLD_SENSN_bits_t;
typedef enum {
// positive signal lead-off detection register bits
LOFF8P = 0x80,
LOFF7P = 0x40,
LOFF6P = 0x20,
LOFF5P = 0x10,
LOFF4P = 0x08,
LOFF3P = 0x04,
LOFF2P = 0x02,
LOFF1P = 0x01,
// ADS1298
LOFF_SENSP_const = 0xFF
} LOFF_SENSP_bits_t;
typedef enum {
// negative signal lead-off detection register bits
LOFF8N = 0x80,
LOFF7N = 0x40,
LOFF6N = 0x20,
LOFF5N = 0x10,
LOFF4N = 0x08,
LOFF3N = 0x04,
LOFF2N = 0x02,
LOFF1N = 0x01,
// ADS1298
LOFF_SENSN_const = 0x02
} LOFF_SENSN_bits_t;
typedef enum {
// lead-off flip register bits
LOFF_FLIP8 = 0x80,
LOFF_FLIP7 = 0x40,
LOFF_FLIP6 = 0x20,
LOFF_FLIP5 = 0x10,
LOFF_FLIP4 = 0x08,
LOFF_FLIP3 = 0x04,
LOFF_FLIP2 = 0x02,
LOFF_FLIP1 = 0x01,
// ADS1298
LOFF_FLIP_const = 0x00
} LOFF_FLIP_bits_t;
typedef enum {
// lead-off positive signal status register bits
IN8P_OFF = 0x80,
IN7P_OFF = 0x40,
IN6P_OFF = 0x20,
IN5P_OFF = 0x10,
IN4P_OFF = 0x08,
IN3P_OFF = 0x04,
IN2P_OFF = 0x02,
IN1P_OFF = 0x01,
// ADS1298
LOFF_STATP_const = 0xFE
} LOFF_STATP_bits_t;
typedef enum {
// lead-off negative signal status register bits
IN8N_OFF = 0x80,
IN7N_OFF = 0x40,
IN6N_OFF = 0x20,
IN5N_OFF = 0x10,
IN4N_OFF = 0x08,
IN3N_OFF = 0x04,
IN2N_OFF = 0x02,
IN1N_OFF = 0x01,
// ADS1298
LOFF_STATN_const = 0x06
} LOFF_STATN_bits_t;
typedef enum {
// general-purpose I/O register bits
GPIOD4 = 0x80,
GPIOD3 = 0x40,
GPIOD2 = 0x20,
GPIOD1 = 0x10,
GPIOC4 = 0x08,
GPIOC3 = 0x04,
GPIOC2 = 0x02,
GPIOC1 = 0x01,
// ADS1298
GPIO_const = 0x00
} GPIO_bits_t;
typedef enum {
// pace detect register bits
PACEE1 = 0x10,
PACEE0 = 0x08,
PACEO1 = 0x04,
PACEO0 = 0x02,
PD_PACE = 0x01,
PACEE_CHAN2 = 0x00,
PACEE_CHAN4 = PACEE0,
PACEE_CHAN6 = PACEE1,
PACEE_CHAN8 = (PACEE1 | PACEE0),
PACEO_CHAN1 = 0x00,
PACEO_CHAN3 = PACEE0,
PACEO_CHAN5 = PACEE1,
PACEO_CHAN7 = (PACEE1 | PACEE0),
// ADS1298
PACE_const = 0x00
} PACE_bits_t;
typedef enum {
// respiration control register bits
RESP_DEMOD_EN1 = 0x80,
RESP_MOD_EN1 = 0x40,
RESP_PH2 = 0x10,
RESP_PH1 = 0x08,
RESP_PH0 = 0x04,
RESP_CTRL1 = 0x02,
RESP_CTRL0 = 0x01,
RESP_PH_22_5 = 0x00,
RESP_PH_45 = RESP_PH0,
RESP_PH_67_5 = RESP_PH1,
RESP_PH_90 = (RESP_PH1 | RESP_PH0),
RESP_PH_112_5 = RESP_PH2,
RESP_PH_135 = (RESP_PH2 | RESP_PH0),
RESP_PH_157_5 = (RESP_PH2 | RESP_PH1),
RESP_NONE = 0x00,
RESP_EXT = RESP_CTRL0,
RESP_INT_SIG_INT = RESP_CTRL1,
RESP_INT_SIG_EXT = (RESP_CTRL1 | RESP_CTRL0),
// ADS1298 (not support)
RESP_const = 0x00
} RESP_bits_t;
typedef enum {
// configuration register 4 bits
RESP_FREQ2 = 0x80,
RESP_FREQ1 = 0x40,
RESP_FREQ0 = 0x20,
SINGLE_SHOT = 0x08,
WCT_TO_RLD = 0x04,
PD_LOFF_COMP = 0x02,
RESP_FREQ_64k_Hz = 0x00,
RESP_FREQ_32k_Hz = RESP_FREQ0,
RESP_FREQ_16k_Hz = RESP_FREQ1,
RESP_FREQ_8k_Hz = (RESP_FREQ1 | RESP_FREQ0),
RESP_FREQ_4k_Hz = RESP_FREQ2,
RESP_FREQ_2k_Hz = (RESP_FREQ2 | RESP_FREQ0),
RESP_FREQ_1k_Hz = (RESP_FREQ2 | RESP_FREQ1),
RESP_FREQ_500_Hz = (RESP_FREQ2 | RESP_FREQ1 | RESP_FREQ0),
// ADS1298
CONFIG4_const = PD_LOFF_COMP
} CONFIG4_bits_t;
typedef enum {
// WCT1: wilson central terminal and augmented lead control register bits
aVF_CH6 = 0x80,
aVL_CH5 = 0x40,
aVR_CH7 = 0x20,
avR_CH4 = 0x10,
PD_WCTA = 0x08,
WCTA2 = 0x04,
WCTA1 = 0x02,
WCTA0 = 0x01,
WCTA_CH1P = 0x00,
WCTA_CH1N = WCTA0,
WCTA_CH2P = WCTA1,
WCTA_CH2N = (WCTA1 | WCTA0),
WCTA_CH3P = WCTA2,
WCTA_CH3N = (WCTA2 | WCTA0),
WCTA_CH4P = (WCTA2 | WCTA1),
WCTA_CH4N = (WCTA2 | WCTA1 | WCTA0),
// ADS1298
WCT1_const = PD_WCTA | WCTA1
} WCT1_bits_t;
typedef enum {
// WCT2: wilson central terminal control register bits
PD_WCTC = 0x80,
PD_WCTB = 0x40,
WCTB2 = 0x20,
WCTB1 = 0x10,
WCTB0 = 0x08,
WCTC2 = 0x04,
WCTC1 = 0x02,
WCTC0 = 0x01,
WCTB_CH1P = 0x00,
WCTB_CH1N = WCTB0,
WCTB_CH2P = WCTB1,
WCTB_CH2N = (WCTB1 | WCTB0),
WCTB_CH3P = WCTB2,
WCTB_CH3N = (WCTB2 | WCTB0),
WCTB_CH4P = (WCTB2 | WCTB1),
WCTB_CH4N = (WCTB2 | WCTB1 | WCTB0),
WCTC_CH1P = 0x00,
WCTC_CH1N = WCTC0,
WCTC_CH2P = WCTC1,
WCTC_CH2N = (WCTC1 | WCTC0),
WCTC_CH3P = WCTC2,
WCTC_CH3N = (WCTC2 | WCTC0),
WCTC_CH4P = (WCTC2 | WCTC1),
WCTC_CH4N = (WCTC2 | WCTC1 | WCTC0),
// ADS1298
WCT2_const = PD_WCTC | PD_WCTB | WCTB_CH3P | WCTC_CH2N
} WCT2_bits_t;
#ifdef __cplusplus
}
#endif
#endif // ADS1298_H
The issue is that there is a deviation in voltage measurements between the two setups in general. Below is a summary table of voltages measured between the two setups:
Channel No. | ADS1298 DevKit & GUI SW (mV) | Custom Design (mV) |
1 | -1.588392 | -1.237154154 |
2 | -0.723791122 | -1.197433614 |
3 | -1.223898 | -1.365900203 |
4 | -1.398134 | -1.233053354 |
5 | -1.174879 | -0.781917665 |
6 | -1.245832 | 350.5889834 |
7 | -1.276207 | -79.24800864 |
8 | -0.989675522 | -76.67232474 |
There also seems to be a large fluctuation in values read in our design when measuring the test data on channels 6, 7 and 8. All voltage measurements on all channels read on the dev kit via GUI are stable. Are there any hardware connection dependencies to perform this test?
Looking forward to some suggestions and/or troubleshooting steps.
Thank you in advance.
Best regards,
Eric