TI ADS7250 Read From SPI and SPI1 Simultaneously

I’m so confused by the ADS2750 datasheet here, I can’t seem to figure the proper bit shift value to read data from bits 15-27 properly. I’m not even sure what some of the acronyms mean on page 23 table 1. I get that the first 15 bits are empty while the ADC takes a reading and then the last 12 bits for the 12 bit ADC are the value from that ADC that matches the SPI A or B input. Would someone be willing to explain to me how you would read data based on this datasheet using information from table 2 page 24?

My hardware set up to ADC7250
VCC 5 Volts

  • D5 SS fro Both SPI & SPI1
  • D13 SCK for Both SPI & SPI1
  • D11 MISO SPI_A from ADC
  • D4 MISO SPI_B from ADC
  • No MOSI connected

I’m not sure what to send in the SPI.Transfer(0x00). I’m also not sure if I’m setting up the modes properly, SPISettings settings(24*MHZ, MSBFIRST, SPI_MODE1); as I not 100% on the clock speed. I also I’m confused if this is LSB or MSB as the datasheet has two conflicting notes, the transfer function used LSB and then two paragraphs say “MSBs of ADC_A and ADC_B are output”

I’d love some help decoding this data sheet and getting a script that can read data from this chip using both SPI and SPI1 simultaneously.

Working on only reading SPI first the will add SPI1.

    unsigned int readRegister(byte thisRegister, int bytesToRead);
    
    const int CS_ADC_ISOLATOR = D5;
    __SPISettings settings(24*MHZ, MSBFIRST, SPI_MODE0);
    const int buffersize = 30;
    unsigned char dataBuffer [buffersize];
    const byte READ = 0x22;
    
    // setup() runs once, when the device is first turned on.
    void setup() {
      Serial.begin(115200); 
      pinMode (CS_ADC_ISOLATOR, OUTPUT);
      digitalWrite (CS_ADC_ISOLATOR, HIGH);
      SPI.begin();
      SPI1.begin();
    }
    
    // loop() runs over and over again, as quickly as it can execute.
    void loop() {
        digitalWrite (CS_ADC_ISOLATOR, LOW);
        SPI.beginTransaction(settings);
        for(unsigned char i = 0; i < buffersize; i ++)
        {
            dataBuffer[i] = SPI.transfer(0x00);
        }
        digitalWrite (CS_ADC_ISOLATOR, HIGH);
        SPI.endTransaction();
        for(unsigned char n = 0; n < buffersize; n ++)
        {
            Serial.print(dataBuffer[n]);
        }
        Serial.print("::");
    }

Not sure about that. Each SPI interface has to have its own clock since the the respective MISO/MOSI signals will align with their dedicated clock only.

For SPI1 the clock pin is D2
https://docs.particle.io/reference/device-os/firmware/argon/#spi

If you explicitly need to read both SDO_x pins simultaneously I’m not sure you can use HW SPI for both - maybe @rickkas7 has some thought on that.
One way I’d imagine possible would be to use one HW SPI interface as master and read the respective other data line via an ISR that’s driven by the SCLK line.

This does not make sense. This would shift all zeros 14 bits left which will still be all zeros :wink:
And you cannot store a 32 bit value into a single unsigned char either.
You’d either need to read the 4 individual bytes with one SPI.transfer() call each or better do this

uint32_t val;
SPI.transfer(NULL, (void*)&val, sizeof(val), NULL);

Thanks, to clarify it’s ok to leave us NULL for the my-function argument in this function, the reference confesses me here?

myFunction: user specified function callback to be called after completion of the SPI DMA transfer. It takes no argument and returns nothing, e.g.: void myHandler()

I need to make sure I hold CS (SS) low for 32 clock cycles, I’d like to not use a delay, would you recommend a for loop, that counts the clock edges or using the SPI.available(); function to check the status of the data transfer from SPI & SPI1 MISO?

(I guess you mean it “confuses you”)

The link I provided above also contains this

Not sure where you see the problem or why you’d need a delay of any kind.
With the synchronous version of that call the 32 clock cycles will definitely be finished as soon the call returns.
When using the async version, you’d put the CS-high switching into the callback.

What do you mean by putting the CS-high into the callback?

uint32_t readADS()
{
    uint32_t data;
    digitalWrite(CS_ADC_ISOLATOR,LOW);
    delay(5)
    SPI.transfer(NULL, (void*)&data, sizeof(data), NULL);
    delay(5)
    digitalWrite(CS_ADC_ISOLATOR,HIGH);
    return data;
}

Here is the function I’m using based on your help, yet I’m not sure it’s going to work, because I also need to read SPI1 MISO at the same time, ADS7250 business two SPI inputs to send data back from the two ADC on the IC. It doesn’t look like the Boron’s HAL layer can support this using the SPI library.

To solve this limitation I just ended up bit banging for 32 “CLK” cycles.

digitalWrite (CS_ADC_ISOLATOR, LOW);
   for (int i = 0; i < 32; i++) {
      digitalWrite(SCK, HIGH);
      digitalWrite(SCK, LOW);
       resa <<= 1;       
       resb <<= 1;
       resa |= digitalRead(SDI_A);
       resb |= digitalRead(SDI_B);
   }
  digitalWrite (CS_ADC_ISOLATOR, HIGH);
  Serial.print("SDO_A: "); Serial.println(resa);
  Serial.print("SDO_B: "); Serial.println(resb);

Thanks,
Nicholas

That’s what I tried to address with this proposal

And about this …

If you actually had a callback function you’d do something like this

uint32_t data;

void readADS() {
  digitalWrite(CS_ADC_ISOLATOR,LOW);
  delay(5)
  SPI.transfer(NULL, (void*)&data, sizeof(data), yourCallback);
  // transfer is done asynchronously in the background, so no waiting for the result here
}

void yourCallback() {
  digitalWrite(CS_ADC_ISOLATOR,HIGH);
  // interpret the received data and indicate
  // indicate work-done
}
1 Like