Due ADC initialization bug? ADC Startup time too slow?

56 views
Skip to first unread message

Gabriel Staples

unread,
Sep 16, 2015, 2:54:35 AM9/16/15
to Developers
I recently stumbled across this article, which leads me to believe there is need for some changes in the ADC initialization for the Due: http://www.djerickson.com/arduino/

Referring to: Arduino/hardware/arduino/sam/system/libsam/include/adc.h

ADC_FREQ_MAX is set to 20000000. I think it should be 22000000, per the datasheet, pg. 1403, max ADC Clock Freq = 22Mhz.

ADC_STARTUP_NORM is 40. This doesn't make sense at all. Pg. 1334 shows valid values are 0 through 15 (0 through F in Hex for that nibble, bits 16-19, in the REG_ADC_MR)

ADC_STARTUP_FAST is 12. How is this fast at all??? Per datasheet pg. 1334, 12 --> 768 pds of ADCClock, which is 1/21MHz x 768 = 36.57us. That is one of the slowest startup options available. Shouldn't we use something more like 2 for the startup value instead?

Why such a long startup? 

With startup of 12, the first link above, by djerickson, says each analogRead() in a tight loop takes ~39us. 36.57us of that is the ADC startup time. If we change ADC_STARTUP_FAST to 2 we'd get each sample down to ~4us, which is much much better.

Conclusions:
  1. The ADC_STARTUP_NORM 40 looks like a bug.
  2. We should make ADC_STARTUP_NORM 12, and ADC_STARTUP_FAST 2
  3. Are there certain reasons for making a long startup?
  4. ADC_FREQ_MAX should be 22000000 not 20000000.
Thoughts?

Tyler Freeman

unread,
Sep 16, 2015, 2:14:24 PM9/16/15
to devel...@arduino.cc

Hey Gabriel!

Thanks for the research! Do you have a pull request for this? I have a Due project that needs fast ADC and I'd love to try out your changes to see if they work!

Tyler


--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

Gabriel Staples

unread,
Sep 16, 2015, 2:47:30 PM9/16/15
to devel...@arduino.cc
Hi Tyler,

No pull request yet, as I wanted to open the discussion first to see if there's something I'm missing...ie: some reason why it was done this way. Somebody wrote it this way and may have a reason I don't see yet. 

What kind of project you working on that needs fast ADC? And how fast? The Due's max sample rate is 1MSps according to the datasheet.

Nevertheless, I'm working on an expansion to my NewAnalogRead library (http://www.electricrcaircraftguy.com/2014/05/using-arduino-unos-built-in-16-bit-adc.html) which I originally wrote for the Uno, which will increase the Due's sample rate from ~25kHz to ~250kHz, and increase resolution from 12-bit to up to 16-bit (though increased resolution comes at the cost of speed, since I'm using oversampling). I may have a version done by tonight or tomorrow. It will need testing of course. You interested? 

Honestly I don't even have a Due yet, I'm about to order one.


Thank you!

Sincerely, 

Gabriel Staples

Thibaut VIARD

unread,
Sep 16, 2015, 3:26:19 PM9/16/15
to devel...@arduino.cc

Hi Gabriel,

I may have a partial answer about the parameters: when we implemented the Due core the SAM3X documentation was almost new and the product has been fully characterized since 2011, thus the documentation updated according to results on production parts.

I agree some refresh is needed.

If you are ready to provide a patch, don't hesitate to send it.

Else i will take a look as soon as possible.

Regards,

Thibaut

Tyler

unread,
Sep 16, 2015, 4:29:20 PM9/16/15
to devel...@arduino.cc
We'd need fast ADC for the DrumPants ( http://drumpants.com ), which are an open source, Due-compatible musical instrument. Precision is not as much as a concern, since we have to downsample to 7-bit for MIDI anyway. But faster/more accurate ADC might help give them the response drummers want... or it may not. Either way, I'd love to test them out with your changes!

Thanks!

Tyler

Cristian Maglie

unread,
Sep 16, 2015, 4:54:17 PM9/16/15
to devel...@arduino.cc

Hi Gabriel,

The link you posted is very old and all the issues have been already
solved almost two years ago. I guess that most of your questions may be
answered by looking here:

https://github.com/arduino/Arduino/issues/1418

> Referring to: Arduino/hardware/arduino/sam/system/libsam/include/adc.h
> (https://github.com/arduino/Arduino/blob/bd8f7932e64fb3a41e3d934437d5eabd8707dcc9/hardware/arduino/sam/system/libsam/include/adc.h)
>
> ADC_FREQ_MAX is set to 20000000. I think it should be 22000000, per the
> datasheet, pg. 1403, max ADC Clock Freq = 22Mhz.

Atmel has changed the datasheet. I'm 100% sure that the maximum rated
frequency was 20MHz.

I'm not sure what to think now: the new SAM3X chip may run ADC at 22Mhz?
or maybe Atmel did more tests and discovered that 22Mhz was good also
for the old chips? or maybe is just an error in the datasheet?

> ADC_STARTUP_NORM is 40. This doesn't make sense at all. Pg. 1334 shows
> valid values are 0 through 15 (0 through F in Hex for that nibble, bits
> 16-19, in the REG_ADC_MR)

The adc_init() function writes the correct value into the register,
according to the datasheet conversion table.

This is the fix I've applied at the times

https://github.com/arduino/Arduino/commit/40dce96f1173dfba5f667b0c289687ac3d92506b


> ADC_STARTUP_FAST is 12. How is this fast at all??? Per datasheet pg.
> 1334, 12 --> 768 pds of ADCClock, which is 1/21MHz x 768 = 36.57us. That
> is one of the slowest startup options available. Shouldn't we use
> something more like 2 for the startup value instead?
>
> Why such a long startup?

Because it's needed for the ADC to work properly (see the github's issue
above for details...)

> With startup of 12, the first link above, by djerickson, says each
> analogRead() in a tight loop takes ~39us. 36.57us of that is the ADC
> startup time. If we change ADC_STARTUP_FAST to 2 we'd get each sample
> down to ~4us, which is much much better.

The good news (that is not written on the djerickson website) is that if
the ADC is kept enabled the startup time is applied only to the first
conversion and all the subsequent conversion are much faster
(approaching 1Msps, but the 84MHz clock of the Due's setup allows only
700Ksps maximum, again see the issue linked at the beginning to
understand why).

At the time when djerickson wrote his article, the analogRead() function
used to enable and disable ADC every time, so the startup time was
applied at every conversion. The correct fix is to leave the startup
time as is and keep the ADC enabled in analogRead(), and this is the fix
we applied on the Due.

Just reducing the startup time as suggested in djerickson's article may
lead to ADC not working properly.

C


--
Cristian Maglie <c.ma...@arduino.cc>

Tom Igoe

unread,
Sep 16, 2015, 6:26:23 PM9/16/15
to devel...@arduino.cc
Drum pants!  We had a project like that in 2011, it was a lotta fun: http://work.antoni.us/Drop-It-Like-It-s-Crotch


Tom Igoe


Tyler

unread,
Sep 16, 2015, 8:50:11 PM9/16/15
to devel...@arduino.cc
haha awesome. Just don't miss, or it might hurt a lot!
Reply all
Reply to author
Forward
0 new messages