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_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 0Here's the new output. It's more regular but still stupid readings.
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 valueAndyHow 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 periodOr:
.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 periodSaving 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 periodAnd 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.
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.