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.

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;
}
}