Problem with SincN filtering in smartpins
Chip,
With smartpin modes %11000 (P_ADC) or %11001 (P_ADC_EXT), problem occurs using WXPIN %01_xxxx (Sinc2 filtering) or %10_xxxx (Sinc3 filtering). I've discovered glitches in the decimation data from RDPIN when one of theses modes is active. It becomes more apparent with longer decimation periods but I think it is present at all times. It appears as sporadic extra bits. They tend to be at particular bit positions for a given setup. I've noted only high order bits so far, but can't rule them out at any position. The weirdest part is their occurrences are repeatable, like its somehow timing related. With Sinc2, 1024, and lower, bits (clocks) per decimation seems okay. Which is three octaves lower than your docs say should work. And I couldn't get any number of bits per decimation to be clean with Sinc3.
I've gone over and over my code to find any of my own bugs. I've even tested/verified my own understanding of the ADC hardware and SincN processing by using WXPIN %11_0101 (32 bit captures of the raw bitstream). Everything checks out so far. In fact I can reliably process right up to the limits of 32-bit registers with my own Sinc3 filtering. Namely, Sinc3 at 1024 bits per decimation sample works out fine.
EDIT: Here's my working code. It requires Fastspin and my wrapper code, so you'll probably want to write your own.
EDIT2: Small code adjustment
Update: As per below, it needs handled in software ... But is not a problem with the smartpin hardware. It is just what happens when summing mismatched integer widths with rollover. The solution is to either post-trim off the high bits in the larger integer or pre-scale the smaller integer up to the larger.
With smartpin modes %11000 (P_ADC) or %11001 (P_ADC_EXT), problem occurs using WXPIN %01_xxxx (Sinc2 filtering) or %10_xxxx (Sinc3 filtering). I've discovered glitches in the decimation data from RDPIN when one of theses modes is active. It becomes more apparent with longer decimation periods but I think it is present at all times. It appears as sporadic extra bits. They tend to be at particular bit positions for a given setup. I've noted only high order bits so far, but can't rule them out at any position. The weirdest part is their occurrences are repeatable, like its somehow timing related. With Sinc2, 1024, and lower, bits (clocks) per decimation seems okay. Which is three octaves lower than your docs say should work. And I couldn't get any number of bits per decimation to be clean with Sinc3.
I've gone over and over my code to find any of my own bugs. I've even tested/verified my own understanding of the ADC hardware and SincN processing by using WXPIN %11_0101 (32 bit captures of the raw bitstream). Everything checks out so far. In fact I can reliably process right up to the limits of 32-bit registers with my own Sinc3 filtering. Namely, Sinc3 at 1024 bits per decimation sample works out fine.
EDIT: Here's my working code. It requires Fastspin and my wrapper code, so you'll probably want to write your own.
EDIT2: Small code adjustment
Update: As per below, it needs handled in software ... But is not a problem with the smartpin hardware. It is just what happens when summing mismatched integer widths with rollover. The solution is to either post-trim off the high bits in the larger integer or pre-scale the smaller integer up to the larger.
Comments
EDIT: I fixed the error in the programs below, where there were eight zeros in a row, where there should have been seven.
SINC2 Filtering Mode (%01) This mode performs SINC2 filtering, which requires some software interaction in order to realize ADC samples. To begin SINC2 filtering: WRPIN ##%100011_0000000_00_11000_0,#adcpin 'configure ADC+filter pin(s) WXPIN #%01_0111,#adcpin 'SINC2 filtering at 128 clocks DIRH #adcpin 'enable smart pin(s) Pin interaction must occur after each sample period, so it may be good to set up an event to detect the pin's IN going high: SETSE1 #%001<<6 + adcpin 'SE1 triggers on pin high .loop WAITSE1 'wait for sample period done RDPIN x,#adcpin 'get SINC2 accumulator SUB x,diff 'compute sample ADD diff,x 'update diff value SHR x,#6 'justify 8-bit sample 'use x here 'use sample somehow JMP #.loop 'loop for next period x RES 1 'sample value diff RES 1 'diff value Note that it is necessary to shift the computed sample right by some number of bits to leave the ENOBs intact. For SINC2 filtering, you must shift right by LOG2(samples per period)-1, which in this case is LOG2(128)-1 = 6. SINC3 Filtering Mode (%10) This mode performs SINC3 filtering, which requires some software interaction in order to realize ADC samples. To begin SINC3 filtering: WRPIN ##%100011_0000000_00_11000_0,#adcpin 'configure ADC+filter pin(s) WXPIN #%10_0111,#adcpin 'SINC3 filtering at 128 clocks DIRH #adcpin 'enable smart pin(s) Pin interaction must occur after each sample period, so it may be good to set up an event to detect the pin's IN going high: SETSE1 #%001<<6 + adcpin 'SE1 triggers on pin high .loop WAITSE1 'wait for sample period done RDPIN x,#adcpin 'get SINC3 accumulator SUB x,diff1 'compute sample ADD diff1,x 'update diff1 value SUB x,diff2 'compute sample ADD diff2,x 'update diff2 value SHR x,#7 'justify 14-bit sample 'use x here 'use sample somehow JMP #.loop 'loop for next period x RES 1 'sample value diff1 RES 1 'diff1 value diff2 RES 1 'diff2 value
000a4000 01fb4080 000dff80 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01f48080 0005bf00 00084100 01fb3f80 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 000a4000 01ea4000 001a4000 01ea4000 00174080 01f1ff80 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 00054080 01f3ff80 000a4000 01fa4000 01fa4000 000a4000 000a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01f80080 00113f80 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 00060080 01f33f80 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01f8c080 00007f80 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 0006c080 00027f80 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01ea4000 001a4000 01ea4000 000a4000 00098080 01efbf80 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 00078080 0001bf80 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4080 000eff80 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 00038080 0005bf80 01ea4000 001a4000 01ea4000 000a4000 000a4000 01ea4000 000a4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01f64080 0002ff80 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 00044080 01f4ff80 000a4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01f70080 00123f80 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 00050080 00043f80 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01ea4000 001a4000 01ea4000 001a4000 01e7c080 00117f80 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 0005c080 00037f80 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 00088080 01f0bf80 000a4000 000a4000 01ea4000 000a4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 00068080 0002bf80 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 01f94080 000fff80 01fa4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 000a4000 01f28080 01f6bf80 001a4000 01ea4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01f54080 0013ff80 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 00134080 01e5ff80 000a4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 00060080 01f33f80 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01f40080 00053f80 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 0006c080 01f27f80 000a4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01ea4000 001a4000 01ea4000 0014c080 01f47f80 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 00078080 0001bf80 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 000a4000 01fa4000 01f58080 0003bf80 000a4000 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01f84080 01f0ff80 001a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 000a4000 01ea4000 000a4000 000a4000 01f18080 0007bf80 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01ea4000 001a4000 01f44080 01f4ff80 000a4000 000a4000 01ea4000 000a4000 000a4000 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01f24080 0006ff80 01fa4000 000a4000 01fa4000 000a4000 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 00050080 00043f80 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 000a4000 01ea4000 00130080 01f63f80 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 0005c080 00037f80 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 0003c080 01f57f80 01fa4000 000a4000 000a4000 01ea4000 000a4000 000a4000 01ea4000 000a4000 000a4000 01fa4000 01fa4000 01fa4000 00068080 0002bf80 000a4000 01ea4000 000a4000 000a4000 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01ea4000 00148080 01f4bf80 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fdc080 00033f00 01fac100 0001ff80 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01f08080 0008bf80 000a4000 01fa4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fe8080 01fabf80 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01f14080 0017ff80 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000f4080 01e9ff80 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01f20080 00173f80 01ea4000 000a4000 000a4000 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01ea4000 001a4000 01f00080 00093f80 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01ea4000 0012c080 00067f80 01ea4000 001a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 01fa4000 000a4000 000a4000 01f0c080 00087f80 01fa4000 01fa4000 000a4000 000a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 00038080 01f5bf80 000a4000 000a4000 01ea4000 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 000cc080 01ec7f80 000a4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000 01fa4000 000a4000 01fa4000
_main WRPIN ##%100011_00000000_00_11000_0,#adcpin 'configure ADC+filter pin(s) WXPIN #%10_0111,#adcpin 'SINC3 filtering at 128 clocks DIRH #adcpin 'enable smart pin(s) SETSE1 #%001<<6 + adcpin 'SE1 triggers on pin high mov bcdlen, #8 wrfast #0, ##$2000 mov count, #50 .loop WAITSE1 'wait for sample period done RDPIN pa,#adcpin 'get SINC3 accumulator SUB pa,diff1 'compute sample ADD diff1,pa 'update diff1 value SUB pa,diff2 'compute sample ADD diff2,pa 'update diff2 value ' SHR pa,#7 'justify 14-bit sample wflong pa djnz count, #.loop 'loop for next period rdfast #0, ##$2000 mov count, #50 .loop2 rflong pa call #itoh call #putnl djnz count, #.loop2 jmp #$ diff1 long 0 diff2 long 0 count long 0
Here's the new output. It's more regular but still stupid readings.
Total smartpins = 64 1111111111111111111111111111111111111111111111111111111111111111 Rev B silicon. Sysclock 100.0000 MHz 00057580 001aca80 00200000 00200000 00200000 00200000 00200000 00200000 00200000 00200000 00200000 f8200000 08200000 00200000 00200000 00200000 f8200000 08200000 00200000 00200000 f8200000 08200000 00200000 f8200000 08200000 f8200000 08200000 00200000 f8200000 08200000 f8200000 08200000 f8200000 08200000 f8200000 08200000 f8200000 08200000 f8200000 00200000 08200000 f8200000 00200000 08200000 f8200000 00200000 08200000 f8200000 00200000 00200000
There are erroneous bits in the 2 highest bits of the result, which need to get masked out.
Chips code has en error in the ADC configuration, the second field from left should only have 7 zeroes, not 8.
'' ADC sinc3 Test by Ariba _clkfreq = 180_000_000 ADCPIN = 0 var long sample pub main() coginit(16, @adccog, @sample) 'start ADC loop in new cog repeat waitms(300) debug(udec(sample)) 'show adc values in buffer DAT org 0 adccog WRPIN ##%100011_0000000_00_11000_0,#ADCPIN 'configure ADC+filter pin, gain 1 WXPIN #7+32,#ADCPIN 'SINC3 filtering at 128 clocks DIRH #ADCPIN 'enable smart pin SETSE1 #%001<<6 + ADCPIN 'SE1 triggers on pin high .loop WAITSE1 'wait for sample period done 1.4 MHz! RDPIN x,#ADCPIN 'get SINC3 accumulator SUB x,diff1 'compute sample ADD diff1,x 'update diff1 value SUB x,diff2 'compute sample ADD diff2,x 'update diff2 value SHR x,#7 'justify 14-bit sample AND x,##$3FFFF 'remove erroneous high bits WRLONG x,ptra 'use sample somehow JMP #.loop 'loop for next period x RES 1 'sample value diff1 RES 1 'diff1 value diff2 RES 1 'diff2 value
AndyTotal smartpins = 64 1111111111111111111111111111111111111111111111111111111111111111 Rev B silicon. Sysclock 100.0000 MHz 0000ce1f 000d1917 0018432e 0017ae08 0016b904 0015e3d6 00152ad0 0014832f 0013f310 001374c6 0013075a 0012af33 00125a41 00120e58 f811cde7 081195ba 001167f7 00113c4e 00111333 0010f6f2 f810daed 0810c0f1 0010a9c7 001095f0 001084ef f8107821 08106abd 00106052 001056cd f8104d41 081045dd 001041c4 00103cdc f81036b6 0810322a 00102f29 f81029c8 081027e0 001023c0 f8101f70 08101e45 00101da9 f8101eae 08101ccf 00101b5e f81018ee 08101897 f81015bf 08101474 0010172e
How to pass hubRAM buffer address with your example? I'd want to print consecutive samples like I've done with mine.
EDIT: Oh, I think all I have to do is change "sample" into an array of longwords.
You get the address in PTRA when you start the cog with @sample as 3rd parameter in coginit, as I have done.
Have you added the AND instruction into the sinc3 filter loop?
Andy
It sounds like I have a documentation error, at least.
Andy
So, I guess there is some kind of 27-bit vs 32-bit roll-over mismatch at play here. And the simple fix is to mask out the most significant five bits of the resulting 32-bit sample.
EDIT: Corrected the size.
I did test "pruning" the lower bits, which produced increased granularity, but not the upper bits.
EDIT: Ha, I'll try just that, shift the decimated data up by five bits before diff'ing ...
EDIT2: Yep, works without the mask then. No surprise I guess. Six of one, half a dozen of the other.
This means the Sinc2 decimation period can be a little more than the upper listed 8192 bit-clocks. I calculate up to 2^(27/2 = 13.5) or 11585 bit-clocks. This can be set with a WYPIN ... which I did without trouble.
How was the effective number of bits calculated?
I figure it was an artefact of this glitch. Not that I can remember exactly what code I used at the time.
Using snippet of Chip's example:
.loop WAITSE1 'wait for sample period done RDPIN x,#adcpin 'get SINC2 accumulator (27-bit wide) SHL x,#5 'justify/normalise to most-significant-bit SUB x,diff 'compute sample ADD diff,x 'update diff value SHR x,#11 'justify 8-bit sample 'use x here 'use sample somehow JMP #.loop 'loop for next period
Or:
.loop WAITSE1 'wait for sample period done RDPIN x,#adcpin 'get SINC2 accumulator (27-bit wide) SUB x,diff 'compute sample ADD diff,x 'update diff value AND x,##$7FF_FFFF 'remove erroneous high bits SHR x,#6 'justify 8-bit sample 'use x here 'use sample somehow JMP #.loop 'loop for next period
Saving one long and two cycles:
Or:
.loop WAITSE1 'wait for sample period done RDPIN x,#adcpin 'get SINC2 accumulator (27-bit wide) SUB x,diff 'compute sample ADD diff,x 'update diff value ZEROX x,#27 'remove erroneous high bits SHR x,#6 'justify 8-bit sample 'use x here 'use sample somehow JMP #.loop 'loop for next period
And I do still have issues with me beleaguered glob-top part. When heated, it is exhibiting loss of VIO on certain pin groups. The ADC bitstream changes to either all high or all low. The normal packaged prop2 is giving good results when heated so I know it's not the software.
I don't think it is a solder joint problem, or at least not at the prop2 package. I've tried a number of times now to touch up those supply pins, and the nearby VDDs too. And it's not the LDO regulators either since the other group of four pins supplied by each of those LDOs doesn't have an issue.
Pity, since I was hoping to compare the two parts when mapping out all the ADCs.
EDIT: Here's a piece of a report showing pins P48-P55. All powered from the same LDO regulator. P48-P51 are flatlined, while P52-P55 are normal. The values across the report alternate between GIO and VIO input source for the ADC. Each pair across uses a different method of sampling.
P48 262144 262144 33553056 33553056 0 0 33554432 33554432 P49 0 0 0 0 0 0 0 0 P50 0 0 0 0 0 0 0 0 P51 0 0 0 0 0 0 0 0 P52 41909 213960 5363048 27389198 5368593 27388633 5386802 27401617 P53 45927 220955 5880889 28275544 5884516 28275423 5875670 28264824 P54 48958 223988 6269300 28668312 6266466 28669109 6265835 28647257 P55 42524 215505 5445405 27587886 5448878 27584620 5436067 27598580
Could the higher thermal expansion of the glob, have stressed an inner bond wire to the point it has lifted, to be touching only ?
That would match your symptoms.