This is amazing.
So that clears up crosstalk or induced noise within the unit but- I wonder- (because I don't understand exactly what you've done!)- how does this effect a genuine noisy signal? and you want to see the noise?
This is amazing.
So that clears up crosstalk or induced noise within the unit but- I wonder- (because I don't understand exactly what you've done!)- how does this effect a genuine noisy signal? and you want to see the noise?
Dave
That noise would still be there. This just removes what the other signal is contributing.
Some mathematical musings: the 2-sample delay compensation is a simple 2nd-order digital filter, which is precisely what is needed because the problem is a 2nd-order one, namely the rate of change of the slope of the adjacent input. Unwanted effects are seen when there is a discontinuity in the slope. A 1-sample delay should be insufficient and a 3-sample one should not be any better than 2-sample.
A possible change to the software would be to fix the frequency and sweep the compensation scale to find the sweet spot, or sweep both at the same time.
Is there a simple way to see the raw signals in this display (non-windowed)? I know it would be noisier but it would be interesting to see the response reduce as the frequency is increased. Perhaps this window averaging might be causing the relatively slow displayed slew rate for square and sawtooth waveforms.
Is there a simple way to see the raw signals in this display (non-windowed)? I know it would be noisier but it would be interesting to see the response reduce as the frequency is increased. Perhaps this window averaging might be causing the relatively slow displayed slew rate for square and sawtooth waveforms.
The filter has 68 taps that the ADC bits must pass through. That's a bandwidth limiter, plus there's the roll-off of the analog front end of the ADC. I really want to redesign the ADC to give it more bits, make it independent of modes, and clean up the MUX problem. Just cutting away the PinB selection would solve the worst problem.
Ok. I can see the response reduce when I increase this line up towards 3 MHz. Square wave amplitude holds up for the longest, which makes sense if its output voltage remains at the extremities longer.
E.g
dds_freq = 3000_000.0 'nominal DDS frequency (without FM'ing)
The windowing/filter stuff really seems to impact the displayed slew rate.
At the original lower frequency I would have naively expected a waveform as something looking like Figure3 from this link below, but I guess all the extra front end processing does more than that.
Ok. I can see the response reduce when I increase this line up towards 3 MHz. Square wave amplitude holds up for the longest, which makes sense if its output voltage remains at the extremities longer.
E.g
dds_freq = 3000_000.0 'nominal DDS frequency (without FM'ing)
The windowing/filter stuff really seems to impact the displayed slew rate.
At the original lower frequency I would have naively expected a waveform as something looking like Figure3 from this link below, but I guess all the extra front end processing does more than that.
I've found a way to fix the ADC crosstalk problem by cutting a trace on metal layer 2 to eliminate PinB from getting into the ADC's input resistor array, where it mixes (accidentally) with PinA. This would be possible to work into the next wafers at minimal cost. It would also mean that you could not use the ADC on the adjacent pin, but only on the pin, itself. Probably, nobody would care about this. It's way more important that each pin's ADC can work independently, without coupling unwanted signal from its adjacent pin.
The bigger problem would be reworking our I/O test program that runs on ON's wafer prober, since it uses PinB-to-ADC mode. I'm looking into that now.
Does just using one pin in a pair solve this issue in the current silicon?
Also, is there any advantage to having the pair of pins tied to the same analog signal?
This doesn't sound like the kind of issue that is worth redoing the silicon, to me anyway...
Using just one pin, and making sure the other pin is QUIET, will do the job. Or, tying your analog signal to both pins, in which case you can get an extra bit of resolution.
If we do this, it may only be a $5k mask charge for either M2 or VIA2. It doesn't impact wafer delivery, as they are weeks away from processing the metal layers.
Price is right. But, I'd be afraid of doing a full scale production run with untested masks...
Will OnSemi verify that the change won't mess anything up?
Using just one pin, and making sure the other pin is QUIET, will do the job. Or, tying your analog signal to both pins, in which case you can get an extra bit of resolution.
If we do this, it may only be a $5k mask charge for either M2 or VIA2. It doesn't impact wafer delivery, as they are weeks away from processing the metal layers.
It's common for MCUs to have 'rules' around their ADC pins, around quietest pins/crosstalk etc, and some specify switching to IDLE during ADC conversion for lowest noise...
I'm with Rayman, not sure this is worth the risk/benefit.
Looking at this from ST makes me think it's a common problem...
Also, these two pins are likely to have coupling issues due to the traces leading away from MCU as well.
For that reason, you probably want to use only one of a pair of pins anyway..
Still a fan of being bold, and eliminating errata when it makes sense.
Okay, so how much of a predicted effect does this mask change have on the crosstalk? Will it eliminate it, or will there still be some crosstalk like it gets reduced by 25% but still there?
Because if there is still going to be some immediately noticeable crosstalk, and the solution is still a software fix, the mask change doesn't solve anything and is just extra time and money.
And risk. What onsemi can do on their end, is not throw away the old mask(s). Try a run with the new masks, change your test program, pass testing, ship.
Or fail, and if it's a bad or misaligned mask onsemi will fix it and try again. Or given some other unforeseen effect, you go back to the old mask.
Sounds like this could become a HUGE amount of time for many people in the chain to spend on something that can be solved in no time at all by simply using non-pairs, or even non-group pins, with the current mask. Not to mention opportunity cost, as you'll be distracted from Spin2/etc..
Did you find some really compelling reason to consider the mod ?
Otherwise, what you said above "Or, tying your analog signal to both pins, in which case you can get an extra bit of resolution.".....
That seems like a fine reason to keep your design as-is, and document that recommendation as a feature.
Seems like that's a good feature to me: Joined pairs for highest resolution, alternate pins for medium resolution, and adjoining pins for lower resolution.
Seems like that's a good feature to me: Joined pairs for highest resolution, alternate pins for medium resolution, and adjoining pins for lower resolution.
Seems like that's a good feature to me: Joined pairs for highest resolution, alternate pins for medium resolution, and adjoining pins for lower resolution.
Yes, agree.
This works for me too. And there is a software fix also.
But SETSCP/GETSCP work on a 4-pin block and if one pin in a pair is unused or both tied together it will be 2-channel, not 4-channel, and half the data will be wasted?
Aside from a single layer mask expense, I would just need to rewrite the test program to not use that pin B mode. I'm looking at that right now. It's really not that complicated, but makes the scope modes work like they're supposed to.
The risk of making this change is extremely low. It just takes some time for me to rewrite the test program.
What happens when you drive pairs of pins in differential mode? Do you get an added crosstalk on one pin and a subtracted crosstalk on the other? Remember, sigma delta conversion is notorious for out of band oscillations, like those period 7 "1011011" patterns that are so hard to suppress. But of course; if you could get an equal and opposite effect which cancels out around the problem "codes" then the achievable bandwidth goes up, I'm tempted to say - exponentially; maybe speaking figuratively or maybe not - because there is a type of "modulator" known as a "Weaver" modulator, that for example is used to make SSB signals by first modulating an audio signal with a 1.5 kilohertz pair of carriers, i.e. for SSB speech. Really, its just an analog implementation of the first stage of Cooley-Tukey FFT using ring modulators, but because it turns, let's say a 3kHz bandwidth audio signal into four 1.5 kHz bandwidth signals, you get the effect of doubling the A to D bandwidth if you follow the Weaver with a set of modulators instead of upconverting to an SSB carrier frequency. Or you can get 10 or 20 Mhz. bandwidth from a 5 to 10 Mhz. oscilloscope front end, or double that if you cascade a pair of Weaver filters. So if the is a silver lining among the clouds of grey, it is that if you have ever looked at the schematic of a 555, or 741 or an analog three terminal regulator, especially those three terminal regulators; because they have to use the ratio of a set or set of matched resistors to compare to junction intrinsic (Ebers-Moll equation again?) characteristic of two different junctions, so as to be able to use a bizarre arrangement of logarithmic convertors to compensate for temperature and produce a constant output voltage. Which means, likewise, if there is an exact - very precisely controlled amount of parasitic crosstalk that can be perfectly cancelled in software among the pins, then it is possible to exactly compensate for gain differences in the internal and external circuity, in addition to computing the cross-talk cancellation factor, which is also the "chopper" factor if you are doing instrumentation like EEG, EKG, etc., and you need near ZERO dc offset and near ZERO drift and as complete 1/f cancellation when you compare the summation of "count bits" on each of the pins with the filter outputs.
How much crosstalk is there between non-paired pins? There is likely still some from the pcb and package. Digital outputs have a low impedance and probably aren't a good representation of an analog source. Maybe 50 ohms from digital output to ADC, or use a reduced drive mode.
How much crosstalk is there between non-paired pins? There is likely still some from the pcb and package. Digital outputs have a low impedance and probably aren't a good representation of an analog source. Maybe 50 ohms from digital output to ADC, or use a reduced drive mode.
Very little between non-paired pins, but between paired pins, the crosstalk is at about -24dB, which is really high, about 4 bits down.
Comments
'************************************************* '* Use DDS to demonstrate 4-Channel SCOPE mode * '************************************************* CON scp_base = 52 'must be a multiple of 4, 1st pin is level-triggered input dds_base = 48 'must be a multiple of 4, connect these pins to scop_base pins hdmi_base = 32 'must be a multiple of 8 trigger_level = $90 'scope trigger level arm_level = $70 'scope arm level scope_filter = 0 'scope filter: 0 = 68-tap, 1 = 45-tap, 2 = 28-tap dds_freq = 500_000.0 'nominal DDS frequency (without FM'ing) freq = 250_000_000.0 'system clock frequency must be 250 MHz for HDMI buffer = $1000 'sample buffer (4 KB) bitmap = buffer+$1000 'HDMI bitmap (300 KB) DAT org hubset ##%1_000001_0000011000_1111_10_00 'config PLL, 20MHz/2*25*1 = 250MHz waitx ##20_000_000 / 200 'allow crystal+PLL 5ms to stabilize hubset ##%1_000001_0000011000_1111_10_11 'switch to PLL setq ##($7FFFF - @end_of_pgm)/4 'clear hub RAM wrlong #0,##@end_of_pgm coginit #2,##@pgm_dds 'launch DDS coginit #1,##@pgm_scp 'launch Scope coginit #0,##@pgm_hdmi 'launch HDMI '********* '* DDS * '********* DAT org pgm_dds cogid x 'init DAC pins for this cog's DAC channels setnib dacmode,x,#2 wrpin dacmode,#3<<6+dds_base dirh #3<<6+dds_base ' Make sine/triangle/sawtooth/square patterns in LUT mov z,#$1FF 'make 512-sample DDS table in LUT .lut shl z,#32-9 'channel 0 = sine qrotate #127,z shr z,#32-9 getqy y mov x,z 'channel 1 = triangle testb x,#8 wc if_c not x xor x,#$80 setbyte y,x,#1 mov x,z 'channel 2 = sawtooth shr x,#1 xor x,#$80 setbyte y,x,#2 setbyte y,#$81,#3 'channel 3 = square if_c setbyte y,#$7F,#3 wrlut y,z 'write square:sawtooth:triangle:sine into LUT djnf z,#.lut 'loop until 512 samples ' Output DDS patterns and slowly FM xcont dds_d,dds_s 'issue perpetual DDS/Goertzel command .loop qrotate ##3_000_000,x 'slowly FM the signals getqy y add y,xfreq setxfrq y add x,#100 jmp #.loop ' Data dacmode long %0000_0000_000_10110_00000000_01_00000_0 'DAC mode, cog DAC channels xfreq long round(dds_freq/freq * 65536.0 * 32768.0) 'streamer frequency value dds_d long %1111_1111_0000_0111<<16 + $FFFF 'DDS/Goertzel mode, continuous dds_s long %0000_0000_000_000000000 'DDS/Goertzel mode, no input x res 1 y res 1 z res 1 '*********** '* Scope * '*********** ' DAT org pgm_scp wrpin .scpmode,#3<<6+scp_base 'init ADC/scope pins wxpin .scp_x,#3<<6+scp_base dirh #3<<6+scp_base setscp #1<<6 + scp_base 'enable scope channels setse1 #%001<<6 + scp_base 'set SE1 event to first scope pin trigger setxfrq ##$2000_0000 'set streamer NCO frequency to sample every 4th clock ' Capture waveforms before and after trigger .loop wrfast #$1000/64,##buffer 'set wrfast to wrap 1k-sample circular buffer of 4 scope channels xinit .scp_d,#0 'issue 4-ADC8 capture command waitx ##320*4 'allow time to fill first half of buffer akpin #scp_base 'acknowledge trigger pin to clear pollse1 'clear any old trigger event akpin #scp_base 'acknowledge trigger pin to clear waitse1 'wait for new trigger event getptr .x 'capture write pointer, reflects trigger point waitx ##320*4 'allow time to fill second half of buffer xstop 'stop streamer, ~640 samples gathered within 1k sample buffer sub .x,##320*4 'determine start of buffer so that trigger point is in the middle and .x,##$0FFC or .x,##buffer rdfast #$1000/64,##buffer 'set rdfast to wrap 1k-sample buffer .scan getptr .y 'advance to starting sample (320 samples before trigger) cmp .y,.x wz if_nz rflong .p if_nz jmp #.scan ' Dim existing pixels in bitmap loc ptra,#bitmap mov .y,#480 .dimline setq2 #640/4-1 'read in 640 pixels rdlong 0,ptra mov ptrb,#0 rep @.r,#640/4 'dim 640 rgbi8 pixels rdlut .p,ptrb mov .q,.p and .q,.rgbmasks not .p or .p,.rgbmasks addpix .p,.incbytes not .p or .p,.q wrlut .p,ptrb++ .r setq2 #640/4-1 'write back 640 pixels wrlong 0,ptra++ djnz .y,#.dimline ' Plot waveforms mov .x,#0 rflong .p .xloop mov .d,.i 'get samples to compute deltas from mov .i,.p ' mov .n,.p rflong .p 'get 4-channel sample getbyte .da,.i,#3 'perform compensation getbyte .j,.d,#3 sub .da,.j muls .da,.scale sar .da,#8 getbyte .db,.i,#2 getbyte .j,.d,#2 sub .db,.j muls .db,.scale sar .db,#8 getbyte .fa,.p,#3 sub .fa,.db rolbyte .k,.fa,#0 getbyte .fb,.p,#2 sub .fb,.da rolbyte .k,.fb,#0 getbyte .da,.i,#1 getbyte .j,.d,#1 sub .da,.j muls .da,.scale sar .da,#8 getbyte .db,.i,#0 getbyte .j,.d,#0 sub .db,.j muls .db,.scale sar .db,#8 getbyte .fa,.p,#1 sub .fa,.db rolbyte .k,.fa,#0 getbyte .fb,.p,#0 sub .fb,.da rolbyte .k,.fb,#0 mov .q,#480 'plot channel 3 first rep @.plot,#4 'ready to plot 4 channels getbyte .y,.k,#3 'get sample shr .y,#1 'divide by 2 to fit screen subr .y,.q 'flip and vertically position mul .y,.xsize 'get bitmap pixel address add .y,.x add .y,.bitmap wrbyte .color,.y 'plot pixel shl .k,#8 'ready next sample sub .q,#117 'ready next vertical position ror .color,#8 'ready next color .plot incmod .x,.xlimit wc 'loop until all pixels plotted if_nc jmp #.xloop ' Plot trigger level marker mov .y,.scp_x 'get trigger level shr .y,#9 subr .y,#128 mul .y,.xsize add .y,#320-9 add .y,.bitmap setq #4-1 wrlong ##$FFFFFFFF,.y 'white marker ' Toggle P56 for a speed indicator, then loop drvnot #56 jmp #.loop 'loop ' Data .scpmode long %0000_0000_000_100011_0000000_00_11010_0 'ADC/scope mode .scp_d long %1111_0000_1000_0110<<16 + $FFFF 'DDS/Goertzel mode .scp_x long (trigger_level & $FC)<<8 + (arm_level & $FC) + scope_filter .rgbmasks long $E0E0E0E0 .incbytes long $01010101 .xlimit long 640-1 .xsize long 640 .bitmap long bitmap .color long $5F_BF_DF_1F 'initial trace colors .scale long 200/2 .x res 1 .y res 1 .p res 1 .d res 1 .q res 1 .k res 1 .j res 1 .i res 1 .n res 1 .da res 1 .db res 1 .fa res 1 .fb res 1 '********************************* '* HDMI 640 x 480 x 8bpp rgbi8 * '********************************* DAT org pgm_hdmi setcmod #$100 'enable HDMI mode drvl #7<<6 + hdmi_base 'enable HDMI pins wrpin ##%111001<<8,#7<<6 + hdmi_base 'set 1.5k low drive on HDMI pins setxfrq ##$0CCCCCCC+1 'set streamer freq to 1/10th clk (25 MHz) rdfast ##640*480/64,##bitmap 'set rdfast to wrap on 300KB bitmap ' Field loop .field mov .hsync0,.sync_000 'vsync off mov .hsync1,.sync_001 callpa #10,#.blank 'top blanks mov .i,#480 'set visible lines .line call #.hsync 'do horizontal sync xcont .m_rf,#0 'do visible line djnz .i,#.line 'another line? callpa #33,#.blank 'bottom blanks mov .hsync0,.sync_002 'vsync on mov .hsync1,.sync_003 callpa #2,#.blank 'vertical sync blanks jmp #.field 'loop ' Subroutines .blank call #.hsync 'blank lines xcont .m_vi,.hsync0 _ret_ djnz pa,#.blank .hsync xcont .m_bs,.hsync0 'horizontal sync xzero .m_sn,.hsync1 _ret_ xcont .m_bv,.hsync0 ' Data .sync_000 long %1101010100_1101010100_1101010100_10 ' .sync_001 long %1101010100_1101010100_0010101011_10 ' hsync .sync_002 long %1101010100_1101010100_0101010100_10 'vsync .sync_003 long %1101010100_1101010100_1010101011_10 'vsync + hsync .m_bs long $70810000 + hdmi_base<<17 + 16 'before sync .m_sn long $70810000 + hdmi_base<<17 + 96 'sync .m_bv long $70810000 + hdmi_base<<17 + 48 'before visible .m_vi long $70810000 + hdmi_base<<17 + 640 'visible .m_rf long $B0830000 + hdmi_base<<17 + 640 'visible rfbyte luma8 .hsync0 res 1 .hsync1 res 1 .i res 1 end_of_pgm
Thanks for suggesting a math solution. It wasn't occurring to me that something could be done in software. I was only thinking about hardware.
This technique is good enough for SCOPE mode, but for high-resolution conversions, some pin-use considerations are going to be necessary.
This is amazing.
So that clears up crosstalk or induced noise within the unit but- I wonder- (because I don't understand exactly what you've done!)- how does this effect a genuine noisy signal? and you want to see the noise?
Dave
That noise would still be there. This just removes what the other signal is contributing.
A possible change to the software would be to fix the frequency and sweep the compensation scale to find the sweet spot, or sweep both at the same time.
The filter has 68 taps that the ADC bits must pass through. That's a bandwidth limiter, plus there's the roll-off of the analog front end of the ADC. I really want to redesign the ADC to give it more bits, make it independent of modes, and clean up the MUX problem. Just cutting away the PinB selection would solve the worst problem.
E.g
dds_freq = 3000_000.0 'nominal DDS frequency (without FM'ing)
The windowing/filter stuff really seems to impact the displayed slew rate.
At the original lower frequency I would have naively expected a waveform as something looking like Figure3 from this link below, but I guess all the extra front end processing does more than that.
https://sound-au.com/articles/squarewave.htm
Figure 3 is what the ADC analog front end sees, but the 68-tap filter absolutely limits slew.
Its just nice that the scope mode does so much work for you.
The bigger problem would be reworking our I/O test program that runs on ON's wafer prober, since it uses PinB-to-ADC mode. I'm looking into that now.
Meanwhile, here is the fix:
Also, is there any advantage to having the pair of pins tied to the same analog signal?
This doesn't sound like the kind of issue that is worth redoing the silicon, to me anyway...
Using just one pin, and making sure the other pin is QUIET, will do the job. Or, tying your analog signal to both pins, in which case you can get an extra bit of resolution.
If we do this, it may only be a $5k mask charge for either M2 or VIA2. It doesn't impact wafer delivery, as they are weeks away from processing the metal layers.
Will OnSemi verify that the change won't mess anything up?
It's common for MCUs to have 'rules' around their ADC pins, around quietest pins/crosstalk etc, and some specify switching to IDLE during ADC conversion for lowest noise...
I'm with Rayman, not sure this is worth the risk/benefit.
Also, these two pins are likely to have coupling issues due to the traces leading away from MCU as well.
For that reason, you probably want to use only one of a pair of pins anyway..
Okay, so how much of a predicted effect does this mask change have on the crosstalk? Will it eliminate it, or will there still be some crosstalk like it gets reduced by 25% but still there?
Because if there is still going to be some immediately noticeable crosstalk, and the solution is still a software fix, the mask change doesn't solve anything and is just extra time and money.
And risk. What onsemi can do on their end, is not throw away the old mask(s). Try a run with the new masks, change your test program, pass testing, ship.
Or fail, and if it's a bad or misaligned mask onsemi will fix it and try again. Or given some other unforeseen effect, you go back to the old mask.
Did you find some really compelling reason to consider the mod ?
Otherwise, what you said above "Or, tying your analog signal to both pins, in which case you can get an extra bit of resolution.".....
That seems like a fine reason to keep your design as-is, and document that recommendation as a feature.
Seems like that's a good feature to me: Joined pairs for highest resolution, alternate pins for medium resolution, and adjoining pins for lower resolution.
This works for me too. And there is a software fix also.
The risk of making this change is extremely low. It just takes some time for me to rewrite the test program.
Very little between non-paired pins, but between paired pins, the crosstalk is at about -24dB, which is really high, about 4 bits down.