Timer and Clock

Technical questions regarding the XTC tools and programming with XMOS.
malo
Active Member
Posts: 33
Joined: Fri Sep 16, 2016 9:03 pm

Timer and Clock

Post by malo »

Hello,

Is there a way to couple timer with clock?
having use case when need to perform and action on ext signal "tick", well still need to divide that ext signal by constant divider and can not handle that "tick" division from the code (no spare time / core for that).
For the moment came up with idea of sampling port always connected to zero while port has clock with ext src.

using
configure_clock_src_divide
configure_in_port
start_clock

and case
case p_always_zero_in_ when pinseq (0x0):> void:

It works but have feeling that must me more elegant way how to do it:)
any hints?
Im on XEF216-512.

wbr
malo


henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi Malo,

xCORE200 processors can divide the external clock in a clock block; would that sort your problem out?

Cheers,
Henk
malo
Active Member
Posts: 33
Joined: Fri Sep 16, 2016 9:03 pm

Post by malo »

Hello Henk,

I'm using that functionality with configure_clock_src_divide, but could not find the syntax how to use clock block in the select/case.
Or how to couple clock block with timer which can be used in the select/case.
Is there a way?

wbr
malo
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Code: Select all

Or how to couple clock block with timer which can be used in the select/case.
The built in timer types always clock from the reference clock (100MHz normally) so, if you want to have a periodic tick synchronous to an external clock, you could use a port timer to generate an event. The only thing is that:

- A port timer is 16b. So make sure your overflow period is within 2^16 ticks away. Or use a clock divider to increase the time between port clock ticks
- If you miss a port timer event, it will not happen until the next time around (unlike a timerafter event)

Something like this perhaps:

Code: Select all

#include <xs1.h>
#include <print.h>

in port p_ext_clock = XS1_PORT_1A;
in port p_using_this_as_counter = XS1_PORT_16A;
clock clk_ext = XS1_CLKBLK_1;

out port p_test = XS1_PORT_1B;

#define PERIOD_EXT_CLOCK_TICKS	10

void test_clock (void){
	unsigned short time_trigger;

	//Connect p_ext_clock to clock block. Using divide by 1 but could be higher
	configure_clock_src_divide(clk_ext, p_ext_clock, 0);
	//Clock the counter/port to the clock block
	set_port_clock(p_using_this_as_counter, clk_ext);
	start_clock(clk_ext);

	//Grab current time from port timer
	p_using_this_as_counter :> void @ time_trigger;
	time_trigger += PERIOD_EXT_CLOCK_TICKS;
	while(1){
		select{
			//Input will be delayed until time_trigger is reached in the counter
			case p_using_this_as_counter @ time_trigger :> void:
				static int tt = 1;
				if (tt) {printint(time_trigger); printstrln(" Tick");}
				else  {printint(time_trigger); printstrln(" Tock");}
				tt ^= 1;
				time_trigger += PERIOD_EXT_CLOCK_TICKS;
				break;
		}
	}
}

//Test clock @ ~100KHz. This is not exact and will slip a bit
void clock_gen(void){
	while(1){
		p_test <: 1;
		delay_microseconds(5);
		p_test <: 0;
		delay_microseconds(5);
	}
}

int main (void){
	par{
		clock_gen();
		test_clock();
	}
	return 0;
}

To run you can use this command line:

Code: Select all

xcc  -target=XCORE-200-EXPLORER tick.xc
xsim a.xe --max-cycles 500000 --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1A 1 0 -port tile[0] XS1_PORT_1B 1 0' --trace-plugin VcdPlugin.dll '-tile tile[0] -o trace.vcd -xe a.xe -ports'
Note the port loopback in the simulator and output to vcd (like GTKWAVE) if you need it. This outputs:

Code: Select all

~/Desktop/tmp/tick:$ sh make_sim.sh 
10 Tick
20 Tock
30 Tick
40 Tock
50 Tick
60 Tock
70 Tick
80 Tock
90 Tick
xsim: error: C51188: maximum cycles reached (500000)
malo
Active Member
Posts: 33
Joined: Fri Sep 16, 2016 9:03 pm

Post by malo »

Hello infiniteimprobability,

thanks for your example, it is more or less the same as I have now, there is one GPIO "wasted" for fake input.
was hoping that there is way how to tie clock with timer and use timerafter in the select / case.

thanks anyway!

wbr
malo