0

I'm so confused by the ADS2750 datasheet here, I can't seem to figure the proper bit shift 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 << 14);
    }
    digitalWrite (CS_ADC_ISOLATOR, HIGH);
    SPI.endTransaction();
    for(unsigned char n = 0; n < buffersize; n ++)
    {
        Serial.print(dataBuffer[n]);
    }
    Serial.print("::");
}

1 Answer 1

1

You can't use the normal SPI library for communicating with this device properly. Well, you can, but you will only be able to use one channel - the other will be completely ignored.

SPI only works on one MISO pin - you need two. There are two other types of "SPI" that are used by devices, most notably SPI flash chips: DSPI and QSPI (dual SPI and quad SPI). You want DSPI.

Unfortunately the Arduino doesn't do DSPI, so you will have to "bit bang" it, which means manually manipulating the IO pins to create your own SPI signals in software.

Now... on to the datasheet:

The important part is the timing diagram on page 9. From that you can see that you just send 32 clock pulses and the chip responds, after 15 pulses, with the data.

So if you just do 4 8-bit transfers back-to-back then you get the data. It doesn't matter what you "send" in those transfers since the MOSI pin isn't connected to anything.

As far as speed goes, 24MHz is the maximum speed that it will run at. The actual speed is dictated by the Arduino and how fast you manipulate the SCK pin. That can be as slow as 1x10-1000Hz if you really want.

Data should be read on the falling edge of SCK.

So you could write a little routine that looks like:

uint32_t resa = 0;
uint32_t resb = 0;

pinMode(SCK, OUTPUT);
pinMode(SDI_A, INPUT);
pinMode(SDI_B, INPUT);
pinMode(CS, OUTPUT);
digitalWrite (CS, HIGH);


digitalWrite (CS, 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, HIGH);

Serial.print("A: "); Serial.println(resa);
Serial.print("B: "); Serial.println(resb);

So for 32 iterations you pulse the clock HIGH then LOW, then shift each result 1 bit to the left, and then add in the newly read bit into the lowest bit position.

You could speed up operation by using direct port manipulation and avoiding the slow digitalWrite() and digitalRead() functions.

5
  • Let's say I selected an MCU with DSPI, it has SPI and SPI1 capabilities, would I be able to use the SPI library then or would bit danging be my best beat still? I'm using a Particle Boron which has DSPI. Commented Jul 1, 2020 at 18:10
  • No, that doesn't have DSPI (or if it does, you can't tell from that picture. That has two independent SPI channels. That's not DSPI. DSPI, and QSPI, are just one channel, but with multiple data pins on the one channel.
    – Majenko
    Commented Jul 1, 2020 at 18:16
  • So I'm going to have to bit dang... dang. How would you recommend holding CL low for the correct amount of time without a delay? I'd like something that checks the data and pulls CS pin HIGH again based data's status, but can't confidently think of a solution. Commented Jul 4, 2020 at 0:53
  • Sorry, I don't understand. You just lower CS, send your clocks and read the data, then raise CS again. There's nothing to "check".
    – Majenko
    Commented Jul 4, 2020 at 9:41
  • Ok, so I should be able to drow CS low fro 32 CLK cycles and read the data coming from the ADC into any GPIO instead of the standard SPI library. The Boron uses a nRF52840 datasheet page 399 talks about the SPI bus and page 286 talks about the Quad serial peripheral interface. What I understood from reading 6.19 is that the QSPI is not useful here because teh two SPI buses are designed for memory and won't be able to share a single CLK. What recommendation do you have to reading a ADC with two SPI MISO inputs? Commented Jul 7, 2020 at 6:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.