aboutsummaryrefslogtreecommitdiffstats
path: root/src/atsamd/adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atsamd/adc.c')
-rw-r--r--src/atsamd/adc.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/atsamd/adc.c b/src/atsamd/adc.c
index a48a5471..a5436982 100644
--- a/src/atsamd/adc.c
+++ b/src/atsamd/adc.c
@@ -12,7 +12,26 @@
#define ADC_TEMPERATURE_PIN 0xfe
DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN);
-#if CONFIG_MACH_SAMD21
+#if CONFIG_MACH_SAMC21
+
+#define ADC_INPUTCTRL_MUXNEG_GND 0x18
+
+#define SAMD51_ADC_SYNC(ADC, BIT) \
+ while(ADC->SYNCBUSY.reg & ADC_SYNCBUSY_ ## BIT)
+static const uint8_t adc_pins[] = {
+ /* ADC0 */
+ GPIO('A', 2), GPIO('A', 3), GPIO('B', 8), GPIO('B', 9), GPIO('A', 4),
+ GPIO('A', 5), GPIO('A', 6), GPIO('A', 7), GPIO('A', 8), GPIO('A', 9),
+ GPIO('A', 10), GPIO('A', 11),
+ /* Padding to 16 */
+ 255, 255, 255, 255,
+ /* ADC1 */
+ GPIO('B', 0), GPIO('B', 1), GPIO('B', 2), GPIO('B', 3), GPIO('B', 8),
+ GPIO('B', 9), GPIO('B', 4), GPIO('B', 5), GPIO('B', 6), GPIO('B', 7),
+ GPIO('A', 8), GPIO('A', 9)
+};
+
+#elif CONFIG_MACH_SAMD21
#define SAMD51_ADC_SYNC(ADC, BIT)
static const uint8_t adc_pins[] = {
@@ -21,6 +40,7 @@ static const uint8_t adc_pins[] = {
GPIO('B', 2), GPIO('B', 3), GPIO('B', 4), GPIO('B', 5), GPIO('B', 6),
GPIO('B', 7), GPIO('A', 8), GPIO('A', 9), GPIO('A', 10), GPIO('A', 11)
};
+
#elif CONFIG_MACH_SAMX5
#define SAMD51_ADC_SYNC(ADC, BIT) \
@@ -53,7 +73,7 @@ static struct gpio_adc gpio_adc_pin_to_struct(uint8_t pin)
}
#if CONFIG_MACH_SAMD21
Adc* reg = ADC;
-#elif CONFIG_MACH_SAMX5
+#elif CONFIG_MACH_SAMC21 || CONFIG_MACH_SAMX5
Adc* reg = (chan < 16 ? ADC0 : ADC1);
chan %= 16;
#endif
@@ -69,7 +89,38 @@ adc_init(void)
return;
have_run_init = 1;
-#if CONFIG_MACH_SAMD21
+#if CONFIG_MACH_SAMC21
+ // Enable adc clock
+ enable_pclock(ADC0_GCLK_ID, ID_ADC0);
+ enable_pclock(ADC1_GCLK_ID, ID_ADC1);
+
+ // Load calibration info
+ // ADC0
+ uint32_t refbuf = GET_FUSE(ADC0_FUSES_BIASREFBUF);
+ uint32_t comp = GET_FUSE(ADC0_FUSES_BIASCOMP);
+ ADC0->CALIB.reg = (ADC0_FUSES_BIASREFBUF(refbuf)
+ | ADC0_FUSES_BIASCOMP(comp));
+
+ // ADC1
+ refbuf = GET_FUSE(ADC1_FUSES_BIASREFBUF);
+ comp = GET_FUSE(ADC1_FUSES_BIASCOMP);
+ ADC1->CALIB.reg = (ADC0_FUSES_BIASREFBUF(refbuf)
+ | ADC0_FUSES_BIASCOMP(comp));
+
+ // Setup and enable
+ // ADC0
+ ADC0->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC1;
+ ADC0->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV128;
+ ADC0->SAMPCTRL.reg = ADC_SAMPCTRL_SAMPLEN(63);
+ ADC0->CTRLA.reg = ADC_CTRLA_ENABLE;
+
+ // ADC1
+ ADC1->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC1;
+ ADC1->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV128;
+ ADC1->SAMPCTRL.reg = ADC_SAMPCTRL_SAMPLEN(63);
+ ADC1->CTRLA.reg = ADC_CTRLA_ENABLE;
+
+#elif CONFIG_MACH_SAMD21
// Enable adc clock
enable_pclock(ADC_GCLK_ID, ID_ADC);
// Load calibraiton info
@@ -135,7 +186,7 @@ gpio_adc_setup(uint8_t pin)
SYSCTRL->VREF.reg |= SYSCTRL_VREF_TSEN;
return (struct gpio_adc){ .regs=ADC,
.chan=ADC_INPUTCTRL_MUXPOS_TEMP_Val };
-#else
+#elif CONFIG_MACH_SAMX5
SUPC->VREF.reg |= SUPC_VREF_TSEN;
return (struct gpio_adc){ .regs=ADC0,
.chan=ADC_INPUTCTRL_MUXPOS_PTAT_Val };