problem re-purposing XC-3 board

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
chow
Junior Member
Posts: 7
Joined: Thu Sep 29, 2011 8:08 pm

problem re-purposing XC-3 board

Post by chow »

I am just getting started with using the XMOS devices, so I can easily be doing something obviously wrong here. I have an XC-3 board which I got so I could over time play with the networking stuff, but for starters I am just trying to control a strip of LEDs using SPI mode-0 (just clock and mosi).

I have a bit of code that works in the simulator, using the 1st and 2nd pin of the LED Out expansion header to drive the LED strip. However, nothing I do to run it on the actual hardware seems to work. PORT_LED_OUT_R0 has no voltage and PORT_LED_OUT_G0 appears as solid 3.3v to my scope.

Any ideas what I might be doing wrong?


Below is the code I am using
====================

// Copyright (c) 2011, XMOS Ltd., All rights reserved
// This software is freely distributable under a derivative of the
// University of Illinois/NCSA Open Source License posted in
// LICENSE.txt and at <http://github.xcore.com/>

///////////////////////////////////////////////////////////////////////////////
//
// Test bench for SPI master
// Using the XC-1A board
//
// xc1a_test.xc
//
#include <xs1.h>
#include <platform.h>

#define FRAME_WIDTH 8
#define FRAME_HEIGHT 38
#define FRAME_SIZE FRAME_WIDTH * FRAME_HEIGHT
#define FRAME_OUT_DELAY 50000 // 500 uSecs
#define WS2801_CMD_DISABLE 0
#define WS2801_CMD_ENABLE 1
#define WS2801_CLK_DIV 25 // 4 Mhz - sclk driven on even, mosi driven on odd clock ticks

// rrrrrrrrggggggggbbbbbbbbaaaaaaaa
unsigned frame_buffer[FRAME_WIDTH * FRAME_HEIGHT];

clock clk = XS1_CLKBLK_1;
out buffered port:1 sclk = XS1_PORT_1F;
out buffered port:1 mosi = XS1_PORT_1G;


int main()
{
unsigned time;
timer t;

configure_clock_rate_at_most(clk, 100, WS2801_CLK_DIV);
configure_out_port(sclk, clk, 0);
configure_out_port(mosi, clk, 0);
start_clock(clk);

sclk <: 0;
t :> time;
time += FRAME_OUT_DELAY;
t when timerafter(time) :> void;

mosi <: 1; // first bit of data
sync(mosi);

while (1) {
for (int i = 0; i < FRAME_SIZE; i++) {
unsigned data = 0xFF000000; // test with one solid color
for (int j = 0; j < 24; j++) {
if (data & 0x80000000) {
mosi <: 1;
} else {
mosi <: 0;
}
sclk <: 0;
sync(sclk);
sclk <: 1;
data <<= 1;
sync(sclk);
}
}

sclk <: 0;
t :> time;
time += FRAME_OUT_DELAY;
t when timerafter(time) :> void;
}
}


User avatar
matrix
Active Member
Posts: 62
Joined: Sat Sep 17, 2011 12:05 pm

Post by matrix »

Hi Chow,

your sample code does not implement SPI-mode 0,
it appears to be be mode 3.
User avatar
matrix
Active Member
Posts: 62
Joined: Sat Sep 17, 2011 12:05 pm

Post by matrix »

oops sorry. mode 0 seems to be correct.
User avatar
matrix
Active Member
Posts: 62
Joined: Sat Sep 17, 2011 12:05 pm

Post by matrix »

Hi Chow,

Hi Chow,

your posted code will not work, mainly because you
have mixed up clocked I/O with bit banging technique.

You can try this code, if clocked I/O is what you want for
SPI operation.

I have stripped out the loop and delay time between your
application specific frames, to focus just on the principle.

I did not try the code, let me know if it works.

Code: Select all

#include <xs1.h>
#include <xclib.h>

out buffered port:32 sclk = XS1_PORT_1F;
out buffered port:32 mosi = XS1_PORT_1G;


clock blk1 = XS1_CLKBLK_1 ;
clock blk2 = XS1_CLKBLK_2 ;

int main()
{

	   unsigned int data=0xff000000;
	   
       //configure clocked output 	   
	   configure_clock_rate(blk1, 100,25);
	   configure_out_port(sclk, blk1, 0);
	   configure_clock_src(blk2, sclk);
	   configure_out_port(mosi, blk2, 0);
	   
	   clearbuf(mosi);

	   start_clock(blk1);
	   start_clock(blk2);

	   //check MSB of data and set MOSI line accordingly
	   //skip check if you need SPI mode 3, and set clock pattern to 0xFFFFFFFF
	   
	   if(data&0x80000000)
	   configure_out_port(mosi, blk2, 1);
	   else configure_out_port(mosi, blk2, 0);

	   //reverse data to big endian order
	   mosi <: bitrev(data); 

	   //clock pattern
	   sclk <: 0x55555555;
	   sclk <: 0x55555555;
	   // wait until clocked output operation is finalized.
	   sync(sclk);

return 0;
}
User avatar
chow
Junior Member
Posts: 7
Joined: Thu Sep 29, 2011 8:08 pm

Post by chow »

I'll give that a try, but I am still wondering why the simulator output from the code I specified above looked correct in the Waveform viewer, but nothing appeared to come out the actual hardware pins.
User avatar
matrix
Active Member
Posts: 62
Joined: Sat Sep 17, 2011 12:05 pm

Post by matrix »

Hi again,

Ok, I have given your code a run in simulator mode.
The waveform looks ok on the first transmit frame.

One thing that I have noticed is that you have forgotten to pull down
SCLK after the last clock. You can achieve this by placing sclk <: 0;
at the beginning of your frame transmission loop, for example.

But I am not sure if this was your problem, though it is SPI mode 0 standard
that SCLK is low during IDLE time.

Can you post the SPI part of the LED strip data sheet ?