>Working, with library!< Interfacing ADS1213 22-bit ADC

Today I glanced over my code again, and I discovered a major fault: I wrote the PORTB bit the wrong way round! So now port 7 was being set instead of 13... But I fixed it, as well as adjusting the timing for the reset for a 2 MHz crystal, as the reset function could not have worked before because the reset function has maximum timings which were not met.

I looked over my code a lot of times, tested a lot of times but it just doesn't work. The main loop simply reads the Vbias, the easiest way to check if the write to the CMR has been successful.

So I really don't know what to do any more because I tried everything but it still doesn't seem to work.

@CrossRoads: Have you done any testing with the ADS1213 yet, and if not, would you like to check and try my code? (it might work in the very unlikely event that both my ADS1213 chips are smoked)

Here's the latest code:

// This code tries to read the ADC1213 chip from Texas Instruments using SPI.

// The ADC1213 is assumed to have a 2MHz external crystal connected here.

#define DRDYPIN 6 // Data ready pin

#define SELPIN 8 // Selection Pin (CS)
#define DATAOUT 10// MOSI
#define DATAIN  12// MISO
#define SPICLOCK  13// Serial clock (SCLK)

void ResetADC() { //********************************************************* Resets the ADS1213, needed after power-up
  // NOTE: Does SELPIN have to be low (selected) while resetting, and if so, what are the minimum delay times? Datasheet is quite vague here, specifying nothing else than SLKC times.
  delay(300); // Delay to stabilize power

  PORTB &= B11111110; //digitalWrite(SELPIN,LOW); //Select ADC
  delayMicroseconds(6); // t24 in datasheet

//  NOTE: A reset doesn't need a DRDY LOW right?

  PORTB |= B00100000; // Set port 13 (SCLK) HIGH
  delayMicroseconds(550); // t3 on datasheet p.30, @2MHz clock
  PORTB &= B11011111; // Set port 13 LOW
  delayMicroseconds(6); // t2
  PORTB |= B00100000; // Port 13 HIGH
  delayMicroseconds(300); // t1
  PORTB &= B11011111; // Port 13 LOW
  delayMicroseconds(6); // t2
  PORTB |= B00100000; // Port 13 HIGH
  delayMicroseconds(550); // t3
  PORTB &= B11011111; // Port 13 LOW
  delayMicroseconds(6); // t2
  PORTB |= B00100000; // Port 13 HIGH
  delayMicroseconds(1030); // t4
  PORTB &= B11011111; // Port 13 LOW

  delayMicroseconds(5); // Random quirk (necessary?)
  
  PORTB |= B00000001;// Deselect device again (= //digitalWrite(SELPIN,HIGH);)
  delay(100); // Stabilize everything. Is this necessary?
}



void setup ()//********************************************************* Setup
{
 // Bitbanging the SPI interface, from: http://www.arduino.cc/playground/Code/MCP3208
 //set pin modes 
  pinMode(SELPIN, OUTPUT); 
    digitalWrite(SELPIN,HIGH);   //Deselect device to start with 
  pinMode(DATAOUT, OUTPUT); 
    digitalWrite(DATAOUT,LOW); 
  pinMode(DATAIN, INPUT); 
  pinMode(SPICLOCK, OUTPUT); 
    digitalWrite(SPICLOCK,LOW); 
  pinMode(DRDYPIN, INPUT);

  Serial.begin(115200);
  ResetADC();
  
//*** NOTE: DRDY should be low when writing! Therefore I'll first check if it's low and if it has been high (to avoid arriving at the end of a LOW).
  byte GoOn = 0;
  byte HasBeenHigh = 0;
  while (GoOn == 0) {
    if (PIND & B01000000) HasBeenHigh = 1;
    else if (HasBeenHigh) GoOn = 1;
    //Serial.println('W');
  }
  
  // Set the desired mode
  byte commandWriteCMR = B00000100;
  // 0 for write: 00 for 1 byte: 0 because it has to be there: 0100 for command register byte 3
  byte CMRbyte1 = B11100010; // Sets Vbias ON
  
  //delayMicroseconds(2); // t21 in datasheet (probably not neccesary...)
  
//*** Now for the actual write sequence:
  PORTB |= B11111110; //digitalWrite(SELPIN,LOW); //Select ADC
  delayMicroseconds(6); // t24 in datasheet
  
  //*** Write the instruction byte
  for (int i=7; i>=0; i--){
    if (commandWriteCMR&1<<i) {
      PORTB |= B00100100; // Set SPICLOCK & DATAOUT HIGH
    }
    else {
      PORTB &= B11111011; // Set DATAOUT LOW
      PORTB |= B00100000; // Set SPICLOCK HIGH
    }
    delayMicroseconds(3); // t10 in datasheet. NOTE: Is this necessary?
    PORTB &= B11011111; //digitalWrite(SPICLOCK,LOW); note: Also possible using ^=
    delayMicroseconds(3); // t11 in datasheet
  }
  PORTB &= B11111011; // Set DATAOUT LOW, for when the last bit was a 1 (we don't want it to stay high though it might work?)
  
  delayMicroseconds(7); // t19 in datasheet, min time between sending INSR and writing CMR
  
  //*** Write to the command register to set the right settings  
  for (int i=7; i>=0; i--){
    if (CMRbyte1&1<<i) {
      PORTB |= B00100100; // Set SPICLOCK & DATAOUT HIGH
    }
    else {
      PORTB &= B11111011; // Set DATAOUT LOW
      PORTB |= B00100000; // Set SPICLOCK HIGH
    }
    delayMicroseconds(3); // t10 in datasheet. NOTE: Is this necessary?
    PORTB &= B11011111; //digitalWrite(SPICLOCK,LOW); note: Also possible using ^=
    delayMicroseconds(3); // t11 in datasheet
  }
  PORTB &= B11111011; // Set DATAOUT LOW, for when the last bit was a 1 (we don't want it to stay high though it might work?)

  while (digitalRead(DRDYPIN) == LOW) { // Hold when DRYDY is still low, then delay to adhere to t23 in the datasheet
    //Serial.println('D');
  }
  delayMicroseconds(2); // t23 in the datasheet (min time from rising edge of DRDY to rising edge of CS)
  digitalWrite(SELPIN,HIGH); // Deselect device again
  delay(100); // Stabilize everything. Is this necessary?
  Serial.println("Finished with setup");
}


void loop() {//********************************* Main loop
  int VbiasPin = 1;
  Serial.println(analogRead(VbiasPin));
  delay(1000);
}