The data sheet indicates that both Ch1 & Ch2 may be used for RLD. But we can only use Ch2 with an unexpected configuration for the RLD to work.
Can you explain why Ch1 RLD does not output the the 1.65 VDC as expected?
Our SW configuration & HW schematic is attached for your reference.
(We use a TIVA129X family MCU to configure the ADS using a SPI interface. CCS version 6.1.4. The ECG chip uses a dedicated, and isolated power supply.)
Thank you for your help,
Fred
ECG_CommStatusType ConfigECGChip(void)
{
uint32_t wait;
ECG_CommStatusType retVal;
uint8_t tempByte;
// -----------------------------------------
// RESET Command
// Our signal is provided by the CPU
// The PWDN/RESET signal start low at power up and is then asserted high by the CPU output pin sometime after power up.
// It remains high for 1.29 Sec during initialization followed by a 10 uS (18 TClks) reset pulse.
// the signal recalled at anytime, reset the chip via a cmd as well.
// Reset all registers to default values before changing anything.
// -----------------------------------------
SendECGCommand(ECG_RESET);
for (wait= 0; wait < _9US_COUNTS; wait++) ; // It takes 9xFmod cycles (70.3 uS) for the RESET cmd to complete. >>FA Measure wait
// Wait added here for testing only.
// -----------------------------------------
// Send STOP CONTINOUS Mode Command
// ADS1292R device wakes up in the continuous mode.
// We must stop the continuous mode so the registers can be written
// -----------------------------------------
SendECGCommand(ECG_SDATAC);
for (wait= 0; wait < _9US_COUNTS; wait++) ; // Must wait 4xTclk cycles (31.25 uS) for the cmd to complete.
// Wait 18 TClks (~8.8 uS given our 2.048 MHz clk)
// -----------------------------------------
// Read the REG_ID
// -----------------------------------------
ReadOneECGRegister(ECG_REG_ID, &tempByte);
if (tempByte != EXPECTED_ECG_ID)
{
System_printf ("Invalid ADS1292R chip! ID is: %01x. Expected %01x. \n", tempByte, EXPECTED_ECG_ID);
System_flush();
return INVALID_DEVICE_ID;
}
for (wait= 0; wait < _9US_COUNTS; wait++) ;
// -----------------------------------------
// Write the ECG_REG_LOFF_CONTROL register
// Set to all default values
// -----------------------------------------
WriteECGRegister(ECG_REG_LOFF, 0x10);
for (wait= 0; wait < _9US_COUNTS; wait++) ;
// -----------------------------------------
// Write the CONFIG 2 register
// -----------------------------------------
WriteECGRegister( ECG_REG_CONFIG2, ECG_CONFIG2_NORMAL);
for (wait= 0; wait < _9US_COUNTS; wait++) ; // Wait for the reference to settle. Data sheet does not identify what the min wait time should be.
// -----------------------------------------
// Write the CONFIG 1 register
// -----------------------------------------
WriteECGRegister( ECG_REG_CONFIG1, ECG_CONFIG1_NORMAL);
for (wait= 0; wait < _9US_COUNTS; wait++) ;
// -----------------------------------------
// Write the ECG_REG_LOFF_STAT register
// Set the clock divider for 2.048 MHz clock per sequence specification
// -----------------------------------------
WriteECGRegister(ECG_REG_LOFF_STAT, LOFF_CONFIG);
for (wait= 0; wait < _9US_COUNTS; wait++) ; // Wait 18 TClks (~8.8 uS given our 2.048 MHz clk)
// -----------------------------------------
// Configure channel 1
// -----------------------------------------
WriteECGRegister(ECG_REG_CH1SET, ECG_CH_NORMAL);
for (wait= 0; wait < _9US_COUNTS; wait++) ; // Wait 18 TClks (~8.8 uS given our 2.048 MHz clk)
// -----------------------------------------
// Configure Channel 2
//WriteECGRegister(ECG_REG_CH2SET, ECG_CH_RLD); // This does not work. Why?
WriteECGRegister(ECG_REG_CH2SET, ECG_CH_DRPM);
//WriteECGRegister(ECG_REG_CH2SET, ECG_CHAN_SET_PWR_DOWN);
for (wait= 0; wait < _9US_COUNTS; wait++);
// -----------------------------------------
// Configure RLD output related registers:
// -----------------------------------------
WriteECGRegister(ECG_REG_RLD_SENS, RLD_SENS_USE_CH2);
WriteECGRegister(ECG_REG_RESP2, RESP2_INTERNAL_REF);
// -----------------------------------------
// Send the Start command
// -----------------------------------------
SendECGCommand(ECG_START);
for (wait= 0; wait < _9US_COUNTS; wait++) ;
return ECG_COMM_SUCCESS;
}
///////////////////////////////////////////////////////////////
// The relevant header file contents:
typedef enum
{
// System Commands
ECG_WAKEUP = 0x02, // Wake up from standby mode
ECG_STANDBY = 0x04, // Enter standby mode
ECG_RESET = 0x06, // Reset the registers of the device to default values
ECG_START = 0x08, // Start / Restart (synchronized) conversions
ECG_STOP = 0x0A, // Stop Conversions
ECG_OFFSETCAL = 0x1A, // Channel offset calibration
// Data Read Commands
ECG_RDATAC = 0x10, // Enable Read Data continuous mode
ECG_SDATAC = 0x11, // Stop Read Data Continuous mode
ECG_RDATA = 0x12, // Read data by command
// Register Read / Write Commands. Note that these are 2 byte commands.
// The second byte's lowest 5 bits contains the # of registers to R/W -1.
// So to read 3 registers, the second byte should contain a 0x02.
ECG_RREG = 0x20, // Read Register: The least 5 significant bits are the starting register's address to read from
ECG_WREG = 0x40 // Write Register: The least 5 significant bits are the starting register's address to write to
} ECG_CMD;
typedef enum
{
// Device Settings (READ ONLY REGs)
ECG_REG_ID = 0x00, // Reg ID Control Register: Factory programmed, Read only register
// Global settings accross channels
ECG_REG_CONFIG1 = 0x01, // Configuration 1 Reg
ECG_REG_CONFIG2 = 0x02, // Configuration 1 Reg
ECG_REG_LOFF = 0x03, // Lead-Off Control Reg
//Channel-specific settings
ECG_REG_CH1SET = 0x04, // Channel 1 Settings
ECG_REG_CH2SET = 0x05, // Channel 2 Settings
ECG_REG_RLD_SENS = 0x06, // Right Leg Drive Sense Selection
ECG_REG_LOFF_SENS = 0x07, // Lead-Off Sense Selection
ECG_REG_LOFF_STAT = 0x08, // Lead-Off Sense Status
// GPIO and other Registers
ECG_REG_RESP1 = 0x09, // Respiration Control Register 1
ECG_REG_RESP2 = 0x0A, // Respiration Control Register 1
ECG_REG_GPIO = 0x0B, // General Purpose I/O Register
ECG_REG_COUNT = 0x0C // Reg Count
} ECG_REG_MAP;
// Config2 register: Configures ADC sample rate & mode (continuous / one shot)
typedef enum
{
// Bits 0 - 2 are used for oversampling ratio for both channels 1 & 2
// fMod (128 KHz) / one of these #s. (Ex /64 = 128K / 64 = 2KHz ECG sampling)
ECG_CONFIG1_DIVBY_1024 = 0x00,
ECG_CONFIG1_DIVBY_512 = 0x01,
ECG_CONFIG1_DIVBY_256 = 0x02,
ECG_CONFIG1_DIVBY_128 = 0x03,
ECG_CONFIG1_DIVBY_64 = 0x04,
ECG_CONFIG1_DIVBY_32 = 0x05,
ECG_CONFIG1_DIVBY_16 = 0x06,
// Bits 6-3 are constants, and must be set to 0
ECG_CONFIG1_CONSTANT = 0x00,
// Bit 7
ECG_CONFIG1_SINGLE_SHOT = 0x80,
ECG_CONFIG1_CONTINUOUS = 0x00
} ECG_CONFIG1_REG;
#define ECG_CONFIG1_NORMAL (ECG_CONFIG1_DIVBY_64 + ECG_CONFIG1_CONTINUOUS)
// Config2 register: Configures the TEST signal, CLK, reference and LOFF buffer
typedef enum
{
// Bit 7 must always be set high & BIT2: Must always be set to 0
ECG_CONFIG2_CONSTANT = 0x80,
// Bit 6: PDB_LOFF_COMP
ECG_CONFIG2_PDB_LOFF_COMP_ENABLED = 0x40,
// BIT5: PDB_REFBUF
ECG_CONFIG2_PDB_REFBUF_ON = 0x20,
// BIT4: VREF)2.42V or 4.033V. We can only have a 2.42 reference since the 4 V ref requires a 5VDC supply
//ECG_CONFIG2_VREF_4033 = 0x10,
// BIT 3: CLK_EN internal Osc is not used in our design. Only external Osc is used
// BIT1: TEST signal
ECG_CONFIG2_TEST_ON = 0x02,
// BIT 0: TEST_FREQ: DC / 1Hz
ECG_CONFIG2_TEST_FREQ_1HZ = 0x01
}ECG_CONFIG2_REG;
#define ECG_CONFIG2_TEST (ECG_CONFIG2_CONSTANT | ECG_CONFIG2_PDB_REFBUF_ON | ECG_CONFIG2_TEST_ON | ECG_CONFIG2_TEST_FREQ_1HZ)
#define ECG_CONFIG2_NORMAL (ECG_CONFIG2_CONSTANT | ECG_CONFIG2_PDB_REFBUF_ON /*| ECG_CONFIG2_PDB_LOFF_COMP_ENABLED*/)
typedef enum
{
// Bit 7: Channel power up / down
ECG_CHAN_SET_PWR_DOWN = 0x80,
ECG_CHAN_SET_PWR_UP = 0x00,
// BITS 6-4: GAIN
ECG_CHAN_SET_GAIN_6 = 0x00, //Default
ECG_CHAN_SET_GAIN_1 = 0x10,
ECG_CHAN_SET_GAIN_2 = 0x20,
ECG_CHAN_SET_GAIN_3 = 0x30,
ECG_CHAN_SET_GAIN_4 = 0x40,
ECG_CHAN_SET_GAIN_8 = 0x50,
ECG_CHAN_SET_GAIN_12 = 0x60,
// BITS 3:0 Channel input selection
ECG_CHAN_SET_INPUT_NORMAL = 0x00,
ECG_CHAN_SET_INPUT_SHORTED = 0x01,
ECG_CHAN_SET_INPUT_RLD = 0x02,
ECG_CHAN_SET_INPUT_MVDD = 0x03,
ECG_CHAN_SET_INPUT_TEMP = 0x04,
ECG_CHAN_SET_INPUT_TEST = 0x05,
ECG_CHAN_SET_INPUT_RLD_DRP = 0x06,
ECG_CHAN_SET_INPUT_RLD_DRM = 0x07,
ECG_CHAN_SET_INPUT_RLD_DRPM = 0x08,
ECG_CHAN_SET_INPUT_ROUTE_IN3 = 0x09
}ECG_CHAN_SETTINGS_REG;
#define ECG_CH_OFF (ECG_CHAN_SET_PWR_DOWN + ECG_CHAN_SET_INPUT_SHORTED)
#define ECG_CH_DRP (ECG_CHAN_SET_INPUT_RLD_DRP)
#define ECG_CH_RLD (ECG_CHAN_SET_PWR_UP |ECG_CHAN_SET_INPUT_RLD)
#define ECG_CH_DRM (ECG_CHAN_SET_INPUT_RLD_DRM)
#define ECG_CH_DRPM (ECG_CHAN_SET_PWR_UP |ECG_CHAN_SET_INPUT_RLD_DRPM)
#define ECG_CH_NORMAL (ECG_CHAN_SET_PWR_UP | ECG_CHAN_SET_GAIN_1)
typedef enum
{
// Bits 7 & 6: Chop Freq
ECG_RLD_SENS_CF_DIV_16 = 0x00,
ECG_RLD_SENS_CF_RES = 0x40,
ECG_RLD_SENS_CF_DIV_2 = 0x80,
ECG_RLD_SENS_CF_DIV_4 = 0xC0,
// Bit 5: Buffer Power
ECG_RLD_SENS_PDB_RLD_EN = 0x20,
// Bit 4: RLD_LOFF_SENSE
ECG_RLD_SENS_RLD_LOFF_SENSE_EN = 0x10,
// Bit 3: RLD2N Ch2 RLD neg inputs
ECG_RLD_SENS_RLD2N_CONNECTED = 0x08,
// Bit 2: RLD2P Ch2 RLD pos inputs
ECG_RLD_SENS_RLD2P_CONNECTED = 0x04,
// Bit 1: RLD1N Ch1 RLD neg inputs
ECG_RLD_SENS_RLD1N_CONNECTED = 0x02,
// Bit 0: RLD1P Ch1 RLD pos inputs
ECG_RLD_SENS_RLD1P_CONNECTED = 0x01
}ECG_RLD_SENS_REG;
#define RLD_SENS_USE_CH2 (ECG_RLD_SENS_PDB_RLD_EN | ECG_RLD_SENS_RLD2N_CONNECTED | ECG_RLD_SENS_RLD2P_CONNECTED)
#define RLD_SENS_USE_CH1 (ECG_RLD_SENS_PDB_RLD_EN | ECG_RLD_SENS_RLD1N_CONNECTED | ECG_RLD_SENS_RLD1P_CONNECTED)
#define RLD_SENS_USE_BOTH_CHS (ECG_RLD_SENS_PDB_RLD_EN | ECG_RLD_SENS_RLD1N_CONNECTED | ECG_RLD_SENS_RLD1P_CONNECTED | ECG_RLD_SENS_RLD2N_CONNECTED | ECG_RLD_SENS_RLD2P_CONNECTED)
typedef enum
{
// Bits 7 & 5: Constant must be 0
ECG_LOFF_STAT_CONSTANT = 0x00,
// Bit 6: CLK_DIV
ECG_LOFF_STAT_CLK_DIV_2048KHZ = 0x40, // Our HW provided external Osc.
// Bit 4: RLD_STAT
ECG_LOFF_STAT_RLD_DISCONNECTED = 0x20,
// Bit 3 IN2N_OFF (Input 2 Negative electrode connection status)
ECG_LOFF_STAT_IN2N_DISCONNECTED = 0x08,
// Bit 3 IN2P_OFF (Input 2 Positive electrode connection status)
ECG_LOFF_STAT_IN2P_DISCONNECTED = 0x04,
// Bit 3 IN2N_OFF (Input 1 Negative electrode connection status)
ECG_LOFF_STAT_IN1N_DISCONNECTED = 0x02,
// Bit 3 IN2N_OFF (Input 1 Positive electrode connection status)
ECG_LOFF_STAT_IN1P_DISCONNECTED = 0x01
}ECG_LOFF_STATUS_REG;
#define LOFF_CONFIG (ECG_LOFF_STAT_CLK_DIV_2048KHZ + ECG_LOFF_STAT_IN2N_DISCONNECTED + ECG_LOFF_STAT_IN2P_DISCONNECTED)
/*
// Register not configured
typedef enum
{
// Bits 7 Demo Demodulation Enable
ECG_RESP1_DEMO_EN1 = 0x80,
// Bit 6: Demo Modulation Enable
ECG_RESP1_DEMO_EN = 0x40,
// Bits 5- 2 Respiration phase
ECG_RESP1_PHASE = 0x00,
// Bit 1:
ECG_RESP1_CONSTANT = 0x02,
// Bit 0: External Clock
ECG_RESP1_EXT_CLK = 0x01
}ECG_REG_RESP1_REG;
#define TEST_RESP1_CONFIG (ECG_RESP1_CONSTANT | ECG_RESP1_DEMO_EN1 | ECG_RESP1_DEMO_EN)
*/
typedef enum
{
// Bits 7 Calibration on
ECG_RESP2_CALIB_ON = 0x80,
// Bit 6 -3 Must be 0s.
// Bit 2:
ECG_RESP2_RESP_FREQ_64KHZ = 0x04,
ECG_RESP2_RESP_FREQ_32KHZ = 0X00,
// Bits 1:RLD_REF_INT Internal or externally generated RLD ref
ECG_RESP2_RLD_REF_INTERNAL = 0x02,
ECG_RESP2_RLD_REF_EXTERNAL = 0X00,
// bit 0: must be 1
ECG_RESP2_CONSTANT = 0x01,
}ECG_REG_RESP2_REG;
#define RESP2_EXTERNAL_REF (ECG_RESP2_RLD_REF_EXTERNAL | ECG_RESP2_CONSTANT)
#define RESP2_INTERNAL_REF (ECG_RESP2_RLD_REF_INTERNAL | ECG_RESP2_CONSTANT)