Edge triggering?

Technical questions regarding the XTC tools and programming with XMOS.
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Edge triggering?

Post by JohnR »

I am using pinseq to try and find the delay between the leading edges of two square wave inputs,
thus

while{
start when pinseq(1) :> void;
tmr :> tStart;
stop when pinseq(1) :> void;
tmr :> tStop;
.......................

}

The problem is (of course, once I saw it) was that the start line triggers repeatedly while the input square wave is high.

Is there any neat way of making the code respond to edges rather than levels? I had thought that the peek() function might work in conjunction with a toggle variable but there must be a neater way?

John.


User avatar
wibauxl
Active Member
Posts: 35
Joined: Mon Dec 14, 2009 4:40 pm

Post by wibauxl »

You could try

Code: Select all

start when pinseq(1) :> void;
tmr :> tStart;
stop when pinseq(1) :> void;
tmr :> tStop;
start when pinseq(0) :> void;
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Hi,

The cure _was_ easy. The peek() function solved the problem, now pinseq is not called if 'start' is high, thus:

while{
if(peek(start)==0) // only wait for start with input low
{
start when pinseq(1) :> void;
tmr :> tStart;
stop when pinseq(1) :> void;
tmr :> tStop;
tmr :> t;
delay = delay + (tStop - tStart);
...........................
}
}

John.
User avatar
Woody
XCore Addict
Posts: 165
Joined: Wed Feb 10, 2010 2:32 pm

Post by Woody »

Or along similar lines to wibauxl:

Code: Select all

while{
  start when pinseq(0) :> void;
  start when pinseq(1) :> void;
  tmr :> tStart;
  stop  when pinseq(1) :> void;
  tmr :> tStop;
...
}
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Thanks for the code sample. I will try it shortly as it's simpler than my version.

The next problem is tackling the problem when there is no stop pulse (optics out of line, etc). In my simple code , stop when pinseq(1) :> void; , the program would hang forever if no stop pulse occurs, I think.

I could use one of the pinsneq_at(), pinseq_at() functions but they seem to be an AND sort of functions, the value and the time have both to be true. I need a sort of OR function. In the case of the value being zero, the code would bypass the data accumulation steps.

As usual any ideas are welcome.

John.
User avatar
Woody
XCore Addict
Posts: 165
Joined: Wed Feb 10, 2010 2:32 pm

Post by Woody »

I guess you'd want to wait for stop to be asserted unless it takes a long time. What about this? It provides a timeout if stop isn't asserted quickly enough.

Code: Select all

select {
  case stop when pinseq(1) :> void:
    stopTimeout = 0;
    break;
  case tmr when timerafter(timeout) :> void:
    stopTimeout = 1;
    break;
}
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Woody wrote: select {
case stop when pinseq(1) :> void:
stopTimeout = 0;
break;
case tmr when timerafter(timeout) :> void:
stopTimeout = 1;
break;
}
That's pretty neat. I will try it today.

The problem I can see is that this may slow down the capturing the stop signal time accurately. I am looking at time differences in the tens of nanoseconds, say 50 - 100 nsecs. I am hoping to get adequate resolution by stacking lots of data and allowing the system jitter to randomise the timing.
At the present I can resolve differences of 3 nsec or better. I guess that the select/case statements resolve to branch instructions so that should not put too much delay into the code?

John.
User avatar
Woody
XCore Addict
Posts: 165
Joined: Wed Feb 10, 2010 2:32 pm

Post by Woody »

Sounds like what you need is a timestamped output (see section 4.3 of 'Programming XC on XMOS Devices' (http://www.xmos.com/system/files/xcuser_en.pdf)). This allows you to save the time that the transition occurred rather than having to read a timer afterwards

Code: Select all

start when pinseq(0) :> void;
start when pinseq(1) :> void @ startHiTime;
stop  when pinseq(1) :> void @ stopHiTime;
}
So long as start and stop are both clocked off the 100MHz reference clock you will get resolution of about 10ns. If you need higher resolution you can try increasing the reference clock to 500MHz for 2ns resolution. That's probably +/- 2ns on that resolution though.
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

XMOS_delay.GIF
Hi,

I am still having some problems measuring very short delays with the code shown below.
The input is a pair of pulses separated in this example by about 6 nsec (the top two traces in the attachment). The third trace is the test port (test <: 1, test <: 0).

Code: Select all

		if(peek(start)==0) // only wait for start with input low
		{
			start when pinseq(1) :> void; // @ tStart;
            tmr :> tStart;
	        test <: 1;

			stop  when pinseq(1) :> void; // @ tStop;
	        tmr :> tStop;
	        test <: 0;
	        tmr :> t;
	        delay = delay + (tStop - tStart);

The delay between the first pulse and test going high is 66 nsecs. The subsequent delay for test going low is another 60 nsecs. I had expected the first delay but not the second. It is almost as if the system was not processing the second pulse until the first pulse had been processed??

This means that I cant measure any delays less than about 60 nsecs which might be OK for my project but I would still like to understand what is happening. Above 60 nsecs the delay measurement is as expected.

John.
You do not have the required permissions to view the files attached to this post.
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Hi,

I forgot to add in my previous post that I had tested the code at both 100 Mhz and 200 Mhz reference clocks but the minimum measurement time remained the same at about 60 nsecs.

John.