SPI Problems with LTC2418

25 May 2011

Hello

I am trying to code up a simple test on an LTC2418 ADC. This chip uses SPI to read up to 16 Single ended signals. I cannot seem to get correct output from my SPI calls. I would really be grateful if someone could take a look and give feedback.

Datasheet here http://cds.linear.com/docs/Datasheet/241418fa.pdf

Basically you send it an 8bit command to select single ended and the channel and read the 32bit result. Do some massaging of the 32bits and get a result. My results make no sense and changing the input voltage causes erratic changes in result.

I believe the SPI mode is 8,0 but not 100% sure of that.

#include "mbed.h"

DigitalOut CS(p8);  //chip select of the LTC2418
SPI device(p11, p12, p13); // mosi, miso, sclk
Serial pc(USBTX, USBRX);
PwmOut aClk(p26);  //used to feed Fo external oscillator on LTC2418


char buffer[32];


union {
    unsigned int i_data;
    char data[4];
} u_data;

unsigned int ADC;
float Result;

int main() {
    
    pc.baud(115200);
    device.format(8,0);
    device.frequency(10000000);
    aClk.period_us(10);
    aClk.write(.5);



    CS=0;    //set chip select low
    wait(.25);   //wait some time for conversion to finish (would be better to poll the MISO pin for low..but how?
    u_data.data[0] = device.write(0xB0);   //write 10110000 to put ADC in single ended mode and select CH0
    CS=1;    
    wait(.25);

    while (1) {

        CS=0;
        wait(.5);
        for (int i=3;i>0;i--) {
            u_data.data[i] = device.write(0xB0);
        }
        CS=1;

        ADC = u_data.i_data<<3;
        ADC = ADC>>9;
        
        pc.printf("%i\n\r",ADC);

        Result=(((float)ADC)/(16777216.0)*2.5;

    }
}

26 May 2011

One suggestion - send the SDO signal to both MISO and to a digital input pin. Then you can use the latter to poll for conversion complete when you pulse CS low.

Do you get the same values repeated over and over when your loop is executing? What value is reported when the input is tied to ground? To +full scale?

26 May 2011

I have had a quick look at your code, and it appears you are not actually reading in from SPI. Also, why not just printf the data, and do conversion in your head or paper to test if it is behaving ? Cheers Ceri.

If I get a chance, will look at something very similar I have done in the morning.

26 May 2011

Just skimmed through datasheet, and there is a demo block of code, But it uses bit bashing. Although, you can still use the SPI pins , but do not assign them as SPI.

26 May 2011

Matt, in your for loop, i>0 will only read 3 bytes so u_data.data[0] will never get updated from the initial read before the while loop. Changing it to i>=0 should take care of it.

Also, Fo can be tied high or low to use the internal oscillator at around 156kHz unless you want 100kHz for the application.

26 May 2011

When I read the data sheet correctly, you handle the protocol wrong. For each conversion, you first need to supply the channel selection, then read the result. You send the channel selector only once, which means each subsequent conversion is one byte off (look at page 14 or at the example code).

Depending on how the ADC behaves when you set CS high too soon, you either go one byte further off each cycle, just end the converion or transmission prematurely, or you confuse the ADC.

26 May 2011

Hendrik, the way Matt has implemented reads should work fine. A read cycle for the part is started by a h/l transition on CS, with 32 bits transfered, the previous cycles result is returned, the first 8 bits set the mode for the next conversion.

The first time the device is accessed, there is no valid data to read so just writing the first byte as 0xB0 will start a new conversion.

If you were using multiple channels you would parse that information out of the lower 6 bits of the result but as Matt is only reading one channel that was not needed so he just masks off the upper 3 bits and lower 6 bits.

27 May 2011

Don, I read the datasheet again - I was wrong :( That leaves only your explanation of reading too few data (which might, as CS is pulled high too early) the same problem.

28 May 2011

Thanks everyone. It turns out that I also read the datasheet and missed somehting. The 29th bit is a sign bit which is set for signals greater than zero. I was not handling this bit properly. Once I corrected that everything magically started working as it should. The SPI stuff was fine it was my processing of the data that was wrong.

Thanks everyone for taking the time to help.

Matt