How to change clock polarity and phase

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
yugandhar
Junior Member
Posts: 7
Joined: Wed Aug 31, 2011 9:13 am

How to change clock polarity and phase

Post by yugandhar »

Hai all,

I want to use XS1-L1 as SPI master. I had problems with clock polarity and phase.

For Output ports ::
Initially clock polarity is 0 data to be driven on falling edge of clock.

If i use set_port_inv(), clock polarity became 1 and data to be driven on rising edge.

I want clock polarity = 0 and data to be driven on rising edge. How to achieve it ??

I tried set_port_sample_delay() also, but this will work for INPUT ports only.

If anybody have solution or suggestions to achive it, please reply me.

Thankyou
Yugandhar


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

Post by matrix »

Hi,

I am also new to XMOS and have experienced similar problems with spi.
According to XC programming manual, clocked I/O is specified
as follows:

clock falling edge: data is driven
clock rising edge: data is valid

I can't see how to reconfigure this, and even the XMOS SPI reference
implementation is hard-wired to spi mode 3.

You might have a look at the xs1.h file in your project environment.
There are two functions defined:

set_clock_rise_delay(clk, n)
set_clock_fall_delay(clk, n)

By using the functions, it is possible to introduce a phase shift of the clock relative to your
mosi data, thereby changing your current spi mode. I do not find this straightforward, however.
You have to calculate somehow the required additional delays (clock cycles), which depends
on your clock rate settings and other things. Then you should verify the wave form of your
spi signals with the simulator, and if available, with your logic analyzer as well.
and, if available, with your logic analyzer as well.

If your spi application has low-speed requirements, you can also consider bit-banging and avoiding
clocked I/O. The advantage is then that you can generate easily any wanted spi mode.

Hope this helps a bit, maybe an experienced member here can give you more details.

matrix
User avatar
yugandhar
Junior Member
Posts: 7
Joined: Wed Aug 31, 2011 9:13 am

Post by yugandhar »

Hi matrix,

Thank you very much for your reply. The functions u specified are not suitable to change clock polarity and phase.

Is XMOS SPI Reference Code is hardwired to SPI Mode 3 (CPOL = 1, CPHA = 1)??

I think not so.

Can u explain ??

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

Post by matrix »

well I can try...

Let's have a look at the start of the supplied header of the spi master package:

Code: Select all

/**
 * Module:  module_spi_master
 * Version: 1v0
 * Build:   21a5617cdbae74496f778b2a7da0f0661babbd36
 * File:    spi_master.h
 *
 * The copyrights, all other intellectual and industrial 
 * property rights are retained by XMOS and/or its licensors. 
 * Terms and conditions covering the use of this code can
 * be found in the Xmos End User License Agreement.
 *
 * Copyright XMOS Ltd 2010
 *
 * In the case where this code is a modification of existing code
 * under a separate license, the separate license terms are shown
 * below. The modifications to the code are still covered by the 
 * copyright notice above.
 *
 **/                                   
///////////////////////////////////////////////////////////////////////////////
//
// SPI master (mode 3)
//
// Select lines are intentionally not part of API
// They are simple port outputs
// They depend on how many slaves there are and how they're connected
//

#ifndef _spi_master_h_
#define _spi_master_h_
#include <xs1.h>
So yes, it should be mode 3

The functions which I mentioned will not change the clock polarity, this you have to
do yourself, but the functions can change the phase of a given clock signal.

Let's see how the clock polarity is set in spi initialization functon:

Code: Select all

**/                                   
///////////////////////////////////////////////////////////////////////////////
// Select lines are intentionally not part of API
// They are simple port outputs
// They depend on how many slaves there are and how they're connected
//

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

void spi_init(spi_master_interface &i, int spi_clock_div)
{
	// configure ports and clock blocks
	configure_clock_rate(i.blk1, 100, spi_clock_div);
	configure_out_port(i.sclk, i.blk1, 0);
	configure_clock_src(i.blk2, i.sclk);
	configure_out_port(i.mosi, i.blk2, 0);
	configure_in_port(i.miso, i.blk2);
	clearbuf(i.mosi);
	clearbuf(i.sclk);
	start_clock(i.blk1);
	start_clock(i.blk2);
	i.sclk <: 0xFF;
}
In the last line of the function block, the clock level is set to H: i.sclk<:0xFF
If you wanted to start out with the inverse clock polarity, you would comment out
this line, I believe.

I you have a look at the remaining code, you can see frequently code like:

Code: Select all

.
.
i.sclk <: 0xAA;
i.sclk <: 0xAA;
.
That is actually where the spi clock is generated by shifting out a bit-pattern. If you
want to change clock polarity, you might change this to 0x55.

But take it not for granted, I did not try it.

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

Post by matrix »

Mode CPOL CPHA
0 0 0
1 0 1
2 1 0
3 1 1


At CPOL=0 the base value of the clock is zero
For CPHA=0, data are captured on the clock's rising edge (low→high transition) and data are propagated on a falling edge (high→low clock transition).
For CPHA=1, data are captured on the clock's falling edge and data are propagated on a rising edge.

At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
For CPHA=0, data are captured on clock's falling edge and data are propagated on a rising edge.
For CPHA=1, data are captured on clock's rising edge and data are propagated on a falling edge.