After some experimentation, I found that periodically clearing the first integrators in the Goertzel circuit, by temporarily switching from Sinc2 to Sinc1, and back to Sinc2, gets rid of the buildup problem.
Does changing the mode always reset the integrators, so switch to Sinc1 can be followed immediately by switch back to Sinc2?
After some experimentation, I found that periodically clearing the first integrators in the Goertzel circuit, by temporarily switching from Sinc2 to Sinc1, and back to Sinc2, gets rid of the buildup problem.
Does changing the mode always reset the integrators, so switch to Sinc1 can be followed immediately by switch back to Sinc2?
Correct. During Sinc1 mode, the first integrators always hold the scaled sin and cosine, without accumulating them, like in Sinc2 mode.
On each clock, the first integrators are added into the second integrators, which get cleared on GETXACC.
After some experimentation, I found that periodically clearing the first integrators in the Goertzel circuit, by temporarily switching from Sinc2 to Sinc1, and back to Sinc2, gets rid of the buildup problem.
The new Goertzel circuit allows up to 4 ADC input pins with selectable polarity for each. This is going to make relative measurements possible, among other things.
In these videos, there is a stable 1MHz sine coming into one pin and a swept sine above and below 1MHz coming into another pin. The two pins are summed to form the input sample. The sample is then multiplied each clock by cosine and sine values which are accumulated and periodically converted to power (hypotenuse).
For the Sinc2 video, I'm clearing the first integrators at the outset of each swept-sine measurement. You can see the resolving difference between Sinc1 and Sinc2 quite nicely.
I've thought for a long time that the Goertzel hardware could be used for windowed ADC sampling. But it would be tricky if we wanted to reduce the sample rate by anything other than a power of 2. It could be done if we calculate exactly what steps the Goertzel hardware would use and we put our coefficeints at those locations in the look up table. But what if we don't want to decimate the ADC data by an integer?
For example, if we want exactly 640 samples per line of NTSC video, we need a sampling rate of 10.06976MHz. Note that I'm ignoring the blanking interval.
We could divide the 250MHz sysclock by 24.827 to meet our desires. The problem with doing that is we will have some intervals with 25 sysclocks between samples and some intervals with 24 sysclocks between cycles. This will affect our ADC accumulators because integrating for a longer time will result in a larger output value. Maybe we could compensate for that. One of the main lessons in this thread is that we need a window filter to get good performance from the P2 ADC. For demonstration, I'll use a triangular window. There may be other choices that perform better.
Despite having a different number of samples in the interval, the full scale gain doesn't change that much. The gain variance as the number of samples changes is reduced from 4.1% to .13%. Maybe we could compensate for the deviation in the number of samples per interval. But we still need a window function to get good performance from the ADC. The beauty is that a carefully chosen window function will compensate for fractional resampling automatically. All we need to do is program our desired sample rate into the streamer's frequency register.
This is just a one point test, it's not always this good. The gain varies with the stating phase and the sampling frequency. Over all starting phases, the peak-to-peak gain deviation is .32%
The P2 ADC video quality looks quite good. The test images are from a TV connected to the propeller's DAC. One is composite direct to the TV for reference. Note that 10.x MHz is a little bit low for the highest quality video. If Chip has added modes to use multiple pins in parallel, that should produce very good video when using 2 or 4 ADC pins.
Saucy, we could use multiple pins in parallel with a common signal, summing their conversions. That could work with the scope mode, too. The biggest problem is that we have something like -3dB @1.5MHz on the ADC's analog front end.
Saucy, you could do this now on the V1 silicon: Run the NTSC baseband signal into four pins and sum their conversions, instead of just using one pin. You should get two more bits of quality that way.
This mode uses the lookup RAM as a source of sine/cosine samples, such that bytes 3 and 2 must be unbiased signed sine and cosine values, and bytes 1 and 0 are biased (positive) sine and cosine values suitable for driving DACs. By incorporating DDS output with Goertzel input, many interactive real-world measurements can be made to determine things like time-of-flight and resonance.
Question: I don't understand any general meaning of biased/unbiased. I suspect its meaning is situation dependant. You've labelled positive beside biased, is that what biased means there?
This mode uses the lookup RAM as a source of sine/cosine samples, such that bytes 3 and 2 must be unbiased signed sine and cosine values, and bytes 1 and 0 are biased (positive) sine and cosine values suitable for driving DACs. By incorporating DDS output with Goertzel input, many interactive real-world measurements can be made to determine things like time-of-flight and resonance.
Question: I don't understand any general meaning of biased/unbiased. I suspect its meaning is situation dependant. You've labelled positive beside biased, is that what biased means there?
By "biased", I meant that the MSB is inverted, so that it ranges from $01..$FF, whereas unbiased would range from -$7F..+$7F.
In the new silicon, all Goertzel LUT bytes need to be unbiased. When output to the DACs, the Goertzel hardware will flip the MSB of each byte, making it suitable for DAC output.
Saucy, you could do this now on the V1 silicon: Run the NTSC baseband signal into four pins and sum their conversions, instead of just using one pin. You should get two more bits of quality that way.
Combining multiple ADC pins is going to be the last thing I do. Since I use the Goertzel hardware for the window filter, it's one ADC per cog. I'd need to keep all of the cogs exactly in sync, while I vary the sampling frequency to lock onto the video source. What I will try is switching the ADC to 3.16x mode. That may need attenuation and AC coupling. It should improve the quality by using as much of the full ADC range as practical. Maybe we could add a pre-emphasis circuit to equalize the rolloff of the ADC a bit.
The most important part of video input is synchronization. I'm working on that now. Then perhaps color decoding, because we all like that! We can sample at 13.5MHz, but should we? If we use 12.273MHz we get square pixels for NTSC. I think having a monochrome decoder in one cog is a good goal.
The code I posted could be adapted to a scope filter with a max sampling rate of perhaps 20MS.
I have an Idea about how to best utilize parallel ADCs. The last ~10 pages of this thread are about how the P2 ADC can't have an absolute accuracy better than 1/N where N is the number of clock cycles is the measurement interval. With windowing filters, we can get way more than N output levels. The problem is, at certain points in the ADC output range, like 1/3, the bitstream becomes too uniform to detect small changes in a short sampling time. That causes a non-linearity in the output at those points. It is thought that a second order or higher modulator would not be subject to this problem.
If using 2 or more ADCs in parallel, it might be best to offset their ranges slightly. That way they both don't hit the non-linear points at the same time. The hardware would look like this:
AC coupling capacitors optional. For a video input, I would use them because 1. It's industry standard practice. 2. To run the ADCs in 3.16x mode, which results in a full-scale range of 1.56Vpp.
Nice idea. There is quite a difference between the adc ranges from one channel to another, as well as from one chip to another. Thats why its necessary to do the autocalibration using GIO and VIO. So, the offset may not be so important, if the two channels are naturally sufficiently different
In the future I would like to expand the ADC converters so that they work independent of any pin mode. This way, they can always monitor a pin without dictating mode. Also, I would like to increase the number of integrators to 15, each differentiated in some way, like you've shown. That way, we can get 4 bits per clock, instead of one. I wish I could work on that right now.
hello.
I am not part of the loop on the smart pins. Would you be able to send me a commented code for of how to replicate the counters from the p1 so that I can
understand how it works. I am attempting to port code from the p1 to the p2. The pins elude me. Please help
\
Thanks
hello.
I am not part of the loop on the smart pins. Would you be able to send me a commented code for of how to replicate the counters from the p1 so that I can
understand how it works. I am attempting to port code from the p1 to the p2. The pins elude me. Please help
\
Thanks
Yeah, the better thing to do would be to determine what you want to accomplish and then figure out what smartpin mode looks appropriate, then ask some questions here.
@cgracey
Sorry it took so long. I have been off of the forums for a couple of weeks. I am looking to replicate the counters so I can use some of the sensors that require the counters. I.E. if I remember correctly one of the gyros, inclinometers and others. I can send you the list. I was able to work the counters in P1 but now have to work with the smart pins. I was not in the loop on the fpga stuff.
What kind of oscope signals will I look for to verify that I am using the smart pins correctly. Can you give me an example of nco with smart pins using a sensor.
Thanks
... I am looking to replicate the counters so I can use some of the sensors that require the counters. I.E. if I remember correctly one of the gyros, inclinometers and others. I can send you the list...
It may help to expand on what P1 Counter modes you were using ?
eg if the P2 CTR was used in Pulse Density output as a DAC, you may instead use a real DAC on P2.
Count gating, and increment on edge modes should have P2 equivalents.
Logical actions on 2 pins were possible on P1, but not so directly supported on P2.
P2 has other modes like frequency counting, where it can do quite a bit more than P1, and you can access a lot more than just 2 counters per COG.
I'm guessing that wants a pulse measuring input. There is lots of those smartpins modes ... and some have too terse documentation. I haven't sussed them all out myself.
Here's my most recent summary of the smartpin counter modes:
SPM_CNT_QUAD = %01011_0 ' count: A-B quadrature encoder
SPM_CNT_UP_ENA = %01100_0 ' count: A clock up, B enable
SPM_CNT_DIR = %01101_0 ' count: A clock, B direction
SPM_CNT_UP = %01110_0 ' count: A clock up
SPM_CNT_UP_DN = %01110_0 ' count: A clock up, B clock down
SPM_ACC_UP = %01111_0 ' accumulate: A up
SPM_ACC_UP_DN = %01111_0 ' accumulate: A up, B down
SPM_TIM_STEP = %10000_0 ' interval: of most recent step duration
SPM_TIM_PULSE = %10001_0 ' interval: of most recent pulse duration
SPM_TIM_MANY = %10010_0 ' interval: of X number of accum/pulses/steps
SPM_TIMEOUT = %10010_0 ' interval: since most recent high/rise/edge, with X compare
SPM_TIM_PULS = %10011_0 ' interval: of X number of A-B pulses/steps
SPM_ACC_PULS = %10100_0 ' accumulate: pulses/steps, of X number of A-B pulses/steps
SPM_TIM_OVER = %10101_0 ' interval: of A-B pulses/steps, for at least X duration
SPM_ACC_OVER = %10110_0 ' accumulate: A-B pulses/steps, for at least X duration
SPM_CNT_OVER = %10111_0 ' count: A-B pulses/steps, for at least X duration
I've given each numerical mode number a name (suitable as a constant) according to how it functions but also kept the mode list in numerical order so they match the order in the prop2 document. Reading both the prop2 document and these one-liners should help categorise them for you.
EDIT: The three general category descriptions. Count: Increment/decrement on a defined transition. Accumulate: Increment/decrement every clock cycle that a condition is true. The condition can alternate over time. Interval: Increment every clock cycle for the duration between two conditions or transitions.
EDIT: Updated SPM_TIM_STEP and SPM_TIM_PULSE
Also, SPM_TIM_A and SPM_TIM_PULS and SPM_ACC_PULS
EDIT: I haven't got my head around the last three modes. They are likely incorrectly described.
EDIT: Updated SPM_TIMEOUT and SPM_ACC_PULS
EDIT: Updated SPM_TIM_OVER, SPM_ACC_OVER and SPM_CNT_OVER
EDIT: Renamed SPM_TIM_A to SPM_TIM_MANY
Chip! What's the story with the smartpin scope mode? That's managing four ADCs in parallel, with filtering, all in one smartpin! How can that not have bloated?
EDIT: Not to mention a whole new set of buses added between smartpins and streamers. No wonder revB got bigger!
EDIT2: Ah, I see, the opening description is a little misleading. The smartpin doesn't handle four ADCs. It's still four smartpins for four ADCs. It's explained further down how the streamer/cog does the grouping of four together via combining multiple RDPIN buses. Which also eliminates those extra buses I imagined.
Here's my most recent summary of the smartpin counter modes:
SPM_TIM_STEP = %10000_0 ' interval: of one step
SPM_TIM_PULSE = %10001_0 ' interval: of one pulse
To me that's still terse, and not helped by the P2 docs being terse too....
Taking those 2 examples, P2 uses the wording
%10000 = Time A-input states
%10001 = Time A-input high states
It says 'states' but does not clarify what a state actually is. To me, adding new words of step and pulse will only confuse users more.
%10000 = Time A-input states I cannot quite fathom, but a bit clearer is
%10001 = Time A-input high states
Continuous high states are counted in clock cycles.
Upon each high-to-low transition, the previous high duration count is placed in Z, and IN is raised.
ie Sounds like a Gated Counter with Capture, H=CountEnable and =\_ is Capture. That gives a 1 whole period read time limit.
not mentioned is what happens to Ctr on capture, and over-runs ?
If Ctr clears on capture, over-run will drop a value, if Ctr does not clear, capture increments by t=H for every new capture, and users need to manage 'how many pulses' elsewhere.
If previous is not read in time, does a new capture replace that, or get discarded ?
Is there any way for the user to know they skipped a capture ?
The word "one" is relevant in my short description. It basically means most recent. So most recent step or pulse. That's quite short so I'll change to that ...
SPM_TIM_PULS = %10011_0 ' interval: until X number of A-B pulses/steps
SPM_ACC_PULS = %10100_0 ' accumulate: A up, until X number of A-B pulses/steps
I think they auto adjust to be whole periods, so that's an important word to have in any description.
ie %10011 is Time captured over X whole A-B periods. (Time to read is X periods)
%10100 is a gated version of that, A=H=Enable, so it gives a % of H time.
in use, Alternating %10011 and %10100 can give PWM(duty) capture in a single Smart Pin, but could give lower precision specs than using 2 smart pins to capture X-Whole_Periods Time and % Time over the same X-periods. (eg RC Oscillator MCUs generating PWM, will have noise/drift added to the results)
A Xtal generated PWM should be better, with sysclk sampling noise limited.
Addit: The docs are vague around clear-on-capture ? Merely says "... and a new measurement begins"
Also vague is if this is 'gapless' ? My guess is one period is consumed at each boundary, but it may be smart enough to capture & restart on the same edge, making capture X-Whole_Periods Time sums gapless and equivalent to real time. (with just a phase delay on the very first edge, after smart pin config/arming)
I'll change all the "until"s to "of"s. It needs a little more thought when reading but is slightly more precise description.
EDIT: Hmm, might revert that for the "X time" ones. Not sure, I'll double check ...
EDIT2: Clarification on SPM_TIM_PULSE = %10001_0, it's not the whole pulse period but only the pulse duration. I've corrected the listing. The difference between this and step duration is pulse is only the true interval vs both true and false intervals with step.
Comments
Does changing the mode always reset the integrators, so switch to Sinc1 can be followed immediately by switch back to Sinc2?
Correct. During Sinc1 mode, the first integrators always hold the scaled sin and cosine, without accumulating them, like in Sinc2 mode.
On each clock, the first integrators are added into the second integrators, which get cleared on GETXACC.
Thanks! for the video's Chip, that's very cool.
I wonder what chip means by other things and What kind of other measurements may be possible ?
I've thought for a long time that the Goertzel hardware could be used for windowed ADC sampling. But it would be tricky if we wanted to reduce the sample rate by anything other than a power of 2. It could be done if we calculate exactly what steps the Goertzel hardware would use and we put our coefficeints at those locations in the look up table. But what if we don't want to decimate the ADC data by an integer?
For example, if we want exactly 640 samples per line of NTSC video, we need a sampling rate of 10.06976MHz. Note that I'm ignoring the blanking interval.
We could divide the 250MHz sysclock by 24.827 to meet our desires. The problem with doing that is we will have some intervals with 25 sysclocks between samples and some intervals with 24 sysclocks between cycles. This will affect our ADC accumulators because integrating for a longer time will result in a larger output value. Maybe we could compensate for that. One of the main lessons in this thread is that we need a window filter to get good performance from the P2 ADC. For demonstration, I'll use a triangular window. There may be other choices that perform better.
Despite having a different number of samples in the interval, the full scale gain doesn't change that much. The gain variance as the number of samples changes is reduced from 4.1% to .13%. Maybe we could compensate for the deviation in the number of samples per interval. But we still need a window function to get good performance from the ADC. The beauty is that a carefully chosen window function will compensate for fractional resampling automatically. All we need to do is program our desired sample rate into the streamer's frequency register.
This is just a one point test, it's not always this good. The gain varies with the stating phase and the sampling frequency. Over all starting phases, the peak-to-peak gain deviation is .32%
The P2 ADC video quality looks quite good. The test images are from a TV connected to the propeller's DAC. One is composite direct to the TV for reference. Note that 10.x MHz is a little bit low for the highest quality video. If Chip has added modes to use multiple pins in parallel, that should produce very good video when using 2 or 4 ADC pins.
Saucy, those captures are impressive!
Question: I don't understand any general meaning of biased/unbiased. I suspect its meaning is situation dependant. You've labelled positive beside biased, is that what biased means there?
By "biased", I meant that the MSB is inverted, so that it ranges from $01..$FF, whereas unbiased would range from -$7F..+$7F.
In the new silicon, all Goertzel LUT bytes need to be unbiased. When output to the DACs, the Goertzel hardware will flip the MSB of each byte, making it suitable for DAC output.
Combining multiple ADC pins is going to be the last thing I do. Since I use the Goertzel hardware for the window filter, it's one ADC per cog. I'd need to keep all of the cogs exactly in sync, while I vary the sampling frequency to lock onto the video source. What I will try is switching the ADC to 3.16x mode. That may need attenuation and AC coupling. It should improve the quality by using as much of the full ADC range as practical. Maybe we could add a pre-emphasis circuit to equalize the rolloff of the ADC a bit.
The most important part of video input is synchronization. I'm working on that now. Then perhaps color decoding, because we all like that! We can sample at 13.5MHz, but should we? If we use 12.273MHz we get square pixels for NTSC. I think having a monochrome decoder in one cog is a good goal.
The code I posted could be adapted to a scope filter with a max sampling rate of perhaps 20MS.
If using 2 or more ADCs in parallel, it might be best to offset their ranges slightly. That way they both don't hit the non-linear points at the same time. The hardware would look like this: AC coupling capacitors optional. For a video input, I would use them because 1. It's industry standard practice. 2. To run the ADCs in 3.16x mode, which results in a full-scale range of 1.56Vpp.
The 3.16x makes a lot of sense too
In the future I would like to expand the ADC converters so that they work independent of any pin mode. This way, they can always monitor a pin without dictating mode. Also, I would like to increase the number of integrators to 15, each differentiated in some way, like you've shown. That way, we can get 4 bits per clock, instead of one. I wish I could work on that right now.
hello.
I am not part of the loop on the smart pins. Would you be able to send me a commented code for of how to replicate the counters from the p1 so that I can
understand how it works. I am attempting to port code from the p1 to the p2. The pins elude me. Please help
\
Thanks
There is no direct replication using the smartpins, or anything in the prop2. The answer depends on the application.
Yeah, the better thing to do would be to determine what you want to accomplish and then figure out what smartpin mode looks appropriate, then ask some questions here.
Sorry it took so long. I have been off of the forums for a couple of weeks. I am looking to replicate the counters so I can use some of the sensors that require the counters. I.E. if I remember correctly one of the gyros, inclinometers and others. I can send you the list. I was able to work the counters in P1 but now have to work with the smart pins. I was not in the loop on the fpga stuff.
What kind of oscope signals will I look for to verify that I am using the smart pins correctly. Can you give me an example of nco with smart pins using a sensor.
Thanks
eg if the P2 CTR was used in Pulse Density output as a DAC, you may instead use a real DAC on P2.
Count gating, and increment on edge modes should have P2 equivalents.
Logical actions on 2 pins were possible on P1, but not so directly supported on P2.
P2 has other modes like frequency counting, where it can do quite a bit more than P1, and you can access a lot more than just 2 counters per COG.
EDIT: The three general category descriptions.
Count: Increment/decrement on a defined transition.
Accumulate: Increment/decrement every clock cycle that a condition is true. The condition can alternate over time.
Interval: Increment every clock cycle for the duration between two conditions or transitions.
EDIT: Updated SPM_TIM_STEP and SPM_TIM_PULSE
Also, SPM_TIM_A and SPM_TIM_PULS and SPM_ACC_PULS
EDIT: I haven't got my head around the last three modes. They are likely incorrectly described.
EDIT: Updated SPM_TIMEOUT and SPM_ACC_PULS
EDIT: Updated SPM_TIM_OVER, SPM_ACC_OVER and SPM_CNT_OVER
EDIT: Renamed SPM_TIM_A to SPM_TIM_MANY
EDIT: Not to mention a whole new set of buses added between smartpins and streamers. No wonder revB got bigger!
EDIT2: Ah, I see, the opening description is a little misleading. The smartpin doesn't handle four ADCs. It's still four smartpins for four ADCs. It's explained further down how the streamer/cog does the grouping of four together via combining multiple RDPIN buses. Which also eliminates those extra buses I imagined.
Taking those 2 examples, P2 uses the wording
%10000 = Time A-input states
%10001 = Time A-input high states
It says 'states' but does not clarify what a state actually is. To me, adding new words of step and pulse will only confuse users more.
%10000 = Time A-input states I cannot quite fathom, but a bit clearer is
%10001 = Time A-input high states
Continuous high states are counted in clock cycles.
Upon each high-to-low transition, the previous high duration count is placed in Z, and IN is raised.
ie Sounds like a Gated Counter with Capture, H=CountEnable and =\_ is Capture. That gives a 1 whole period read time limit.
not mentioned is what happens to Ctr on capture, and over-runs ?
If Ctr clears on capture, over-run will drop a value, if Ctr does not clear, capture increments by t=H for every new capture, and users need to manage 'how many pulses' elsewhere.
If previous is not read in time, does a new capture replace that, or get discarded ?
Is there any way for the user to know they skipped a capture ?
ie %10011 is Time captured over X whole A-B periods. (Time to read is X periods)
%10100 is a gated version of that, A=H=Enable, so it gives a % of H time.
in use, Alternating %10011 and %10100 can give PWM(duty) capture in a single Smart Pin, but could give lower precision specs than using 2 smart pins to capture X-Whole_Periods Time and % Time over the same X-periods. (eg RC Oscillator MCUs generating PWM, will have noise/drift added to the results)
A Xtal generated PWM should be better, with sysclk sampling noise limited.
Addit: The docs are vague around clear-on-capture ? Merely says "... and a new measurement begins"
Also vague is if this is 'gapless' ? My guess is one period is consumed at each boundary, but it may be smart enough to capture & restart on the same edge, making capture X-Whole_Periods Time sums gapless and equivalent to real time. (with just a phase delay on the very first edge, after smart pin config/arming)
The most important part of my list is the classification clarification of what the type of measurement is: count, accumulate or interval.
EDIT: Hmm, might revert that for the "X time" ones. Not sure, I'll double check ...
EDIT2: Clarification on SPM_TIM_PULSE = %10001_0, it's not the whole pulse period but only the pulse duration. I've corrected the listing. The difference between this and step duration is pulse is only the true interval vs both true and false intervals with step.