can HW-counters be used to create pulsetrains of variable length?
StefanL38
Posts: 2,292
Hi,
inspired by another thread I was asking myself and now the forum
is there a possability to use the counters to produce a pulsetrain at high
frequencies with an EXACT amount of pulses?
I mean create 8.652.127 pulses at frequency 100 kHz. (not a single pulse more or less)
Then create 329.811 pulses at frequency 300 kHz. (not a single pulse more or less)
Then create 234 pulses at frequency 200 kHz (not a single pulse more or less) etc. etc.
Could this be possible by connecting two counters through IO-pins?
One counter is working as enable-disable-control of the other counter?
best regards
Stefan
inspired by another thread I was asking myself and now the forum
is there a possability to use the counters to produce a pulsetrain at high
frequencies with an EXACT amount of pulses?
I mean create 8.652.127 pulses at frequency 100 kHz. (not a single pulse more or less)
Then create 329.811 pulses at frequency 300 kHz. (not a single pulse more or less)
Then create 234 pulses at frequency 200 kHz (not a single pulse more or less) etc. etc.
Could this be possible by connecting two counters through IO-pins?
One counter is working as enable-disable-control of the other counter?
best regards
Stefan
Comments
However when you think about it if you pole a counter at a regular interval you can see how far your axis has moved. Assuming a trapizoidal profile it will start slowly and end slowly so when it comes to stopping the counter it is actually at a low frequency making it easy to stop accurately. I pole at about 1khz if I remember correctly.
Graham
if I remember right there were some tries to use the counters for serial communication. I haven't watched these discussions closely. What was the result? Does it work? If yeas creating pulsetrains should work to as it equals
to sending a certain amount of bytes containing 255 and a last byte containing a lower value.
Back to the main question: can the counters be setup to count only if a pin-state is high/low? If this is possible it might be possible to use
two or three counters to start/stop each other over IO-pins.
please can somebody who is a counter-expert chime in?
Problem is that any counter which can be enabled doesn't have a suitable output for your pulse train. So you're limited to NCO or PLL modes. Which means you either have to sit there and count sheep^wpulses and then stop it or setup a kind of monoflop (half period NCO would do) which could blank the frequency pin. I don't know what your requirements are, i.e. is there an idle state, if so what polarity etc. What about accuracy, i.e. 300kHz will have a certain error attached (@80MHz)?
Bean
thank you for clearing up this
If I have to "sit there and watch" until it is done it is no longer an advantage
over generating the pulse train directly in software(=asm).
@kuroneko:
So if the serial high-speed output can be done. Do you think it will be possible
to generate 16 bit-output in the following way:
Each two bits represent a channel with step and direction.
direction-bit low turn motor clockwise direction-bit high turn motor counterclockwise
each rising edge on bit step means one step in direction.
So two bytes have to be setup to different values at a maximum frequency
that each step-bit of a channel can create pulses that are derived from the maximum frequency. The frequency of the pulses should be any fraction value of the max-frequency.
How many cogs would that need if the maximum frequency is 500 kHz.
16 bytes at 500kHz mean 8MBaud right?
Would coding this starting at your 20MBaud serial driver a tricky performance of magic coding or something that can be done by a
under middle-class PASM programmer like I am?
I'm not asking you for doing it real. Just to get a feeling about the amount
of work that it is: how long would it take you to code that.
rough estimation 6-7 hours, 6-7 weeks or 7-8 months?
best regards
Stefan
I presume you meant 8,652,127 pulses, not a fractional pulse ?
It is simplest is to do this in SW, and getting the exact pulse count is trivial - just a loop.
Harder will be frequency precision, but if you can tolerate some phase jitter, then you can improve average frequency precisions by working over a number of cycles.
Let the cog counters generate a sequence of N pulses autonomously at frequency F, while the cog is free to do something else without babysitting each pulse, however, the cog only needs to comes back with relatively lax timing to check on that the pulse train is finished
That can be done. Not exactly what you are talking about, but workable in some situations.
Two cog counters are overlapped (Propeller standard wired OR), one at the higher frequency F and one at a lower frequency (F/(2N+1) to create a train of N low-going pulses, followed by a gap with no pulses. The main program can start the pulse train, and then do other stuff, with the caveat that it has to come back within 2N/F seconds to disable the process. (Or else the counters will emit another sequence of N pulses).
The attached program illustrates how this can be done. (in Spin, works up to about F=10kHz.)
Just so we are on the same page, do you want 16bit frames sent serially with 500k frames/s (8Mbaud) or are we talking about a 16bit parallel bus (8 channels) which emits 16bit at 500kHz max? I assume it's the latter so I will wrap my head around that one (to give you an estimate).
Jonathan
@all: Anyway, if you stick to counters then it should be possible to have one cog control two channels. So that's 4 cogs total. Doing it manually will probably bring the number down to two (4 channels each). This is just an estimate based on what we know, there are other (unknown) factors like command handling, parameter processing, direction vs step setup timing etc which take their share as well. After all, a 500kHz cycle only covers 160 clock cycles (@80MHz). Regardless, I'd say that could be done in a couple of days.
Having done some more thinking, the 4 cog + counter support setup is probably the best starting point. Main issue with more channels per cog is the update cycle for new parameters as there is only a limited number of hub-windows available if one of the channels is running at max frequency.
phsx := phsx + (frqx * phsx(31))
That could generate self-quenching pulses.
@Kuroneko, Could you please explain more about what you mean about the 4 cog + counter support? Are you addressing StefanL38's original question?
One could use three cog counters all addressing one pin, two to generate a narrow "enable" pulse for the high frequency from the third counter in a second cog. There would be almost a minute of lax time after generating the pulse stream, before it repeats. The cross-cog "triggering" would be a little tricky.
You should have used impossible then you'd have a solution by now