SPI.spiMISO not working

Technical questions regarding the XTC tools and programming with XMOS.
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

SPI.spiMISO not working

Post by voodoosound »

Hi everyone,

I have a problem accessing a codec via spi.

If I use the spi_master port descriptor, it works fine.

Code: Select all


on tile[0]: spi_master_interface spi_m_if =
{
 	XS1_CLKBLK_4,
	 XS1_CLKBLK_5,
	PORT_SPI_MOSI,
  	PORT_SPI_CLK,
        PORT_SPI_MISO
};
on tile[0]: out port SS2 			 			= PORT_SDATA_IN3;	// SPI CS8416

void spi_master_init( int spi_clock_div)
{
    configure_clock_rate(spi_m_if.blk1, 100, spi_clock_div);
    set_port_no_inv(spi_m_if.sclk);
    configure_out_port(spi_m_if.sclk, spi_m_if.blk1, 1);
    sclk_val = 0xAA;

    configure_clock_src(spi_m_if.blk2, spi_m_if.sclk);
    configure_out_port(spi_m_if.mosi, spi_m_if.blk2, 0);
    configure_in_port(spi_m_if.miso, spi_m_if.blk2);
    clearbuf(spi_m_if.mosi);
    clearbuf(spi_m_if.sclk);
    start_clock(spi_m_if.blk1);
    start_clock(spi_m_if.blk2);
}

static inline void spi_master_out_byte_internal( unsigned char data)
{
    // MSb-first bit order - SPI standard
    unsigned x = bitrev(data) >> 24;
    spi_m_if.mosi <: x;
    spi_m_if.sclk <: sclk_val;
    spi_m_if.sclk <: sclk_val;
    sync(spi_m_if.sclk);
    spi_m_if.miso :> void;
}
But if I try to use the SPI_Flash port descriptor,

Code: Select all

SPI.spiMISO :> void;
is not executed.

Code: Select all

on tile[0]: fl_SPIPorts SPI =
{
	PORT_SPI_MISO,
	PORT_SPI_SS,
	PORT_SPI_CLK,
	PORT_SPI_MOSI,
	XS1_CLKBLK_4
};
on tile[0]: clock b_clkblk2 					= XS1_CLKBLK_5;
on tile[0]: out port SS2 			 			= PORT_SDATA_IN3;	// SPI CS8416

void spi_master_init( int spi_clock_div)
{
    // configure ports and clock blocks
    configure_clock_rate(SPI.spiClkblk, 100, spi_clock_div);

    set_port_no_inv(SPI.spiCLK);
    configure_out_port(SPI.spiCLK, SPI.spiClkblk, 1);
    sclk_val = 0xAA;

    configure_clock_src(b_clkblk2, SPI.spiCLK);
    configure_out_port(SPI.spiMOSI, b_clkblk2, 0);
    configure_in_port(SPI.spiMISO, b_clkblk2);
    clearbuf(SPI.spiMOSI);
    clearbuf(SPI.spiCLK);
    start_clock(SPI.spiClkblk);
    start_clock(b_clkblk2);
}

static inline void spi_master_out_byte_internal( unsigned char data)
{
    // MSb-first bit order - SPI standard
    unsigned x = bitrev(data) >> 24;
    SPI.spiMOSI <: x;
    SPI.spiCLK <: sclk_val;
    SPI.spiCLK <: sclk_val;
    sync(SPI.spiCLK);
    SPI.spiMISO :> void;                  // EXECUTION STOPS HERE
}
Does anyone have a clue what I am missing?

regards,
Ck


voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

At least I found the error.

The chip select pin is never set to high level.

Code: Select all

void config_CS8416_spi_mode(){
	unsigned time;
	timer t;

	SS2 	<: LOW;
	t :> time;
	// Set the reset pin to 1
	RST <: 0x3;
	time += DELAY *5;
	t when timerafter ( time ) :> void;
	SS2 	<: HIGH;
}

void select_CS8416(){
	unsigned time;
	timer t;

	t :> time;
	// CS min 1 mikro sec to high between transmissions
	SS2 	<: HIGH;
	time += DELAY;
	t when timerafter ( time ) :> void;
	SS2 <: LOW; // init read state
}
for testing I toggle the pin high and low in milliseconds intervals. no level change is shown on the scope, always low level.

All other port signals are as expected (miso, mosi, clk, rst)


What could cause this to happen?
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am

Post by mon2 »

Which kit are you using or is this your own design ? If using XSLICE kit, there is a mux present between the XMOS and the related SPI EEprom pins. See the XSLICE kit schematic.

What are the values for HIGH and LOW ?

What is the port width for the SS2 pin ?

As a quick suggestion, replace your HIGH and LOW labels with a hard coded value that matches the port width used for this pin.