Skip to content

Commit c3e5bc7

Browse files
committed
Merge branch 'zero-core' into zero-package
2 parents b16baa6 + cf2be17 commit c3e5bc7

File tree

5 files changed

+274
-1
lines changed

5 files changed

+274
-1
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/*
2+
This sketch easily and quickly finds the right ADC correction values for a particular Arduino ZERO board.
3+
The correction values that are found are only valid for the board where the sketch is executed.
4+
5+
This example code is in the public domain.
6+
7+
Written 6 May 2015 by Claudio Indellicati
8+
*/
9+
10+
/*
11+
How to use this sketch
12+
13+
1) Remove any connection cable, shield or jumper from your Arduino ZERO
14+
2) Connect pin A1 to the nearest GND pin using the shortest jumper possible
15+
3) Connect pin A2 to the 3.3V pin using the shortest jumper possible
16+
4) Connect the Arduino ZERO to your PC using a USB cable plugged in the USB programming port of the board
17+
5) Upload this sketch and leave the board powered on for at least one minute
18+
6) Open the Serial Monitor and press the reset button on the Arduino ZERO
19+
7) At the and of the procedure you can find logged
20+
- the offset and gain values for the board where the sketch has been just executed
21+
- the instruction line to copy/paste in the final sketch
22+
*/
23+
24+
#include "SAMD_AnalogCorrection.h"
25+
26+
#define ADC_GND_PIN A1
27+
#define ADC_3V3_PIN A2
28+
29+
#define ADC_READS_SHIFT 8
30+
#define ADC_READS_COUNT (1 << ADC_READS_SHIFT)
31+
32+
#define ADC_MIN_GAIN 0x0400
33+
#define ADC_UNITY_GAIN 0x0800
34+
#define ADC_MAX_GAIN (0x1000 - 1)
35+
#define ADC_RESOLUTION_BITS 12
36+
#define ADC_RANGE (1 << ADC_RESOLUTION_BITS)
37+
#define ADC_TOP_VALUE (ADC_RANGE - 1)
38+
39+
#define MAX_TOP_VALUE_READS 10
40+
41+
void setup()
42+
{
43+
Serial.begin(9600);
44+
45+
Serial.println("\r\nCalibrating ADC with factory values");
46+
47+
analogReadResolution(ADC_RESOLUTION_BITS);
48+
49+
Serial.println("\r\nReading GND and 3.3V ADC levels");
50+
Serial.print(" ");
51+
readGndLevel();
52+
Serial.print(" ");
53+
read3V3Level();
54+
55+
int offsetCorrectionValue = 0;
56+
uint16_t gainCorrectionValue = ADC_UNITY_GAIN;
57+
58+
Serial.print("\r\nOffset correction (@gain = ");
59+
Serial.print(gainCorrectionValue);
60+
Serial.println(" (unity gain))");
61+
62+
// Set default correction values and enable correction
63+
analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
64+
65+
for (int offset = 0; offset < (int)(ADC_OFFSETCORR_MASK >> 1); ++offset)
66+
{
67+
analogReadCorrection(offset, gainCorrectionValue);
68+
69+
Serial.print(" Offset = ");
70+
Serial.print(offset);
71+
Serial.print(", ");
72+
73+
if (readGndLevel() == 0)
74+
{
75+
offsetCorrectionValue = offset;
76+
break;
77+
}
78+
}
79+
80+
Serial.println("\r\nGain correction");
81+
82+
uint8_t topValueReadsCount = 0U;
83+
84+
uint16_t minGain = 0U,
85+
maxGain = 0U;
86+
87+
analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
88+
Serial.print(" Gain = ");
89+
Serial.print(gainCorrectionValue);
90+
Serial.print(", ");
91+
uint16_t highLevelRead = read3V3Level();
92+
93+
if (highLevelRead < ADC_TOP_VALUE)
94+
{
95+
for (uint16_t gain = ADC_UNITY_GAIN + 1; gain <= ADC_MAX_GAIN; ++gain)
96+
{
97+
analogReadCorrection(offsetCorrectionValue, gain);
98+
99+
Serial.print(" Gain = ");
100+
Serial.print(gain);
101+
Serial.print(", ");
102+
highLevelRead = read3V3Level();
103+
104+
if (highLevelRead == ADC_TOP_VALUE)
105+
{
106+
if (minGain == 0U)
107+
minGain = gain;
108+
109+
if (++topValueReadsCount >= MAX_TOP_VALUE_READS)
110+
{
111+
maxGain = minGain;
112+
break;
113+
}
114+
115+
maxGain = gain;
116+
}
117+
118+
if (highLevelRead > ADC_TOP_VALUE)
119+
break;
120+
}
121+
}
122+
else if (highLevelRead >= ADC_TOP_VALUE)
123+
{
124+
if (highLevelRead == ADC_TOP_VALUE)
125+
maxGain = ADC_UNITY_GAIN;
126+
127+
for (uint16_t gain = ADC_UNITY_GAIN - 1; gain >= ADC_MIN_GAIN; --gain)
128+
{
129+
analogReadCorrection(offsetCorrectionValue, gain);
130+
131+
Serial.print(" Gain = ");
132+
Serial.print(gain);
133+
Serial.print(", ");
134+
highLevelRead = read3V3Level();
135+
136+
if (highLevelRead == ADC_TOP_VALUE)
137+
{
138+
if (maxGain == 0U)
139+
maxGain = gain;
140+
141+
minGain = gain;
142+
}
143+
144+
if (highLevelRead < ADC_TOP_VALUE)
145+
break;
146+
}
147+
}
148+
149+
gainCorrectionValue = (minGain + maxGain) >> 1;
150+
151+
analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
152+
153+
Serial.println("\r\nReadings after corrections");
154+
Serial.print(" ");
155+
readGndLevel();
156+
Serial.print(" ");
157+
read3V3Level();
158+
159+
Serial.println("\r\n==================");
160+
Serial.println("\r\nCorrection values:");
161+
Serial.print(" Offset = ");
162+
Serial.println(offsetCorrectionValue);
163+
Serial.print(" Gain = ");
164+
Serial.println(gainCorrectionValue);
165+
Serial.println("\r\nAdd the next line to your sketch:");
166+
Serial.print(" analogReadCorrection(");
167+
Serial.print(offsetCorrectionValue);
168+
Serial.print(", ");
169+
Serial.print(gainCorrectionValue);
170+
Serial.println(");");
171+
Serial.println("\r\n==================");
172+
}
173+
174+
void loop()
175+
{
176+
}
177+
178+
uint16_t readGndLevel()
179+
{
180+
uint32_t readAccumulator = 0;
181+
182+
for (int i = 0; i < ADC_READS_COUNT; ++i)
183+
readAccumulator += analogRead(ADC_GND_PIN);
184+
185+
uint16_t readValue = readAccumulator >> ADC_READS_SHIFT;
186+
187+
Serial.print("ADC(GND) = ");
188+
Serial.println(readValue);
189+
190+
return readValue;
191+
}
192+
193+
uint16_t read3V3Level()
194+
{
195+
uint32_t readAccumulator = 0;
196+
197+
for (int i = 0; i < ADC_READS_COUNT; ++i)
198+
readAccumulator += analogRead(ADC_3V3_PIN);
199+
200+
uint16_t readValue = readAccumulator >> ADC_READS_SHIFT;
201+
202+
if (readValue < (ADC_RANGE >> 1))
203+
readValue += ADC_RANGE;
204+
205+
Serial.print("ADC(3.3V) = ");
206+
Serial.println(readValue);
207+
208+
return readValue;
209+
}
210+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name=SAMD_AnalogCorrection
2+
version=1.0
3+
author=Arduino
4+
maintainer=Arduino <info@arduino.cc>
5+
sentence=Sets and enables the digital correction logic of the SAMD ADC.
6+
paragraph=Useful to correct the values returned by the ADC.
7+
url=
8+
architectures=samd
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright (c) 2015 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#include "SAMD_AnalogCorrection.h"
20+
21+
void analogReadCorrection (int offset, uint16_t gain)
22+
{
23+
// Set correction values
24+
ADC->OFFSETCORR.reg = ADC_OFFSETCORR_OFFSETCORR(offset);
25+
ADC->GAINCORR.reg = ADC_GAINCORR_GAINCORR(gain);
26+
27+
// Enable digital correction logic
28+
ADC->CTRLB.bit.CORREN = 1;
29+
while(ADC->STATUS.bit.SYNCBUSY);
30+
}
31+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright (c) 2015 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#pragma once
20+
21+
#include <Arduino.h>
22+
23+
void analogReadCorrection (int offset, uint16_t gain);
24+

platform.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,5 @@ tools.openocd.erase.pattern=
139139

140140
tools.openocd.bootloader.params.verbose=-d2
141141
tools.openocd.bootloader.params.quiet=-d0
142-
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; at91samd bootloader 0; program {{{runtime.platform.path}/bootloaders/{bootloader.file}}} verify reset; shutdown"
142+
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{{runtime.platform.path}/bootloaders/{bootloader.file}}} verify reset; shutdown"
143143

0 commit comments

Comments
 (0)