How to get timestamp of bit transmission

Technical questions regarding the XTC tools and programming with XMOS.
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

How to get timestamp of bit transmission

Post by babazaroni »

I've got to measure the period of 6 input bits and would like to do it with one core.

I was waiting on each one in a select statement, then reading a timer but found that multiple transitions close to each other were interfering with the time count.

I also tried the @ statement in the select case but that seem to give me the same problems when multiple transitions were happening close to each other.

There seems to be a timestamp register associated with each bit.

How should I configure a 1 bit port to timestamp a transition and read this timestamp?
henk
Verified
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi babazaroni,

How close to each other are the bits in time?

Is there a fixed number of transitions, i.e., it goes 0 -> 1 -> 0 -> 1 -> 0 -> 1 and you are trying to establish the period and duty-cycle of the clock?

Cheers,
Henk
peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

Hi babazaroni,

The hardware only supports one timestamp per hardware port, not per value read on the port. However, you can set up the port to capture 6 bits and give you the time at which the 6th bit is read. If you do this more than once you'll get the time it takes to read 6 bits as the difference between two of the port timer values.

Here's an example:

Code: Select all

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

// The port needs to be buffered in order to do the partin
in buffered port:32 p1 = XS1_PORT_1A;

int main()
{
  unsigned value, start, end;

  {value, start} = partin_timestamped(p1, 6); // Read 6 bits and timestamp
  {value, end} = partin_timestamped(p1, 6); // Read 6 bits and timestamp

  printintln(end - start);

  return 0;
}
Also, remember that port and timer times can't be used interchangeably. If your port is clocked off the reference clock then the port timer ticks will still be 10ns ticks.

Peter
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

Post by babazaroni »

Thanks for the responses. I should be clear what I'm doing. The 6 bits are on 6 1-bit ports, but could use 6 bits on an 8-bit port. For each bit I'm trying to get the freq over a large amount of transitions, say 4096. To do that, I need the start time of the first bit, then count out 4096 bits, then the time of the last bit. The problem I am seeing, is that while reading the times, a transition on another port may have delayed the reading of the timer. The goal is to be able to be accurate to 1hz of a 3mhz signal. The 3mhz sig could also be divided down by an external counter/divider. Would like to do this in 1 core if possible.

How about this solution. Have each 1-bit port clock another 1-bit port in 32-bit buffered mode.

Then in a select statement, have 6 cases that wait on the buffered 1-bit ports. When the case gets selected, then use the portin_timestamped(p,32) statement, throw away the value but use the timestamp and note that we've had 32 more bit transitions towards our 4096 goal.

One would need the timestamp of the first and last selected case to make the final calculation.

I realise I don't have a complete understanding of how clocking ports and timestamps work so my proposal might not work.
henk
Verified
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

If you are willing to spend a few clock blocks (you may run out on one tile, and grab the second one):

- connect each of the 1-bit ports to a clock block
- attach each clock block to some random port (never mind which one).
- start_clock on each of them
- then continuously sample each of the ports above and read a port-count and a time stamp.

Code: Select all

  for(int i = 0; i < 6; i++) {
    p[i] @ toggle_count[i] :> int tmp;
    tmp :> time_count[i];
  }
This gets you pairs of toggle counts and time counts, and once the toggle counts have wrapped around often enough you will get your accuracy.

The strategy above assumes that all clocks run; and there isn't a clock that is way out (i.e., 5 clocks of 3 MHz and one clock of 1 Hz).

You can also throw threads at it, that removes the need for the above condition and the for-loop.
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

Post by babazaroni »

Yes, the 6 clocks will all be about around 3mhz.

What's that nomenclature tmp :> time_count?

Is that the same as time_count = tmp?

PS: I see the initial confusion was my title used 'Transmission' but should have been 'Transition'.
henk
Verified
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Sorry - tmp was meant to be a timer tmr; autowrecked.

Code: Select all

  timer tmr;

  ...
  tmr :> time_count[i];
  ...