Software SPI

Technical questions regarding the XTC tools and programming with XMOS.
snoopy
Member++
Posts: 28
Joined: Wed Dec 01, 2010 5:46 pm

Software SPI

Post by snoopy »

Hey,

I'm trying to get a PIC and Xmos to play nice using SPI but having no luck.

Master ---------------> Slave
PIC ---------------> XMOS

The PIC is programmed to send a byte over and the Xmos should Echo the byte (In the code below its not doing that cause I wanted to try send something constant)

I've plugged everything into an oscilloscope and looked at the waveform, the PIC (bless its cottons) works well and produces a nice lean waveform. The xmos chip on the other hand looks like its having tourettes.

the code i'm using is:

Code: Select all

void senddata(){

	unsigned char data;

//	data = 0b10101010;
	while(1){
//	  start();
	  data = receive_byte();
//	  stop();

//	  start();
	  send_byte(data);
//	  stop();
	}

}

int main()
{
	setup();
	senddata();

	return 0;
}
and

Code: Select all

in port inputclk = XS1_PORT_1A;
in buffered port:8 mosi = XS1_PORT_1B;
out buffered port:8 miso = XS1_PORT_1C;
in port ss = XS1_PORT_1D;
clock clkblk = XS1_CLKBLK_1;
void setup()

{
	configure_clock_src(clkblk, inputclk);
	configure_in_port(mosi, clkblk);
	configure_out_port(miso, clkblk, 1);

//	configure_in_port_strobed_slave(mosi, ss, clkblk);
//	configure_out_port_strobed_slave(miso, ss, clkblk, 0);


	start_clock(clkblk);
	set_clock_ready_src(clkblk, ss);
//	set_port_inv(ss);
	set_port_strobed(mosi);
	set_port_strobed(miso);
	set_port_slave(mosi);
	set_port_slave(miso);
//	start_clock(clkblk);

//	ss when pinseq(0) :> void;
//	inputclk when pinseq(0) :> void;
//	clearbuf(miso);
//	clearbuf(mosi);

}

void stop()
{
	stop_clock(clkblk);
}

void start()
{
	start_clock(clkblk);
}

unsigned char receive_byte()
{
	unsigned char data;

	clearbuf(miso);
	clearbuf(mosi);

	ss when pinseq(0) :> void;
	//inputclk when pinseq(0) :> void;

	mosi :> data;
	return bitrev(data) >> 24;
}

void send_byte(unsigned char data)
{
	clearbuf(miso);
	clearbuf(mosi);

	ss when pinseq(0) :> void;
	//inputclk when pinseq(0) :> void;

	miso <: 0b11001100;
	mosi :> void;
	//data;//(bitrev(data) >> 24);
}
Sorry for the dirty looking code but this is a direct result of debugging for 2 days and getting no where.

Has anyone successfully managed to interface a PIC or an AVR with xmos as a slave??

Also I found that for some reason using the:

configure_in_port_strobed_slave(mosi, ss, clkblk);
configure_out_port_strobed_slave(miso, ss, clkblk, 0).

gave me a less stable result.
:?

Any help is appreciated,
Jake


bearcat
Respected Member
Posts: 283
Joined: Fri Mar 19, 2010 4:49 am

Post by bearcat »

Not the question you asked, but I have successfully done the other way around. A PIC (slave) to a master XMOS. I struggled with SPI modes for a while. Also have an initialization issue with the PIC I still need to resolve. Solid once it is started, though.

I absolutely needed a logic analyzer to figure out the timings and waveforms.
snoopy
Member++
Posts: 28
Joined: Wed Dec 01, 2010 5:46 pm

Post by snoopy »

I'm using the PIC as a HID interface so thought it would be better to keep it as a master. Might be worth swapping them round. Did you use the configure_out_port_strobed_master? or did you use set commands?

I almost had it working at some point but it was really unreliable in that if the lsb was a 0 then it would sometimes miss it out.

Cheers for the reply, It gives me an indication that it *should* be possible.
Jake
bearcat
Respected Member
Posts: 283
Joined: Fri Mar 19, 2010 4:49 am

Post by bearcat »

I used the SPI routines provided by XMOS as the starting point. They do work just fine, but I found the library needs more capabilities. As provided, the XMOS library uses SPI mode 3. I had a part that had to use MODE 0 (not the PIC), so I had to modify for this mode. To the PIC I use mode 3.

Also, most SPI is done as a 16 bit transfer. Send a register address, receive back the value (at the master). So I added to the routines to provide 16 bit transfers. That got tricky to code for.

I use a "data ready" line from the PIC to the XMOS. When the XMOS sees the line high, it requests data from the PIC. This allows the XMOS to be a master, but still allows for very fast turn around time.

On the PIC I use the MSSP interrupt to process the bytes. But the MSSP peripheral is only an 8 bit device. There is no way for the MSSP to perform an immediate send after receive! Yuck. (Multiple receives is possible). So I had to add a 10uS delay (64Mhz device) between send and receive on the XMOS side to allow for the PIC to ready the transmitter.

Like I said ealier, on power up of the PIC I have some initialization issue. I have not had time to fully debug this yet. I appears something along the line of the PIC needs activity on the SPI port to get setup???? Once the port is running though, it operates without errors.

Good luck. As I said ealier, there was no way I could have got this all working without a logic analyzer with SPI decode.

On the XMOS:
extern buffered out port:8 p_spi_sdi;
extern buffered out port:8 p_spi_sck;
extern buffered in port:8 p_spi_sdo;
...
configure_clock_rate_at_most(spiblk1, 100, SPIDIVIDER);
configure_out_port(p_spi_sck, spiblk1, 0);
configure_clock_src(spiblk2, p_spi_sck);
configure_out_port(p_spi_sdi, spiblk2, 0);
configure_in_port(p_spi_sdo, spiblk2);
clearbuf(p_spi_sdi);
clearbuf(p_spi_sck);
start_clock(spiblk1);
start_clock(spiblk2);
p_spi_sck <: 0xFF;
t :> time;
t when timerafter(50 * MICROSECS + time) :> void; //Wait to output data


Setup, on the PIC:
'Reset SPI
Set iCSPIC On 'Must be high according to datasheet even though input
Dir iCSPIC In
Set SSPEN Off
...
'Mode 3 SPI for XMOS-> CKP=1, CKE=0 (clock idle high, sample rising, output falling)
Set CKP On
Set CKE Off
Set SMP Off 'Must be off for a slave
Set SSPM0 Off 'Slave mode use SS
Set SSPM1 Off
Set SSPM2 On
Set SSPM3 Off
Set SSPOV Off 'Overflow bit only reset via software
Set WCOL Off
If iSCK Then 'Wait for idle state
Set SSPEN On 'Enable SPI
Dir oSDO Out 'Must set to Ouput, actual out is by SS pin
bytTemp = SSPBUF 'Read the SPI buffer to clear it (just in case)
End If
...
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

If you have the PICKIT2/3 to program the PIC with, you may use it as a 3 pin logic-analyzer. Check out the tool-chain from Microchip.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
octal
XCore Addict
Posts: 228
Joined: Thu Jan 27, 2011 3:30 pm
Location: Argenteuil - France

Post by octal »

lilltroll wrote:If you have the PICKIT2/3 to program the PIC with, you may use it as a 3 pin logic-analyzer. Check out the tool-chain from Microchip.
PICKit3 cannot be used as a logic analyzer. The standalone app that gives the possibility to use a PICKit2 as a logic analyzer has not been ported completely to PICKit3. On PICKit3 it still miss the serial port to USB converter mode and the Logic Analyzer feature.

Even with PICKit2, I don't think that you'll be able to see too much things on the SPI bus, as the problem is that PICKit2 Logic Analyzer is quite limited in speed.
bearcat
Respected Member
Posts: 283
Joined: Fri Mar 19, 2010 4:49 am

Post by bearcat »

I use the USBee logic analyzer. I got mine for around $120. Does most things I have needed recently. Can do 24MHz if you really need that speed (sometimes need to retrigger it as the USB bogs down and errors at that speed). SPI decode saved a lot of time. $120 is not alot to spend to save hours in debugging time.
User avatar
octal
XCore Addict
Posts: 228
Joined: Thu Jan 27, 2011 3:30 pm
Location: Argenteuil - France

Post by octal »

+1 for USBee
I have one and I'm very happy with it. I use it a lot.
Saleae has LOGIC, that is multiplatform and is almost the same as USBee. They published recently an sdk that let users develop their own filters and data acquisition tools. Very nice for custom filters and decoders development (I think USBee have something similar in Pro versions of their USBee Suite).
snoopy
Member++
Posts: 28
Joined: Wed Dec 01, 2010 5:46 pm

Post by snoopy »

Here is something odd about the SPI, when I transfer data that has a 1 as the LSB it transfers data fine but when the lsb is a 0 it tends to be left out....

Is there something I'm missing input and output which could cause this???

I don't have access to an oscilloscope at the moment so I'm just taking stabs in the dark at the moment.

Jake