SPI Help!

11 Feb 2010

Hi all,

I'm trying to get an encoder to work over SPI. I had prevoiusly got it going by bit-bashing it, but am told that SPI would be better. The Encoder is the AS5045 and my bit-bashing code was...

EncoderValue=0;
    ChipSelect=0;                //Send Chip Select low to start read
    wait_us(1);                //Wait 1 microsecond
    Clock=0;                    //Send Clock low
   
    for(int i=1;i<18;i++){
        wait_us(1);            //Wait 1 microsecond
        Clock=1;                //Set clock high to start bit read
        wait_us(1);            //Wait 1 microsecond for data to latch onto bus
        if(Data)           
            EncoderValue++;        //If the bit is high add 1 to the encoder value
        EncoderValue=EncoderValue*2;            //Bitshift EncoderValue once
        wait_us(1);            //Wait 1 microsecond (This line may not be needed)
        Clock=0;
    }
    Encoder=EncoderValue>>6;
    ChipSelect=1;                //Send Chip Select high to stop read

    pc.printf("Position %u   \r",Encoder);

 

The first problem I ran into was the encoder returns 18 bits (12 data & 6 status), but SPI only deals with 16 max. So i thought I would read it twice?

My code is...

    spi.format(9,2);            // Setup the spi for 9 bit data, high steady state clock,
    spi.frequency(500000); 
    cs = 0;                     // Select the device by seting chip select low 

    // Send a dummy byte to receive the contents encoder
    int upper = spi.write(0x00);
    int lower = spi.write(0x00);
    lower = lower >> 6;  
    upper = (upper << 6)+lower;
    cs = 1;
   
    pc.printf("%d  \r", upper);

which is quite a bit shorter but doesn't work!

Can anyone help me with this. It's my first try with SPI and i'm getting in a bit of a muddle.

Thanks

Martin

11 Feb 2010 . Edited: 11 Feb 2010

1) You need to use spi.read(), not spi.write().
2) It seems the device uses "data are read on the clock's falling edge and data are changed on a rising edge", i.e. POL=0 and PHA=1, so you probably should try mode 1.
3) To extract the data from two 9-bit reads, I think you need to use the following expression: data = (upper<<3) | (lower >>6)
4) You could also try reading just 12 bits and discard the status ones by raising the CS. Whether that works for multiple measurements depends on the device.

11 Feb 2010

Thanks for your quick reply Igor. Can you explain about the POL & PHA, I can't find an account of them in the handbook except to say what the truth table for the mode is.

Thanks

Martin

11 Feb 2010

There is explanation in Wikipedia. See also the timing diagrams.