8000 atmel-samd: Support multiple ADC channels at once. · pcurry/circuitpython@179413a · GitHub
[go: up one dir, main page]

Skip to content

Commit 179413a

Browse files
committed
atmel-samd: Support multiple ADC channels at once.
Fixes adafruit#61
1 parent d239dbd commit 179413a

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

atmel-samd/common-hal/nativeio/AnalogIn.c

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <string.h>
2828

29+
#include "py/gc.h"
2930
#include "py/nlr.h"
3031
#include "py/runtime.h"
3132
#include "py/binary.h"
@@ -35,6 +36,10 @@
3536
#include "asf/sam0/drivers/adc/adc.h"
3637
#include "samd21_pins.h"
3738

39+
// Number of active ADC channels.
40+
volatile uint8_t active_channel_count;
41+
struct adc_module *adc_instance = NULL;
42+
3843
void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self,
3944
const mcu_pin_obj_t *pin) {
4045
if (!pin->has_adc) {
@@ -44,42 +49,55 @@ void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self,
4449

4550
self->pin = pin;
4651

47-
struct adc_config config_adc;
48-
adc_get_config_defaults(&config_adc);
52+
if (adc_instance == NULL) {
53+
struct adc_config config_adc;
54+
adc_get_config_defaults(&config_adc);
55+
56+
config_adc.reference = ADC_REFERENCE_INTVCC1;
57+
config_adc.gain_factor = ADC_GAIN_FACTOR_DIV2;
58+
config_adc.positive_input = self->pin->adc_input;
59+
config_adc.resolution = ADC_RESOLUTION_16BIT;
60+
config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV128;
61+
62+
// Allocate the instance on the heap so we only use the memory when we
63+
// need it.
64+
adc_instance = gc_alloc(sizeof(struct adc_module), false);
4965

50-
config_adc.reference = ADC_REFERENCE_INTVCC1;
51-
config_adc.gain_factor = ADC_GAIN_FACTOR_DIV2;
52-
config_adc.positive_input = self->pin->adc_input;
53-
config_adc.resolution = ADC_RESOLUTION_16BIT;
54-
config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV128;
66+
adc_init(adc_instance, ADC, &config_adc);
67+
}
5568

56-
adc_init(&self->adc_instance, ADC, &config_adc);
69+
self->adc_instance = adc_instance;
70+
active_channel_count++;
5771
}
5872

5973
void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t *self) {
60-
// TODO(tannewt): Count how many pins are in use and only reset the ADC when
61-
// none are used.
62-
adc_reset(&self->adc_instance);
74+
active_channel_count--;
75+
if (active_channel_count == 0) {
76+
adc_reset(adc_instance);
77+
gc_free(adc_instance);
78+
// Set our reference to NULL so the GC doesn't mistakenly see the
79+
// pointer in memory.
80+
adc_instance = NULL;
81+
}
6382
reset_pin(self->pin->pin);
6483
}
6584

66-
// TODO(tannewt): Don't turn it all on just for one read. This simplifies
67-
// handling of reading multiple inputs and surviving sleep though so for now its
68-
// ok.
6985
uint16_t common_hal_nativeio_analogin_get_value(nativeio_analogin_obj_t *self) {
70-
adc_enable(&self->adc_instance);
71-
adc_start_conversion(&self->adc_instance);
86+
adc_set_positive_input(adc_instance, self->pin->adc_input);
87+
88+
adc_enable(adc_instance);
89+
adc_start_conversion(adc_instance);
7290

7391
uint16_t data;
74-
enum status_code status = adc_read(&self->adc_instance, &data);
92+
enum status_code status = adc_read(adc_instance, &data);
7593
while (status == STATUS_BUSY) {
76-
status = adc_read(&self->adc_instance, &data);
94+
status = adc_read(adc_instance, &data);
7795
}
7896
if (status == STATUS_ERR_OVERFLOW) {
7997
// TODO(tannewt): Throw an error.
8098
}
8199

82-
adc_disable(&self->adc_instance);
100+
adc_disable(adc_instance);
83101
return data;
84102
}
85103

atmel-samd/common-hal/nativeio/types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
typedef struct {
5656
mp_obj_base_t base;
5757
const mcu_pin_obj_t * pin;
58-
struct adc_module adc_instance;
58+
struct adc_module * adc_instance;
5959
} nativeio_analogin_obj_t;
6060

6161
typedef struct {

0 commit comments

Comments
 (0)
0