Priliminary

Dependencies:   DS1307 MAX17048 MODSERIAL SSD1308_128x64_I2C WatchDog mbed-rpc mbed

Fork of ECGAFE_copy by Zainul Charbiwala

ADS1298.cpp

Committer:
zainulcharbiwala
Date:
2015-09-30
Revision:
0:ee0649a9025a

File content as of revision 0:ee0649a9025a:

#include "ADS1298.h"


ADS1298::ADS1298(PinName mosi, 
                     PinName miso, 
                     PinName sck, 
                     PinName csn,
                     PinName reset,
                     PinName drdy,
                     PinName start) : spi_(mosi, miso, sck), cs_(csn), reset_(reset), drdy_(drdy), start_(start) {
}

void ADS1298::sendCommand(uint8_t cmd)
{
    // Select the device by seting chip select low
    cs_ = 0;
    wait_us(TCSSC);
 
    // Send SDATAC, as device comes up in RDATAC
    spi_.write(cmd);
    wait_us(TCMD);
 
    // Deselect the device
    wait_us(TSCCS);
    cs_ = 1;
    // Wait between commands
    wait_us(TCSH);
}

void ADS1298::writeRegister(uint8_t reg, uint8_t val)
{
    // Select the device by seting chip select low
    cs_ = 0;
    wait_us(TCSSC);
 
    // Write register address
    spi_.write(WREG|reg);
    wait_us(TCMD);

    // Writing one register
    spi_.write(0x00);
    wait_us(TCMD);
 
    // Write the value
    spi_.write(val);
    wait_us(TCMD);
 
    // Deselect the device
    wait_us(TSCCS);
    cs_ = 1;

    // Wait between commands
    wait_us(TCSH);
}

uint8_t ADS1298::readRegister(uint8_t reg)
{
    uint8_t res;
    // Select the device by seting chip select low
    cs_ = 0;
    wait_us(TCSSC);
 
    // Write register address
    spi_.write(RREG|reg);
    wait_us(TCMD);

    // Reading one register
    spi_.write(0x00);
    wait_us(TCMD);
 
    // Write a dummy value to read the register
    res = spi_.write(0x00);
    wait_us(TCMD);
 
    // Deselect the device
    wait_us(TSCCS);
    cs_ = 1;

    // Wait between commands
    wait_us(TCSH);
    return res;
}
 
void ADS1298::readData(uint8_t *data)
{
    // Select the device by seting chip select low
    cs_ = 0;
    wait_us(TCSSC);
 
    for (int i=0; i<27; i++) {
        // Write a dummy value to read the register
        *(data+i) = spi_.write(0x00);
    }
    wait_us(TCMD);
 
    // Deselect the device
    wait_us(TSCCS);
    cs_ = 1;

    // Wait between commands
    wait_us(TCSH);
}

void ADS1298::initialize(void (*dataReady)(void))
{
    // Initialize signals
    cs_ = 1;
    start_ = 0;
    reset_ = 1;
    drdy_.fall(dataReady);

    // Set up SPI
    spi_.format(8,1);
    // Choosing 1MHz arbitrarily for now
    spi_.frequency(1000000);


    // Power on reset
    wait_us(TPOR);
    
    // Reset the device
    reset_ = 0;
    wait_us(TRST);
    reset_ = 1;
    wait_us(TRST2);
    
    // Send SDATAC, as device comes up in RDATAC
    sendCommand(SDATAC);

    //pc.printf("ID = 0x%02X\r\n", readRegister(ID));
    //pc.printf("CONFIG1 = 0x%02X\r\n", readRegister(CONFIG1));
    //pc.printf("CONFIG2 = 0x%02X\r\n", readRegister(CONFIG2));
    //pc.printf("CONFIG3 = 0x%02X\r\n", readRegister(CONFIG3));

    // Turn on internal reference and wait for it to settle
    writeRegister(CONFIG3, CONFIG3_DEFAULT | CONFIG3_PD_REFBUF);
    wait_us(TINTREF);
    //pc.printf("CONFIG3 = 0x%02X\r\n", readRegister(CONFIG3));
    
    /*    
    // Set up device
    writeRegister(CONFIG1, CONFIG1_HR | CONFIG1_DR2 | CONFIG1_DR1);    
    pc.printf("CONFIG1 = 0x%02X\r\n", readRegister(CONFIG1));
    writeRegister(CONFIG2, CONFIG2_DEFAULT);    
    pc.printf("CONFIG2 = 0x%02X\r\n", readRegister(CONFIG2));
    
    // Input short on all channels
    writeRegister(CH1SET, CHNSET_MUXN0);    
    writeRegister(CH2SET, CHNSET_MUXN0);    
    writeRegister(CH3SET, CHNSET_MUXN0);    
    writeRegister(CH4SET, CHNSET_MUXN0);    
    writeRegister(CH5SET, CHNSET_MUXN0);    
    writeRegister(CH6SET, CHNSET_MUXN0);    
    writeRegister(CH7SET, CHNSET_MUXN0);    
    writeRegister(CH8SET, CHNSET_MUXN0);    
    pc.printf("CH1SET = 0x%02X\r\n", readRegister(CH1SET));
    pc.printf("CH2SET = 0x%02X\r\n", readRegister(CH2SET));
    pc.printf("CH3SET = 0x%02X\r\n", readRegister(CH3SET));
    pc.printf("CH4SET = 0x%02X\r\n", readRegister(CH4SET));
    pc.printf("CH5SET = 0x%02X\r\n", readRegister(CH5SET));
    pc.printf("CH6SET = 0x%02X\r\n", readRegister(CH6SET));
    pc.printf("CH7SET = 0x%02X\r\n", readRegister(CH7SET));
    pc.printf("CH8SET = 0x%02X\r\n", readRegister(CH8SET));
    */

    /*
    // Set up device
    writeRegister(CONFIG1, CONFIG1_HR | CONFIG1_DR2 | CONFIG1_DR1);    
    writeRegister(CONFIG2, CONFIG2_DEFAULT | CONFIG2_INTTEST);    
    
    // Input test on all channels
    writeRegister(CH1SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH2SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH3SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH4SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH5SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH6SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH7SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    writeRegister(CH8SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
    */

    // Set up device
    writeRegister(CONFIG1, CONFIG1_HR | CONFIG1_DR2 | CONFIG1_DR1);    
    writeRegister(CONFIG2, CONFIG2_DEFAULT);
    writeRegister(CONFIG3, CONFIG3_DEFAULT | CONFIG3_PD_REFBUF |
                            CONFIG3_RLDREF_INT | CONFIG3_PD_RLD);
    writeRegister(CONFIG4, CONFIG4_PD_LOFF_COMP);
    writeRegister(LOFF, LOFF_VLEAD_OFF_EN | LOFF_FLEAD_OFF1 | LOFF_FLEAD_OFF0);    
    writeRegister(LOFF_SENSP, 0xFF); // for V6, LA, LL, V2, V3, V4, V5, V1
    writeRegister(LOFF_SENSN, 0x02); // for RA only
    writeRegister(RLD_SENSP, 0x06); // for LA, LL
    writeRegister(RLD_SENSN, 0x02); // for RA
    writeRegister(WCT1, WCT1_PD_WCTA | WCT1_WCTA1); // WCTA to CH2P = LA
    writeRegister(WCT2, WCT2_PD_WCTC | WCT2_PD_WCTB | 
                        WCT2_WCTB2 | WCT2_WCTC1 | 
                        WCT2_WCTC0); // WCTB to CH3P = LL, WCTC to CH2N = RA
    
    // Input test on all channels
    writeRegister(CH1SET, CHNSET_DEFAULT);    
    writeRegister(CH2SET, CHNSET_DEFAULT);    
    writeRegister(CH3SET, CHNSET_DEFAULT);    
    writeRegister(CH4SET, CHNSET_DEFAULT);    
    writeRegister(CH5SET, CHNSET_DEFAULT);    
    writeRegister(CH6SET, CHNSET_DEFAULT);    
    writeRegister(CH7SET, CHNSET_DEFAULT);    
    writeRegister(CH8SET, CHNSET_DEFAULT);    
    
}

void ADS1298::startCapture() {
    //Start conversion
    start_ = 1;
    
    // Send RDATAC to start data collection
    sendCommand(RDATAC);
}

void ADS1298::stopCapture() {
    //Stop conversion
    start_ = 0;
    
    // Send SDATAC to stop data collection
    sendCommand(SDATAC);
}

int ADS1298::updateLeadOff(uint8_t *buf) {

  // Buffer contains 9 fields of 24 bits each
  // First field contains an identifier and the status bits
  // First nibble of first byte is always 0b1100
  // Second nibble of third byte is always 0x00 because GPIO are not used
  if ((buf[0] & 0xf0) != 0xc0 || (buf[2] & 0x0f) != 0x00)
    return -1;

  // Second nibble of first byte has IN8P_OFF (V1), IN7P_OFF (V5), IN6P_OFF (V4), IN5P_OFF (V3)
  lOff_ = 0;
  lOff_ |= (buf[0] & 0x08) ? (1 << LOFFV1) : 0;
  lOff_ |= (buf[0] & 0x04) ? (1 << LOFFV5) : 0;
  lOff_ |= (buf[0] & 0x02) ? (1 << LOFFV4) : 0;
  lOff_ |= (buf[0] & 0x01) ? (1 << LOFFV3) : 0;
  // First nibble of second byte has IN4P_OFF (V2), IN3P_OFF (LL), IN2P_OFF (LA), IN1P_OFF (V6)
  lOff_ |= (buf[1] & 0x80) ? (1 << LOFFV2) : 0;
  lOff_ |= (buf[1] & 0x40) ? (1 << LOFFLL) : 0;
  lOff_ |= (buf[1] & 0x20) ? (1 << LOFFLA) : 0;
  lOff_ |= (buf[1] & 0x10) ? (1 << LOFFV6) : 0;
  // First nibble of third byte has IN2N_OFF (RA)
  lOff_ |= (buf[2] & 0x20) ? (1 << LOFFRA) : 0;

  return 0;
}