Skip to content

Commit 902d525

Browse files
committed
DM: add ADC1 support for SAMD51
1 parent 8e9ebb1 commit 902d525

File tree

4 files changed

+53
-35
lines changed

4 files changed

+53
-35
lines changed

cores/arduino/WVariant.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ typedef enum _EPioType
259259
#define PIN_ATTR_TIMER (1UL<<4)
260260
#define PIN_ATTR_TIMER_ALT (1UL<<5)
261261
#define PIN_ATTR_EXTINT (1UL<<6)
262+
#define PIN_ATTR_ANALOG_ALT (1UL<<7)
262263

263264
/* Types used for the table below */
264265
typedef struct _PinDescription

cores/arduino/wiring.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,27 +110,30 @@ void init( void )
110110
// Setting clock
111111
#if defined(__SAMD51__)
112112
//set to 1/(1/(48000000/32) * 6) = 250000 SPS
113-
114113
GCLK->PCHCTRL[ADC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 1 (48Mhz)
115-
116-
ADC0->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV32_Val;
117-
ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
118-
119-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB ); //wait for sync
120-
121-
ADC0->SAMPCTRL.reg = 5; // sampling Time Length
122-
123-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_SAMPCTRL ); //wait for sync
124-
125-
ADC0->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND; // No Negative input (Internal Ground)
126-
127-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync
128-
129-
// Averaging (see datasheet table in AVGCTRL register description)
130-
ADC0->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // 1 sample only (no oversampling nor averaging)
131-
ADC_AVGCTRL_ADJRES(0x0ul); // Adjusting result by 0
132-
133-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_AVGCTRL ); //wait for sync
114+
GCLK->PCHCTRL[ADC1_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 1 (48Mhz)
115+
Adc *adcs[] = {ADC0, ADC1};
116+
for(int i=0; i<2; i++){
117+
118+
adcs[i]->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV32_Val;
119+
adcs[i]->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
120+
121+
while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB ); //wait for sync
122+
123+
adcs[i]->SAMPCTRL.reg = 5; // sampling Time Length
124+
125+
while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_SAMPCTRL ); //wait for sync
126+
127+
adcs[i]->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND; // No Negative input (Internal Ground)
128+
129+
while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync
130+
131+
// Averaging (see datasheet table in AVGCTRL register description)
132+
adcs[i]->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // 1 sample only (no oversampling nor averaging)
133+
ADC_AVGCTRL_ADJRES(0x0ul); // Adjusting result by 0
134+
135+
while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_AVGCTRL ); //wait for sync
136+
}
134137

135138
analogReference( AR_DEFAULT ) ; // Analog Reference is AREF pin (3.3v)
136139

cores/arduino/wiring_analog.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,21 @@ void analogReadResolution(int res)
7777

7878
if (res > 10) {
7979
ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val;
80+
ADC1->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val;
8081
_ADCResolution = 12;
8182
} else if (res > 8) {
8283
ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
84+
ADC1->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
8385
_ADCResolution = 10;
8486
} else {
8587
ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val;
88+
ADC1->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val;
8689
_ADCResolution = 8;
8790
}
8891

8992

9093
while(ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB); //wait for sync
94+
while(ADC1->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB); //wait for sync
9195
#else
9296

9397
if (res > 10) {
@@ -131,6 +135,7 @@ void analogReference(eAnalogReference mode)
131135
{
132136
#if defined(__SAMD51__)
133137
while(ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_REFCTRL); //wait for sync
138+
while(ADC1->SYNCBUSY.reg & ADC_SYNCBUSY_REFCTRL); //wait for sync
134139

135140
//TODO: fix gains
136141
switch (mode)
@@ -139,11 +144,13 @@ void analogReference(eAnalogReference mode)
139144
case AR_INTERNAL2V23:
140145
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
141146
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
147+
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
142148
break;
143149

144150
case AR_EXTERNAL:
145151
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
146152
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
153+
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
147154
break;
148155

149156
/* Don't think this works on SAMD51
@@ -156,12 +163,14 @@ void analogReference(eAnalogReference mode)
156163
case AR_INTERNAL1V65:
157164
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
158165
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
166+
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
159167
break;
160168

161169
case AR_DEFAULT:
162170
default:
163171
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
164172
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
173+
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
165174

166175
break;
167176
}
@@ -253,8 +262,13 @@ uint32_t analogRead(uint32_t pin)
253262
#endif
254263

255264
#if defined(__SAMD51__)
256-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync
257-
ADC0->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input
265+
Adc *adc;
266+
if(g_APinDescription[pin].ulPinAttribute & PIN_ATTR_ANALOG) adc = ADC0;
267+
else if(g_APinDescription[pin].ulPinAttribute & PIN_ATTR_ANALOG_ALT) adc = ADC1;
268+
else return 0;
269+
270+
while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync
271+
adc->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input
258272

259273
// Control A
260274
/*
@@ -268,27 +282,27 @@ uint32_t analogRead(uint32_t pin)
268282
* Before enabling the ADC, the asynchronous clock source must be selected and enabled, and the ADC reference must be
269283
* configured. The first conversion after the reference is changed must not be used.
270284
*/
271-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
272-
ADC0->CTRLA.bit.ENABLE = 0x01; // Enable ADC
285+
while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
286+
adc->CTRLA.bit.ENABLE = 0x01; // Enable ADC
273287

274288
// Start conversion
275-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
289+
while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
276290

277-
ADC0->SWTRIG.bit.START = 1;
291+
adc->SWTRIG.bit.START = 1;
278292

279293
// Clear the Data Ready flag
280-
ADC0->INTFLAG.reg = ADC_INTFLAG_RESRDY;
294+
adc->INTFLAG.reg = ADC_INTFLAG_RESRDY;
281295

282296
// Start conversion again, since The first conversion after the reference is changed must not be used.
283-
ADC0->SWTRIG.bit.START = 1;
297+
adc->SWTRIG.bit.START = 1;
284298

285299
// Store the value
286-
while (ADC0->INTFLAG.bit.RESRDY == 0); // Waiting for conversion to complete
287-
valueRead = ADC0->RESULT.reg;
300+
while (adc->INTFLAG.bit.RESRDY == 0); // Waiting for conversion to complete
301+
valueRead = adc->RESULT.reg;
288302

289-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
290-
ADC0->CTRLA.bit.ENABLE = 0x00; // Disable ADC
291-
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
303+
while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
304+
adc->CTRLA.bit.ENABLE = 0x00; // Disable ADC
305+
while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync
292306

293307
#else
294308
syncADC();

variants/trellis_m4/variant.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ const PinDescription g_APinDescription[]=
6565

6666
// 21..22 I2C pins (SDA/SCL)
6767
// ----------------------
68-
{ PORTB, 8, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_12 }, // SERCOM 2.0
69-
{ PORTB, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_13 }, // SERCOM 2.1
68+
{ PORTB, 8, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), ADC_Channel2, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_12 }, // SERCOM 2.0
69+
{ PORTB, 9, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG_ALT|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), ADC_Channel1, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_13 }, // SERCOM 2.1
7070

7171
// ----------------------
7272
// 23 - 28 QSPI (SCK, CS, IO0, IO1, IO2, IO3)

0 commit comments

Comments
 (0)