I am trying to improve some bit-bashed SPI-slave code we have (where the XMOS responds to command from a host micro). We currently have it polling the SCLK line and then outputting the MISO bits as appropriate for the response coming from the XMOS back to the host. This ends up being a bit slow, and after researching, I thought I could use buffered and clocked IO to speed this up.
What I thought I could to do is attach a clock block whose source is the SCLK port to my output buffered MISO port. Then when I write the byte to the MISO port, it will clock out the 8 bits on the trailing edges of the incoming SCLK. Here's a very isolated program that I thought would work:
Code: Select all
#include <platform.h>
#include <xclib.h>
on tile[0] : port PORT_SCLK = PORT_TEST_SCLK; //1-bit port (XS1_PORT_1E)
on tile[0] : in buffered port:8 PORT_MOSI = PORT_TEST_MOSI; //1-bit port (XS1_PORT_1K)
on tile[0] : out buffered port:8 PORT_MISO = PORT_TEST_MISO; //1-bit port (XS1_PORT_1A)
on tile[0] : port PORT_NSS = PORT_TEST_NSS; //1-bit port (XS1_PORT_1P)
on tile[0] : clock CLOCK_SCLK = XS1_CLKBLK_1;
static unsigned char transmit_val = 0x00;
int main()
{
par
{
on tile[0]:
{
unsigned char nSS_val;
unsigned char MISO_val;
set_clock_on(CLOCK_SCLK);
configure_clock_src(CLOCK_SCLK, PORT_SCLK);
configure_out_port(PORT_MISO, CLOCK_SCLK, 0);
start_clock(CLOCK_SCLK);
while (1)
{
//Wait for nSS to be active
while (1)
{
PORT_NSS :> nSS_val;
if (nSS_val == 0)
{
break;
}
}
//Now send out the transmit value on MISO when the SCLK happens
MISO_val = bitrev(transmit_val) >> 24; //Bitswap to send MSb first
clearbuf(PORT_MISO);
PORT_MISO <: MISO_val;
sync(PORT_MISO);
//Increment our transmit value for next loop
transmit_val++;
}
}
}
return 0;
}
Except, it is not working as expected. I do get something output on the MISO line, but the data seen seems fairly random, and not at all sequential. I also read there may be issue with things being shifted by 1-bit (i.e. MODE0/2 vs MODE1/3), but even taking that into account, it does not seem to jive.
Anything obvious that I'm doing wrong? I know there is the spi_lib from XMOS and that has a full SPI slave implementation, but it's pretty heavy weight for what I need to do, and I want to understand how these buffered IOs work before I commit to that or lift parts of it for my own.