ADC Sampling Breakthrough - Page 12 — Parallax Forums

• Posts: 14,024
Chip,
Sinc3 seems like a real tight fit to me. If it is to exist in the design then make it the bare essentials only. Software can be totally precise at sampling if it wants to be.

• Posts: 13,893
evanh wrote: »
Chip,
Sinc3 seems like a real tight fit to me. If it is to exist in the design then make it the bare essentials only. Software can be totally precise at sampling if it wants to be.

Sinc3 will fit. Isn't it going to get us more bits by a good margin that Sinc2?
• Posts: 13,893
edited 2018-11-24 07:51
cgracey wrote: »
If we have all 32-bit accumulators, it keeps the software simpler, right?

It seems to me that we can do 2954 samples before overflowing ACC3 at 32 bits.
Not quite. We have to worry about the output stage too. Although if we did extended math on the output side it might be fine.

This thing has a gain of G=(RM)^N. N=3 for three accumulators. So our maximum RM is 1625. The reason is 1625^3 < 2^32 -1. If we tried to go to 1626, the output would overflow. 1626^3 > 2^32 -1. In practice we could usually go a little more because we wouldn't see solid ones unless the input was above the supply.

It also turn out that Bout bits are needed for each integrator and comb stage. (https://dspguru.com/files/cic.pdf)
cgracey wrote: »
cgracey wrote: »
...The good part about the sinc filter is that there is no counter to synchronize with the ADC reading process. If we generated the window in time domain, we would have to collect the output while the window is zero, to avoid edge discontinuities.

Wouldn't it still be helpful to have the smart pin report ACC3 on a routine basis? Then we'll have plenty of time to pick up the sample and process it. Plus, no information will be lost in ACC3.

Yes. I'm still not quite sure what all the smart pins can do. Automatically collecting ACC3 would be good.

I guess if we were using the Tukey or trapezoid window, the smart pin would know when the report was going to happen and ramp the window down at the right time.
The smart pin could do something like this:
wait for report timer
ramp window down
send report
ramp window up
repeat

But if we run SINC3 continuously, we won't need to do any windowing, right?
```Sinc3_rolling   713849500 3574525500 4291015625 4291015625 4291015625 4291015625 4291015625
```
So it looks like 2 values to flush out.

As I understand, X and Y are write only? What would be the purpose of using them for the accumulators? We only need to read one accumulator, it would be fine to mux them. In case somebody wanted first or second order value for some reason. I would prefer to loose access to part of the accumulators than loose timing accuracy.

While there are WXPIN and WYPIN instructions, and X and Y (and Z and RESULT) 32-bit registers, each smart pin mode can use the WXPIN/WYPIN and X/Y/Z registers independently of each other.
• Posts: 14,024
cgracey wrote: »
Is there a reason to support both Sinc2 and Sinc3?

I suppose not. I'm edgy about going that far. Is this going to be in mode %01100 then, replacing the existing Sinc1?

• Posts: 13,893
evanh wrote: »
cgracey wrote: »
Is there a reason to support both Sinc2 and Sinc3?

I suppose not. I'm edgy about going that far. Is this going to be in mode %01100 then, replacing the existing Sinc1?

That counting mode still has general use. I don't know where it will go, yet. Those counting modes have extra config bits via WYPIN that can be used to enable something like this.
• Posts: 13,893
edited 2018-11-24 10:39
Okay!!! Sinc3 is working quite well. Thanks, all of you, who've been hammering this out.

I used Evanh's Sinc3 algorithm and look what we can resolve in 1024 clocks now. This ramp represents a 12.9mV span. This is equivalent to one step of an 8-bit DAC. We have run into the noise floor with this measurement, but look at the resolving quality. For a normal 1024 clock (10-bit quality) reading, only four steps would have been resolved in this whole span. You can see that we have maybe hundreds of steps, kind of buried in the noise:

Here is the code that ran this Sinc3 test:
```' ADC Sinc3 sampling

m	= 30			'monitoring DAC pin for watching LSBs of conversion
buffadr	= \$10000		'sample buffer in hub \$10000..\$7FFFF (3,670,016 bits)

dat	org

hubset	##%1_000001_0000010011_1111_10_00	'enable crystal+PLL, stay in 20MHz+ mode
waitx	##20_000_000/100			'wait ~10ms for crystal+PLL to stabilize
hubset	##%1_000001_0000010011_1111_10_11	'now switch to PLL running at 200MHz

wrpin	dacmode,#p^1		'output test level on adjacent pin DAC for ADC input
wxpin	#1,#p^1
wypin	dacval,#p^1
dirh	#p^1

wxpin	#1,#m
dirh	#m
'
'
' Get sample stream, convert to readings, then play readings in a loop
'
loop	call	#getsamp		'get ADC samples (\$70000*8 bits)
call	#consamp		'convert into sinc3 readings

.loop	rfword	x			'get next reading
wypin	x,#m			'output on 16-bit dithered DAC pin
waitx	##1024-12		'hold for a while to recreate clock/1024
jmp	#.loop			'loop
'
'
' Get sample bit stream
'
getsamp	wrfast	#0,buff			'ready to have streamer write ADC bits into buffer
xinit	recmode,#0		'do streamer capture of ADC bits

.rec	incmod	modctr,##895	wc	'slowly... (3.67M / (896 * 16 clocks/loop)) = 256 steps
wypin	dacval,#p^1
getptr	x			'wait for buffer full
cmp	x,##\$80000	wc
if_c	jmp	#.rec

xinit	#0,#0			'stop streamer

_ret_	rdfast	#0,buff			'start fast read of buffer
'
'
' Convert sample bit stream
'
consamp	mov	ptra,#0			'point to final sample buffer

.sample	mov	y,#1024/32		'input 1024 bit samples

.long	rflong	z			'get 32 samples

rep	@.bit,#32		'process 32 samples
shr	z,#1		wc
.bit
djnz	y,#.long		'1024 samples, yet?

sub	z,diff3
sub	z,diff2
sub	z,diff1
shr	z,#14	-8		'shift down into 16-bit range

mov	diff3,acc3		'update diff's
sub	diff3,diff2
sub	diff3,diff1

mov	diff2,acc3
sub	diff2,diff1

mov	diff1,acc3

_ret_	djnz	x,#.sample
'
'
' Data
'
dacmode	long	%10100_00000000_01_00010_0	'DAC 16-bit with random dither
recmode	long	\$D<<28 + p<<17 + \$FFFF		'streamer single-pin record command, infinite

dacval	long	\$FBE0				'initial DAC value for feeding ADC

modctr	long	0

acc1	long	0
acc2	long	0
acc3	long	0

diff1	long	0
diff2	long	0
diff3	long	0

x	res	1
y	res	1
z	res	1
```

Next, I'll see what we can resolve in 32 clocks, as we should get way more than 5-bit quality and we won't be dipping into the noise floor.

• Posts: 4,688
So I haven't been following very much of this but with all these potential improvements to the ADC in the P2 being considered what might be the effective number of bits (ENOB?) for audio sampling possible with the P2 rev B at say a 44.1kHz sampling rate? Would it now be something like 13-14 bits or more? And what P2 clock rate would be needed for that?
• Posts: 13,893
Well, 32-clock samples were so good that I couldn't detect much limitation, so I tried 16-clock samples on a 500KHz sine wave.

Here is what we've been doing, to date. This is called Sinc1, where you just add up the bits each period:

Here is Sinc2, which is a 2nd-order approach:

Here is Sinc3, a 3rd-order approach:

And, maybe at the point of diminishing return, here is Sinc4, a 4th-order approach:

Here is my code. {} comments are used to select which SincN you want. It's current set for Sinc3:
```' ADC Sinc3 sampling

m	= 30			'monitoring DAC pin for watching LSBs of conversion
buffadr	= \$10000		'sample buffer in hub \$10000..\$7FFFF (3,670,016 bits)

dat	org

hubset	##%1_000001_0000010011_1111_10_00	'enable crystal+PLL, stay in 20MHz+ mode
waitx	##20_000_000/100			'wait ~10ms for crystal+PLL to stabilize
hubset	##%1_000001_0000010011_1111_10_11	'now switch to PLL running at 200MHz

wrpin	dacmode,#p^1		'output test level on adjacent pin DAC for ADC input
wxpin	#1,#p^1
wypin	dacval,#p^1
dirh	#p^1

wxpin	#1,#m
dirh	#m
'
'
' Get sample stream, convert to readings, then play readings in a loop
'
loop	call	#getsamp		'get ADC samples (\$70000*8 bits)
call	#consamp		'convert into sinc3 readings

.loop	rfword	x			'get next reading
wypin	x,#m			'output on 16-bit dithered DAC pin
waitx	##16-12			'hold for a while to recreate clock/16
jmp	#.loop			'loop
'
'
' Get sample bit stream
'
getsamp	wrfast	#0,buff			'ready to have streamer write ADC bits into buffer
xinit	recmode,#0		'do streamer capture of ADC bits

.rec	incmod	modctr,##895/27	wc	'slowly... (3.67M / (896 * 16 clocks/loop)) = 256 steps
wypin	dacval,#p^1
getptr	x			'wait for buffer full
cmp	x,##\$80000	wc
if_c	jmp	#.rec

xinit	#0,#0			'stop streamer

_ret_	rdfast	#0,buff			'start fast read of buffer
'
'
' Convert sample bit stream
'
consamp	mov	ptra,#0			'point to final sample buffer

.sample	mov	y,#16/16		'input 32 bit samples

.long	rfword	z			'get 32 samples

rep	@.bit,#16		'process 16 samples
shr	z,#1		wc
.bit
djnz	y,#.long		'1024 samples, yet?

{
sub	z,diff1
shl	z,#12			'shift into 16-bit range

mov	diff1,acc1		'update diff
}
{
sub	z,diff2
sub	z,diff1
shl	z,#8			'shift into 16-bit range

mov	diff2,acc2		'update diff's
sub	diff2,diff1

mov	diff1,acc2
}

sub	z,diff3
sub	z,diff2
sub	z,diff1
shl	z,#4			'shift into 16-bit range

mov	diff3,acc3		'update diff's
sub	diff3,diff2
sub	diff3,diff1

mov	diff2,acc3
sub	diff2,diff1

mov	diff1,acc3

{
sub	z,diff4
sub	z,diff3
sub	z,diff2
sub	z,diff1
shl	z,#0			'shift into 16-bit range

mov	diff4,acc4		'update diff's
sub	diff4,diff3
sub	diff4,diff2
sub	diff4,diff1

mov	diff3,acc4
sub	diff3,diff2
sub	diff3,diff1

mov	diff2,acc4
sub	diff2,diff1

mov	diff1,acc4
}

_ret_	djnz	x,#.sample
'
'
' Data
'
dacmode	long	%10100_00000000_01_00010_0	'DAC 16-bit with random dither
recmode	long	\$D<<28 + p<<17 + \$FFFF		'streamer single-pin record command, infinite

dacval	long	\$0000				'initial DAC value for feeding ADC

modctr	long	0

acc1	long	0
acc2	long	0
acc3	long	0
acc4	long	0

diff1	long	0
diff2	long	0
diff3	long	0
diff4	long	0

x	res	1
y	res	1
z	res	1
```

• Posts: 14,024
cgracey wrote: »
This ramp represents a 12.9mV span. This is equivalent to one step of an 8-bit DAC. We have run into the noise floor with this measurement, but look at the resolving quality. For a normal 1024 clock (10-bit quality) reading, only four steps would have been resolved in this whole span.

1024 / 4 * 12.9 = 3302 mV so x1 ADC scale. Plotting full range input would be 125 scope displays tall!

• Posts: 13,893
edited 2018-11-24 12:23
This is a total game changer! I really didn't know that this was even possible on our little ADC. And it's so simple!!! (After it didn't make any sense for 12 years.)

These Sinc2/Sinc3/Sinc4 methods give way better resolution than the first-order counting method, and no windowing is required to cut noise. I think this is the way to go.

Can anyone say if there's any reason to pursue first-order summing with windowing? I don't know that there is, anymore. Man, I've sure learned a lot over the past week.

We just need to decide on Sinc2 or Sinc3, if this is the way to go. I lean toward Sinc3 because it's visibly better. Sinc4 must be better, yet, but I can't tell, and its cost is higher - unless we kept measurements really short. I think Sinc3 is the happy balance.

Thanks so much, Guys, for pursuing this. This is going to make the P2 way better. I almost can't believe it. I'll have to get used to this.
• Posts: 14,024
I gather the rounded ripple like look of each step is limitation of DAC or scope connection. That's stepping at something like 15 Msps.

• Posts: 13,893
Here is what the code that must run in the cog will look like for various Sinc-N possibilities.

Sinc2:
```	rdpin	acc2,#adc

sub	z,diff2
sub	z,diff1

mov	diff2,acc2		'update diff's
sub	diff2,diff1

mov	diff1,acc2
```

Sinc3:
```	rdpin	acc3,#adc

sub	z,diff3
sub	z,diff2
sub	z,diff1

mov	diff3,acc3		'update diff's
sub	diff3,diff2
sub	diff3,diff1

mov	diff2,acc3
sub	diff2,diff1

mov	diff1,acc3
```

Sinc4:
```	rdpin	acc4,#adc

sub	z,diff4
sub	z,diff3
sub	z,diff2
sub	z,diff1

mov	diff4,acc4		'update diff's
sub	diff4,diff3
sub	diff4,diff2
sub	diff4,diff1

mov	diff3,acc4
sub	diff3,diff2
sub	diff3,diff1

mov	diff2,acc4
sub	diff2,diff1

mov	diff1,acc4
```
• Posts: 13,893
evanh wrote: »
I gather the rounded ripple like look of each step is limitation of DAC or scope connection. That's stepping at something like 15 Msps.

That's right. Ah! I should have use the 123-ohm DAC mode.
• Posts: 1,716
Hi chip, the sin looks really good. I' will be away for a week or so and I could make another try to remove the ripple, if I have the data. @evanh if you could somehow manage to create a data file, that would be great. When is the closing date to work on this issue?
• Posts: 13,893
ErNa wrote: »
Hi chip, the sin looks really good. I' will be away for a week or so and I could make another try to remove the ripple, if I have the data. @evanh if you could somehow manage to create a data file, that would be great. When is the closing date to work on this issue?

We have three to five more weeks, I think.
• Posts: 13,893
It's amazing what we can get in 16 clocks, but it's kind of useless when the ADC's front-end analog circuit is only good for a few MHz.
• Posts: 14,024
edited 2018-11-24 13:20
ErNa wrote: »
... if I have the data. @evanh if you could somehow manage to create a data file, that would be great.

Oz produced some real ADC bitstream. - https://forums.parallax.com/discussion/comment/1455002/#Comment_1455002

EDIT: Although I'm unsure of acquisition arrangement, he says it is 8 channels but I don't see any groups in the data file.

EDIT2: Oh, since it's stored as 8-bit number per text line, it's probably one clock per line.
• Posts: 1,716
Ok, that will fit. Just three to five weeks to end this chapter ;-) Measuring analog signals at one MHz is great, filtering in the front end enhances resolution and noise level. Thats good enough. Higher frequencies automaticaly show more phase error, what is not good at all in terms of signal quality. So what we get here is just an optimum.
• Posts: 2,043
cgracey wrote: »
This is a total game changer! I really didn't know that this was even possible on our little ADC. And it's so simple!!! (After it didn't make any sense for 12 years.)

These Sinc2/Sinc3/Sinc4 methods give way better resolution than the first-order counting method, and no windowing is required to cut noise. I think this is the way to go.

Can anyone say if there's any reason to pursue first-order summing with windowing? I don't know that there is, anymore. Man, I've sure learned a lot over the past week.

We just need to decide on Sinc2 or Sinc3, if this is the way to go. I lean toward Sinc3 because it's visibly better. Sinc4 must be better, yet, but I can't tell, and its cost is higher - unless we kept measurements really short. I think Sinc3 is the happy balance.

Thanks so much, Guys, for pursuing this. This is going to make the P2 way better. I almost can't believe it. I'll have to get used to this.

Could LUT data be streamed to a smart pin's ADC accumulator for arbitrary windows? Or a group of pins?
• Posts: 13,893
TonyB_ wrote: »
cgracey wrote: »
This is a total game changer! I really didn't know that this was even possible on our little ADC. And it's so simple!!! (After it didn't make any sense for 12 years.)

These Sinc2/Sinc3/Sinc4 methods give way better resolution than the first-order counting method, and no windowing is required to cut noise. I think this is the way to go.

Can anyone say if there's any reason to pursue first-order summing with windowing? I don't know that there is, anymore. Man, I've sure learned a lot over the past week.

We just need to decide on Sinc2 or Sinc3, if this is the way to go. I lean toward Sinc3 because it's visibly better. Sinc4 must be better, yet, but I can't tell, and its cost is higher - unless we kept measurements really short. I think Sinc3 is the happy balance.

Thanks so much, Guys, for pursuing this. This is going to make the P2 way better. I almost can't believe it. I'll have to get used to this.

Could LUT data be streamed to a smart pin's ADC accumulator for arbitrary windows? Or a group of pins?

There is no conduit for that. What are you thinking about?
• Posts: 2,043
cgracey wrote: »
TonyB_ wrote: »
cgracey wrote: »
This is a total game changer! I really didn't know that this was even possible on our little ADC. And it's so simple!!! (After it didn't make any sense for 12 years.)

These Sinc2/Sinc3/Sinc4 methods give way better resolution than the first-order counting method, and no windowing is required to cut noise. I think this is the way to go.

Can anyone say if there's any reason to pursue first-order summing with windowing? I don't know that there is, anymore. Man, I've sure learned a lot over the past week.

We just need to decide on Sinc2 or Sinc3, if this is the way to go. I lean toward Sinc3 because it's visibly better. Sinc4 must be better, yet, but I can't tell, and its cost is higher - unless we kept measurements really short. I think Sinc3 is the happy balance.

Thanks so much, Guys, for pursuing this. This is going to make the P2 way better. I almost can't believe it. I'll have to get used to this.

Could LUT data be streamed to a smart pin's ADC accumulator for arbitrary windows? Or a group of pins?

There is no conduit for that. What are you thinking about?

Just a thought. It could be a way of applying any sort of window to the bitstream in real-time, but it seems that and Tukey have been superseded now.
• Posts: 13,893
TonyB_ wrote: »
cgracey wrote: »
TonyB_ wrote: »
cgracey wrote: »
This is a total game changer! I really didn't know that this was even possible on our little ADC. And it's so simple!!! (After it didn't make any sense for 12 years.)

These Sinc2/Sinc3/Sinc4 methods give way better resolution than the first-order counting method, and no windowing is required to cut noise. I think this is the way to go.

Can anyone say if there's any reason to pursue first-order summing with windowing? I don't know that there is, anymore. Man, I've sure learned a lot over the past week.

We just need to decide on Sinc2 or Sinc3, if this is the way to go. I lean toward Sinc3 because it's visibly better. Sinc4 must be better, yet, but I can't tell, and its cost is higher - unless we kept measurements really short. I think Sinc3 is the happy balance.

Thanks so much, Guys, for pursuing this. This is going to make the P2 way better. I almost can't believe it. I'll have to get used to this.

Could LUT data be streamed to a smart pin's ADC accumulator for arbitrary windows? Or a group of pins?

There is no conduit for that. What are you thinking about?

Just a thought. It could be a way of applying any sort of window to the bitstream in real-time, but it seems that and Tukey have been superseded now.

I'm running lots of tests on this Sinc3 method and it just beats the pants off any first-order approach.
• Posts: 2,474
cgracey wrote: »
It's amazing what we can get in 16 clocks, but it's kind of useless when the ADC's front-end analog circuit is only good for a few MHz.

I've only been marginally following this conversation. What do you mean when you say "only good for a few MHz"?
• Posts: 426
TonyB_ wrote: »
Could LUT data be streamed to a smart pin's ADC accumulator for arbitrary windows? Or a group of pins?
Isn't that what the Goertzel hardware does? It was intended operate as a DDS, but we could load the LUT with a window function and set the NCO to step one step per clock.

I'm thinking it's ok to only expose the third accumulator. As long as we still have access to the raw bitstream somehow, we can do whatever we want. Not sure why someone would want first or second order other than to go longer between accumulator reads. Maybe for occasional ADC reads, but if the readings are so much worse... I could see a use for a bandpass filter, that is basically Goertzel mode.

I think is would be useful if the sinc3 and Goertzel hardware were able to operate on a digital input. (1 bit) There are ADCs that output the sigma-delta bitstream. It would be nice if the P2 ADC processing could be applied to these as well. I still haven't found the documentation for the P2 ADC, does the sigma-delta bitstream replace the digital input when in analog mode? If that is the case then it should be possible.
• Posts: 4,094
• Posts: 14,994
edited 2018-11-24 20:50
cgracey wrote: »
We just need to decide on Sinc2 or Sinc3, if this is the way to go. I lean toward Sinc3 because it's visibly better. Sinc4 must be better, yet, but I can't tell, and its cost is higher - unless we kept measurements really short. I think Sinc3 is the happy balance..

Do you have a table of Logic Cost yet - SincN vs LUTs added ?
That will for a key part of the decision.

I presume the sample-depths here (Up to the rollover limit) will be user selectable.

Q: Will this also work on an external bitstream ?

There are (many) isolated ADCs that export raw SDM samples at 10~20 MHz clocks, (choice of CLK in or CLK out models) plus there are external (D-FF+OpAmp) ADC designs.

ACPL-7970-300E 10MHz 78dB 16b 6 µV/°C ADC opto DAT out CLK out ]
(similar to TLP7930,TLP7930F )

ACPL-C740 20MHz 83dB 16b 2 µV/°C ADC opto DAT out CLK out Stretched SO-8 Package \$2.44/1k << newer and better
TI: AMC1303x SO-8, 10MHz & 20MHz \$3.44/1k << higher price but netter specs again
• Excellent DC Performance:
– Offset Error: ±50 µV or ±100 µV (max)
– Offset Drift: ±1 µV/°C (max)
– Gain Error: ±0.2% (max)
– Gain Drift: ±40 ppm/°C (max)
• Transient Immunity: 100 kV/µs (typ)

says:

By using an integrated digital filter (such as those in the TMS320F2807x or TMS320F2837x microcontroller families) to decimate the bitstream, the device can achieve 16 bits of resolution with a dynamic range of 85 dB at an effective output data rate of 78 kSPS.

20M/256 = 78125, so they expect 256 samples per result.

Addit: TI show as new a 1V model, AMC1035 DAT out CLK in \$1.50/1k - cheaper, has VREF out and CLK in
• Delta-Sigma Modulator Optimized for Voltage and Temperature Sensing:
– ±1-V Input Voltage Range
– High Differential Input Resistance: 1.6 GΩ (typ)
– Integrated 2.5-V, ±5-mA Reference for Ratiometric Measurement
• Excellent DC Performance:
– Offset Error: ±0.5 mV (max)
– Offset Drift: ±6 µV/°C (max)
– Gain Error: ±0.25% (max)
– Gain Drift: ±45 ppm/°C (max)
– Ratiometric Gain Drift: ±15 ppm/°C (max)
- Dynamic range of 87 dB

TI also sell a SincN modulator chip, http://www.ti.com/lit/ds/symlink/amc1210.pdf
• Posts: 14,994
Seairth wrote: »
I've only been marginally following this conversation. What do you mean when you say "only good for a few MHz"?

I think Chip means the Analog parts - internal current mirrors and tracking amplifiers etc, have a bandwidth of 'some MHz', not the sampling clock itself, which is SysCLK based > 250MHz.
Plus the resistors involved are designed for low power, so add another roll off.

ie Likely good for AC power inverter current sense, but are going to be pushed if anyone tried to digitize video...
• Posts: 1,716
ozpropdev wrote: »
@ErNa
Here's some real streams from P2 silicon.
8 channels of bitstream x 64000 clocks
Made some first experiments. Looks indeed, 8bit in hex and every bit is a bitstream. What was the clock rate? The at 128 mhz 64ksps are about 0.5 ms?
And 1MHz of sinusoid has 128 Samples/period?
• Posts: 13,893
edited 2018-11-24 21:46
Yes, when a pin is in ADC mode, its delta-sigma stream is fed into the IN signal, regardless of any smart pin mode on top of that.

The Sinc3 mode will look at the IN signal from the low-level pin, which could be in ADC mode or some other mode.

It's possible to build the integrator outside the pin, using a coupling cap and clocked negative-feedback logic mode with resistive drive (%0001_101001001, I believe, for 1.5k). Then, you certainly overcome the internal bandwidth problem of the ADC, but need a lower-impedance source. I will try this in a little bit.
• Posts: 13,893
T Chap wrote: »