timing pulse edge with CTRA register (is it possible?)
courtens
Posts: 101
I based all my code on the main clock (cnt) but realized that what I really need is a time counter from a pulse edge.
I would like to code a function that provides me with the time (in clock counts) starting from the time a trigger last went on.
In other words, each time the signal goes on - the counter gets reset to zero. Calling the function returns the clock counts that have gone by since the trigger last went on.
Can this be done using one of the CTRA registers? I did read AN001 (about Propeller Counters) but somehow it is not clicking. More examples would be helpful.
For me the speed and accuracy is very important here, because I use this number as a base for all further time sensitive calculations.
Thanks in advance for your suggestions on how to best do this.
I would like to code a function that provides me with the time (in clock counts) starting from the time a trigger last went on.
In other words, each time the signal goes on - the counter gets reset to zero. Calling the function returns the clock counts that have gone by since the trigger last went on.
Can this be done using one of the CTRA registers? I did read AN001 (about Propeller Counters) but somehow it is not clicking. More examples would be helpful.
For me the speed and accuracy is very important here, because I use this number as a base for all further time sensitive calculations.
Thanks in advance for your suggestions on how to best do this.
Comments
There is no HW Clear, but there is a GATED Clock mode, that Adds FRQx (Usually =1) to PHSx on every CLK, while the Gate is HI.
( POS mode mentioned in #2)
You can then sense the GATE going low, [Count now Freezes] Read and Clear PHSx in SW, then the HW waits until GATE next goes high, when it resumes counting from Zero.
This does need a (small) minimum LOW time.
Usually you need two WAIT phases, one for =\_ when you capture/clear inSW, and another for _/= which is used to ready the WAIT =\_
If you can spare another pin, I think you can use 'POS detector with feedback' mode, and now wait for TWO pins, A and B(A@T-1), and those two bits will will be 01 for one single sample time, on a falling edge - so now a single wait can be used.
This is my code (the signal I am monitoring is a video field signal)
or
More 'accurate' at what ? - waitcnt has the best (lowest) granularity, but it is not checking a pin.
The WAIT family of opcodes work to 1 CLK cycle, so they have (much) less granularity than any read-and-Check polling.
It is kind of scary to think that reading the assembly language code snippet is starting to look like something that can be read (by me that is...) and somewhat understood. I tried to get more familiar with the assembly language, but did not find easy example codes and how-to's, so I gave up on that idea some time ago.
I was trying to stay away of having to start a new cog just for that task, that is why I really liked the register counter idea,
Sofar I wrote all the code using timestamps and cnt as reference, but the code was getting messy and hard to trouble shoot. And I was getting tired of following this kind of workaround to avoid the logic pitfall when the counter goes from 2,147,483,647 to -2,147,483,648
I love the idea of having these two counters available (it would be nice if there would be a third one ... but two will have to do.)
I just realized that my requirements on the resolution or "granularity" as jmg so nicely states is 824 counts, which is 1/3 of an HD frame line (80_000_000 / 29.97 / 1080 / 3). So technically speaking if checking on the count or doing something with it, should stay under 824 count. So 746 ticks is OK.
PS. It is not only the actual interval time that is of interest to me. I am actually much more interested in the timing of three different occurring events that need to happen within two time-windows; and during that phase of one frame. I need to know the tick count from the edge to these different events.
and now learned that I can also code it like this. It uses less code, but takes longer to process: which makes my time_stamp_B less accurate.
but is there a better why to do this sort of thing using assembly language to make it faster? Not sure.
Very very nice!!! This looks like a much better approach. I did not know you could to that. I think this is it
Do I need to set the flagPin as input and output?
The only disadvantage of using this code is that one has to be carfull when to "set" the flagPin
Tracy Allen, somehow this code is not working for me. My flagPin is always high. I even tried to set it low, but even that is not working. How would I set the FlagPin to go high only after say 3_380_000 counts?
This is what I have
I think I just found a solution. This is working -- but the counter is only counting every other count (very strange)
now I am witnessing a strange counting behavior. I am using counter B as a "logical" counter (one count per clock tick); but for some reason it is only counting 1/2 of the counts it should get.
Is this normal for counter B?
Thank you Tracy! YES - I did find something in the code that was pulling up that flagPin. I fixed it, and now your code is working! Very nice. However, I am only getting 1 count for 2 cycles. This is very strange. Is there something that could have changed my clock in that cog?
frqa := 300 '???
phsa := 0
I dumped the frqa := 300 and phsa := 0 approach all together. It worked to kill the loop, but is less elegant then your code.
This is all the code in that cog total (171 bytes.) I reserved 200 for it (50 lonsg)
The phase duration for PAL video is 3_200_000 and I am getting ony 1_599_952 for elapsed_time; only half the expected value. So is video_timeStamp_B: 1_599_382
I could just multiply by 2 -- but something is off if it is suppose to count every count ?!?
My sync pulse is what I expect it to be ... yes. And the timeout behavior (flagPin) is also working well.
Are you getting a value of 3M2 for the elapsed_time?
I am trying to find an explanation for the counters behavior - but some how can't. What is strange is that somehow counter A & B are only counting one clock cycle for every 2 clock cycles. This is not what I intend it to do. It is like if this one cog is running at 40MHz for counter A & B but 80MHz for the cnt clock. Very strange.
If I use this code in place of the above posted code it gives me the correct clock count for the two counters. But this is not the way I expected spin to work. This would be a "quick fix" but with no logical explanation of why the counters are not counting properly.
So with this quick fix in place I am getting the expected 3M2 counts per period (phase), but without doubling it I am only getting half the counts. Something is not right.
Would this kind of behavior point to a memory collision somewhere?
PAL is 25 frames per second ... so 25Hz is right ... or 20uS per frame or 3_200_000 counts per frame.
Try this :http://en.wikipedia.org/wiki/PAL
The vertical timings are:
Vertical frequency 50 Hz
Frame rate in the PALs I know, are all 50Hz, however they do interlace, which may be where your 25Hz figure has come from.
PAL frame rate is 25 fps, NTSC is 29.97!
Frame rate is not the same as AC rate (Hz)
My VS (vertical sync) pulse is one pulse per frame (NOT to be confused by fields!!!)
kuroneko, yes. I am sorry ... I meant mS and not uS ... and not 20 but 40 per frame. So it is 40mS per frame and 20mS per field, and there are 2 files in one video frame. So one PAL frame has 3m2 cycles
And the vertical sync that the code is monitoring is a short pulse that goes low, one time per frame.
But back to my spin misbehavior question in post 20. Somehow my register CTRA and CTRB are not counting one tick per cycle, but only every other tick per cycle. It is as if they would be taking turns in the counting department. And so I am ending up with only half the counts that would be expected for the duration of one frame. I expect 3M2 but get only 1M6 per frame. Is this normal behavoir, or is this some hardware bug? I thought that the two counters would count every clock count.
This is how I set up the two counters:
I plan on using these counters in other parts of my code, and would like to know how they work -- or am I witnessing some memory collision that is messing up the counting? It just is all very strange. Thanks for the help!
I don't think the Prop is lying to you. Do you have a 'scope or logic analyzer where you can visualize the signal?
Get another instrument, and measure that vertical sync rate. Many multimeters have frequency counters.