38
38
#include "asf/sam0/drivers/adc/adc.h"
39
39
#include "samd21_pins.h"
40
40
41
- // Number of active ADC channels.
42
- volatile uint8_t active_channel_count ;
43
-
44
- // Shared between all the instances. Allocated only when needed.
45
- struct adc_module * adc_instance = NULL ;
46
- struct adc_config * config_adc = NULL ;
47
-
48
41
void common_hal_analogio_analogin_construct (analogio_analogin_obj_t * self ,
49
42
const mcu_pin_obj_t * pin ) {
50
43
if (!pin -> has_adc ) {
@@ -54,27 +47,6 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self,
54
47
claim_pin (pin );
55
48
56
49
self -> pin = pin ;
57
-
58
- if (adc_instance == NULL ) {
59
- // Allocate strucs on the heap so we only use the memory when we
60
- // need it.
61
- adc_instance = gc_alloc (sizeof (struct adc_module ), false);
62
- config_adc = gc_alloc (sizeof (struct adc_config ), false);
63
-
64
- adc_get_config_defaults (config_adc );
65
-
66
- config_adc -> reference = ADC_REFERENCE_INTVCC1 ;
67
- config_adc -> gain_factor = ADC_GAIN_FACTOR_DIV2 ;
68
- config_adc -> positive_input = self -> pin -> adc_input ;
69
- config_adc -> resolution = ADC_RESOLUTION_16BIT ;
70
- config_adc -> clock_prescaler = ADC_CLOCK_PRESCALER_DIV128 ;
71
-
72
- adc_init (adc_instance , ADC , config_adc );
73
- }
74
-
75
- self -> adc_instance = adc_instance ;
76
- self -> config_adc = config_adc ;
77
- active_channel_count ++ ;
78
50
}
79
51
80
52
bool common_hal_analogio_analogin_deinited (analogio_analogin_obj_t * self ) {
@@ -85,36 +57,30 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) {
85
57
if (common_hal_analogio_analogin_deinited (self )) {
86
58
return ;
87
59
}
88
- active_channel_count -- ;
89
- if (active_channel_count == 0 ) {
90
- adc_reset (adc_instance );
91
- gc_free (adc_instance );
92
- gc_free (config_adc );
93
- // Set our references to NULL so the GC doesn't mistakenly see the
94
- // pointers in memory.
95
- adc_instance = NULL ;
96
- config_adc = NULL ;
97
- }
98
60
reset_pin (self -> pin -> pin );
99
61
self -> pin = mp_const_none ;
100
62
}
101
63
102
64
void analogin_reset () {
103
- if (adc_instance != NULL ) {
104
- adc_reset (adc_instance );
105
- adc_instance = NULL ;
106
- }
107
- active_channel_count = 0 ;
108
65
}
109
66
110
67
uint16_t common_hal_analogio_analogin_get_value (analogio_analogin_obj_t * self ) {
111
68
// Something else might have used the ADC in a different way,
112
- // so we have to completely re-initialize it.
113
- // ADC must have been disabled before adc_init() is called.
114
- adc_init (adc_instance , ADC , config_adc );
115
- config_adc -> positive_input = self -> pin -> adc_input ;
69
+ // so we completely re-initialize it.
116
70
117
- adc_enable (adc_instance );
71
+ struct adc_config config_adc ;
72
+ adc_get_config_defaults (& config_adc );
73
+
74
+ config_adc .reference = ADC_REFERENCE_INTVCC1 ;
75
+ config_adc .gain_factor = ADC_GAIN_FACTOR_DIV2 ;
76
+ config_adc .positive_input = self -> pin -> adc_input ;
77
+ config_adc .resolution = ADC_RESOLUTION_16BIT ;
78
+ config_adc .clock_prescaler = ADC_CLOCK_PRESCALER_DIV128 ;
79
+
80
+ struct adc_module adc_instance ;
81
+ // ADC must have been disabled before adc_init() is called.
82
+ adc_init (& adc_instance , ADC , & config_adc );
83
+ adc_enable (& adc_instance );
118
84
119
85
// Read twice and discard first result, as recommended in section 14 of
120
86
// http://www.atmel.com/images/Atmel-42645-ADC-Configurations-with-Examples_ApplicationNote_AT11481.pdf
@@ -125,23 +91,23 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
125
91
uint16_t data ;
126
92
enum status_code status ;
127
93
128
- adc_start_conversion (adc_instance );
94
+ adc_start_conversion (& adc_instance );
129
95
do {
130
- status = adc_read (adc_instance , & data );
96
+ status = adc_read (& adc_instance , & data );
131
97
} while (status == STATUS_BUSY );
132
98
if (status == STATUS_ERR_OVERFLOW ) {
133
- // TODO(tannewt): Throw an error.
99
+ mp_raise_RuntimeError ( "ADC result overwritten before reading" );
134
100
}
135
101
136
- adc_start_conversion (adc_instance );
102
+ adc_start_conversion (& adc_instance );
137
103
do {
138
- status = adc_read (adc_instance , & data );
104
+ status = adc_read (& adc_instance , & data );
139
105
} while (status == STATUS_BUSY );
140
106
if (status == STATUS_ERR_OVERFLOW ) {
141
- // TODO(tannewt): Throw an error.
107
+ mp_raise_RuntimeError ( "ADC result overwritten before reading" );
142
108
}
143
109
144
- adc_disable (adc_instance );
110
+ adc_disable (& adc_instance );
145
111
return data ;
146
112
}
147
113
0 commit comments