SPI Help

Technical discussions related to any XMOS development kit or reference design. Eg XK-1A, sliceKIT, etc.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

SPI Help

Post by rp181 »

I am trying to get SPI to work on an XC-1A for the AD7856 ADC. However, I am just getting "FFFFFFFF" all the time.The code is here:


Code: Select all

#include <platform.h>
#include "SPI_Master/spi_master.h"
#include <print.h>

#define SPI_CS XS1_PORT_4A
#define SPI_MOSI XS1_PORT_1D
#define SPI_CLK XS1_PORT_1C
#define SPI_MISO XS1_PORT_1B

out port SPI_ChipSelect = SPI_CS;

const char read_id = 0x9F;
unsigned word;

spi_master_interface spi_if = { XS1_CLKBLK_1, XS1_CLKBLK_2, PORT_SPI_MOSI,
		PORT_SPI_CLK, PORT_SPI_MISO };

void spi_deselect();
void spi_select();

int main(void) {
	spi_init(spi_if, 4);
	spi_deselect();


	spi_select();
	word = spi_in_word(spi_if);
	spi_deselect();

	printhex(word);

	spi_shutdown(spi_if);

}

void spi_select() {
	SPI_ChipSelect <: 0;
}

void spi_deselect() {
	SPI_ChipSelect <: 0b1111;
}


ADC datasheet (PDF): http://www.analog.com/static/imported-f ... AD7856.pdf


User avatar
leon_heller
XCore Expert
Posts: 546
Joined: Thu Dec 10, 2009 10:41 pm
Location: St. Leonards-on-Sea, E. Sussex, UK.

Post by leon_heller »

I often do a loopback test, initially, when I use SPI, without anything connected. I also have a little PCB with a 74HC595 on it, with an LED on each output. The '595 is SPI-compatible, and it's very useful for test purposes. Of course, there are several flavours of SPI, so it won't necessarily be the same as a particular chip, but it can be very helpful for initial debugging.
User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm

Post by Berni »

What i recommend is running the program inside the simulator and trace the ports in to a v*.vcd file so you can later look at it just like a logic analyzer and determine if you are doing it right and if your timing is off.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »

At this point, I am just trying to read the status register. Using the data sheet, this is what i came up to send to it:

Code: Select all

11100101 11010001 
Which in Hex, is 0xE5 and 0xD5. The next read should return 16bits for the status register. The read method looks like this

Code: Select all

unsigned int spi_in_word(spi_master_interface &i) 
{ 
    // big endian byte order 
    unsigned int data = 0; 
    data |= (spi_in_byte(i) << 24); 
    data |= (spi_in_byte(i) << 16); 
    data |= (spi_in_byte(i) << 8); 
    data |= spi_in_byte(i); 
    return data; 
} 

and out method:

Code: Select all

void spi_out_word(spi_master_interface &i, unsigne d int data) 
{ 
  // big endian byte order 
  spi_out_byte(i, (data >> 24) & 0xFF); 
  spi_out_byte(i, (data >> 16) & 0xFF); 
  spi_out_byte(i, (data >> 8) & 0xFF); 
  spi_out_byte(i, data & 0xFF); 
} 

I am unsure about what these are actually doing. When It is sending, does it send as an 8-bit word? I do:

Code: Select all

spi_out_word(spi_if, 0xE5); 
spi_out_word(spi_if, 0xD1);

And when I read, the ADC should be sending 2 8-bit words (i think). Is this method receiving all 16bits? When i read, this is what i get:

Code: Select all

7FCFFFFE 
FF9FFFFE 
Every read after this, without writing, yields the same "FF9FFFFE".

According to the data-sheet, the first bit should always be 0, and this is not. I have also, instead of sending out a word, sending a byte, which gives:

Code: Select all

65D1FFFE 
FF9FFFFE 


This is the main method of the code:

Code: Select all

spi_init(spi_if, 4); 
    delay(250); 

    spi_select(); 
    spi_out_byte(spi_if, 0xE5); 
    spi_out_byte(spi_if, 0xD1); 
    spi_deselect(); 

    delay(10); 

    spi_select(); 
    word = spi_in_word(spi_if); 
    word1 = spi_in_word(spi_if); 

    printhexln(word); 
    printhexln(word1); 

    spi_deselect(); 

    spi_shutdown(spi_if); 
select() pulls the chip select low.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »

Got this to work, but having issue with something, maybe timing.

I am reading an Accelerometer X,Y, and Z. Each one read individually works fine, and any 2 work fine. For example get

X = 1.6
Z = 2.0

or

X = 1.6
Y = 1.3

However, as soon as i add a third read, values swap, so i get:

X = 1.6
Y = 2.0
Z = 1.3

I also tried putting a delay of 1 second between each read, but doesnt do anything. I am using printf to print the results. Everything is in 1 thread.