Is it possible to check exactly what cycle the previous event occured on an input port after the fact?

Technical discussions around xCORE processors (e.g. xcore-200 & xcore.ai).
michaelf
Member++
Posts: 21
Joined: Thu Mar 14, 2024 7:44 pm

Is it possible to check exactly what cycle the previous event occured on an input port after the fact?

Post by michaelf »

Somewhat related to the new app note on "Fast" mode, I'm thinking about latency between the value on an input port changing and the point at which the code is actually able to respond to it.

As an example, I have a 1-bit input put connected to an infrared receiver. For various reasons, the task which parses the IR command is implemented as follows. The numbers are related to the numbers I have labelled on the timing diagram.

1. Wait for pin to go from low to high (this represents the start of an IR pulse train and occurs at point, i.e. half way through bit 1)
2. Delay for a quarter of a cycle (0.445ms) so we are "exactly" 3/4 of the way through bit 1 - read the value of the pin; it is expect to be logic high.
3. Delay for 1 cycle (1.778ms) and sample the pin; logic high means that bit is a 1, logic low means that bit is a 0.
4. Repeat x times until the end of the pulse train.

Image

There is some latency between the the pin going from low to high, and the handler task being able to respond to it. So, depending on what else is going on in that core/other threads, the task will start running a little bit after that initial rising edge. The problem with this is that all subsequent steps are dependent on the that first time point; the port is sampled at discrete time intervals thereafter.

In reality, there is enough leeway in this protocol such that it isn't particularly a problem. This may not be the case for all protocols, though. My question is as follows:

When the the task handler starts, having been triggered by that initial rising edge in "Bit 1", is it possible to query the port to find out how many cycles ago the value actually changed?

Some pseudocode:

Code: Select all

while (1) {
    select {
        case p_ir_receiver when pinseq(1):
            // what is the difference between the current clock cycle, and the clock cycle that the port value changed to 1?
            break;
    }
}
User avatar
fabriceo
XCore Addict
Posts: 246
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

I think you should simply write the case like this:
case p_ir when pinseq(1) :> void @ tmp : { ... }

you get in tmp the value of the "ts" 16 bit counter attached to the port
michaelf
Member++
Posts: 21
Joined: Thu Mar 14, 2024 7:44 pm

Post by michaelf »

fabriceo wrote: Tue Nov 26, 2024 3:56 pm I think you should simply write the case like this:
case p_ir when pinseq(1) :> void @ tmp : { ... }

you get in tmp the value of the "ts" 16 bit counter attached to the port
Ah great, I'll give that a try. I hadn't realised that the timestamped output syntax could be used in a select statement like that.