Skip to content

Commit 52455c1

Browse files
committed
samd/ADC_DAC: Make adc.read_timed() and dac.write_timed() configurable.
Both together require ~1.9k of flash space, including the DMA-manager and the TC-manager. adc.read_timed() uses ~700 bytes, dac.write_timed() ~600 bytes.
1 parent 7074908 commit 52455c1

File tree

6 files changed

+90
-13
lines changed

6 files changed

+90
-13
lines changed

ports/samd/dma_manager.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "dma_manager.h"
3131
#include "samd_soc.h"
3232

33+
#if MICROPY_HW_DMA_MANAGER
34+
3335
// Set a number of dma channels managed here. samd21 has 21 dma channels, samd51
3436
// has 32 channels, as defined by the lib macro DMAC_CH_NUM.
3537
// At first, we use a smaller number here to save RAM. May be increased as needed.
@@ -129,3 +131,5 @@ void dac_stop_dma(int dma_channel, bool wait) {
129131
}
130132
#endif
131133
}
134+
135+
#endif

ports/samd/machine_adc.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ typedef struct _machine_adc_obj_t {
4545
uint8_t avg;
4646
uint8_t bits;
4747
uint8_t vref;
48+
#if MICROPY_PY_MACHINE_ADC_TIMED
4849
int8_t dma_channel;
4950
int8_t tc_index;
51+
#endif
5052
} machine_adc_obj_t;
5153

5254
#define DEFAULT_ADC_BITS 12
@@ -69,9 +71,11 @@ static uint8_t adc_vref_table[] = {
6971

7072
typedef struct _device_mgmt_t {
7173
bool init;
74+
#if MICROPY_PY_MACHINE_ADC_TIMED
7275
bool busy;
7376
mp_obj_t callback;
7477
mp_obj_t self;
78+
#endif
7579
} device_mgmt_t;
7680

7781
device_mgmt_t device_mgmt[ADC_INST_NUM];
@@ -98,10 +102,7 @@ typedef struct _device_mgmt_t {
98102
mp_obj_t self;
99103
} device_mgmt_t;
100104

101-
device_mgmt_t device_mgmt[ADC_INST_NUM] = {
102-
{ 0, 0, -1, MP_OBJ_NULL, MP_OBJ_NULL},
103-
{ 0, 0, -1, MP_OBJ_NULL, MP_OBJ_NULL}
104-
};
105+
device_mgmt_t device_mgmt[ADC_INST_NUM];
105106

106107
#endif // defined(MCU_SAMD21)
107108

@@ -122,6 +123,8 @@ mp_int_t log2i(mp_int_t num) {
122123
return res;
123124
}
124125

126+
#if MICROPY_PY_MACHINE_ADC_TIMED
127+
125128
// Active just for SAMD21, stops the freerun mode
126129
// For SAMD51, just the INT flag is reset.
127130
void adc_irq_handler(int dma_channel) {
@@ -151,6 +154,7 @@ void adc_irq_handler(int dma_channel) {
151154
}
152155
#endif
153156
}
157+
#endif
154158

155159
STATIC void adc_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) {
156160
(void)kind;
@@ -170,7 +174,9 @@ STATIC mp_obj_t adc_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_
170174
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = DEFAULT_ADC_BITS} },
171175
{ MP_QSTR_average, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_ADC_AVG} },
172176
{ MP_QSTR_vref, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_ADC_VREF} },
177+
#if MICROPY_PY_MACHINE_ADC_TIMED
173178
{ MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
179+
#endif
174180
};
175181

176182
// Parse the arguments.
@@ -198,18 +204,20 @@ STATIC mp_obj_t adc_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_
198204
if (0 <= vref && vref <= MAX_ADC_VREF) {
199205
self->vref = vref;
200206
}
207+
// flag the device/channel as being in use.
208+
ch_busy_flags |= (1 << (self->adc_config.device * 16 + self->adc_config.channel));
209+
device_mgmt[self->adc_config.device].init = false;
210+
211+
#if MICROPY_PY_MACHINE_ADC_TIMED
201212
device_mgmt[adc_config.device].callback = args[ARG_callback].u_obj;
202213
if (device_mgmt[adc_config.device].callback == mp_const_none) {
203214
device_mgmt[adc_config.device].callback = MP_OBJ_NULL;
204215
} else {
205216
device_mgmt[adc_config.device].self = self;
206217
}
207-
208-
// flag the device/channel as being in use.
209-
ch_busy_flags |= (1 << (self->adc_config.device * 16 + self->adc_config.channel));
210-
device_mgmt[self->adc_config.device].init = false;
211218
self->dma_channel = -1;
212219
self->tc_index = -1;
220+
#endif
213221

214222
adc_init(self);
215223

@@ -222,9 +230,12 @@ STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) {
222230
Adc *adc = adc_bases[self->adc_config.device];
223231
// Set the reference voltage. Default: external AREFA.
224232
adc->REFCTRL.reg = adc_vref_table[self->vref];
233+
234+
#if MICROPY_PY_MACHINE_ADC_TIMED
225235
if (device_mgmt[self->adc_config.device].busy != 0) {
226236
mp_raise_OSError(MP_EBUSY);
227237
}
238+
#endif
228239

229240
// Set the reference voltage. Default: external AREFA.
230241
adc->REFCTRL.reg = adc_vref_table[self->vref];
@@ -250,6 +261,8 @@ STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) {
250261
}
251262
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_u16_obj, machine_adc_read_u16);
252263

264+
#if MICROPY_PY_MACHINE_ADC_TIMED
265+
253266
STATIC mp_obj_t machine_adc_read_timed(mp_obj_t self_in, mp_obj_t values, mp_obj_t freq_in) {
254267
machine_adc_obj_t *self = self_in;
255268
Adc *adc = adc_bases[self->adc_config.device];
@@ -382,6 +395,9 @@ STATIC mp_obj_t machine_adc_busy(mp_obj_t self_in) {
382395
}
383396
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_busy_obj, machine_adc_busy);
384397

398+
#endif
399+
400+
#if MICROPY_PY_MACHINE_ADC_TIMED
385401
void adc_deinit_all(void) {
386402
ch_busy_flags = 0;
387403
device_mgmt[0].init = 0;
@@ -391,12 +407,23 @@ void adc_deinit_all(void) {
391407
device_mgmt[1].dma_channel = -1;
392408
#endif
393409
}
410+
#else
411+
void adc_deinit_all(void) {
412+
ch_busy_flags = 0;
413+
device_mgmt[0].init = 0;
414+
#if defined(MCU_SAMD51)
415+
device_mgmt[1].init = 0;
416+
#endif
417+
}
418+
#endif
394419

395420
STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = {
396-
{ MP_ROM_QSTR(MP_QSTR_busy), MP_ROM_PTR(&machine_adc_busy_obj) },
397421
{ MP_ROM_QSTR(MP_QSTR_read_u16), MP_ROM_PTR(&machine_adc_read_u16_obj) },
398-
{ MP_ROM_QSTR(MP_QSTR_read_timed), MP_ROM_PTR(&machine_adc_read_timed_obj) },
422+
#if MICROPY_PY_MACHINE_ADC_TIMED
423+
{ MP_ROM_QSTR(MP_QSTR_busy), MP_ROM_PTR(&machine_adc_busy_obj) },
399424
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_adc_deinit_obj) },
425+
{ MP_ROM_QSTR(MP_QSTR_read_timed), MP_ROM_PTR(&machine_adc_read_timed_obj) },
426+
#endif
400427
};
401428

402429
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);

ports/samd/machine_dac.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,16 @@ typedef struct _dac_obj_t {
4444
bool initialized;
4545
uint8_t vref;
4646
mp_hal_pin_obj_t gpio_id;
47+
#if MICROPY_PY_MACHINE_DAC_TIMED
4748
int8_t dma_channel;
4849
int8_t tc_index;
4950
bool busy;
5051
uint32_t count;
5152
mp_obj_t callback;
53+
#endif
5254
} dac_obj_t;
5355
Dac *const dac_bases[] = DAC_INSTS;
5456
STATIC void dac_init(dac_obj_t *self);
55-
STATIC mp_obj_t dac_deinit(mp_obj_t self_in);
5657

5758
#if defined(MCU_SAMD21)
5859

@@ -84,6 +85,8 @@ static uint8_t dac_vref_table[] = {
8485

8586
#endif // defined SAMD21 or SAMD51
8687

88+
#if MICROPY_PY_MACHINE_DAC_TIMED
89+
8790
void dac_irq_handler(int dma_channel) {
8891
dac_obj_t *self;
8992

@@ -122,14 +125,18 @@ void dac_irq_handler(int dma_channel) {
122125
#endif
123126
}
124127

128+
#endif
129+
125130
STATIC mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
126131
const mp_obj_t *all_args) {
127132

128133
enum { ARG_id, ARG_vref, ARG_callback };
129134
static const mp_arg_t allowed_args[] = {
130135
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
131136
{ MP_QSTR_vref, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_DAC_VREF} },
137+
#if MICROPY_PY_MACHINE_DAC_TIMED
132138
{ MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
139+
#endif
133140
};
134141

135142
// Parse the arguments.
@@ -149,15 +156,17 @@ STATIC mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
149156
self->vref = vref;
150157
}
151158

159+
#if MICROPY_PY_MACHINE_DAC_TIMED
152160
self->callback = args[ARG_callback].u_obj;
153161
if (self->callback == mp_const_none) {
154162
self->callback = MP_OBJ_NULL;
155163
}
156-
157164
self->dma_channel = -1;
158165
self->tc_index = -1;
159-
self->initialized = false;
160166
self->busy = false;
167+
#endif
168+
169+
self->initialized = false;
161170

162171
dac_init(self);
163172
// Set the port as given in self->gpio_id as DAC
@@ -234,9 +243,11 @@ STATIC mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) {
234243
if (self->initialized == false) {
235244
mp_raise_OSError(MP_ENODEV);
236245
}
246+
#if MICROPY_PY_MACHINE_DAC_TIMED
237247
if (self->busy != false) {
238248
mp_raise_OSError(MP_EBUSY);
239249
}
250+
#endif
240251

241252
int value = mp_obj_get_int(value_in);
242253

@@ -253,6 +264,8 @@ STATIC mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) {
253264
}
254265
MP_DEFINE_CONST_FUN_OBJ_2(dac_write_obj, dac_write);
255266

267+
#if MICROPY_PY_MACHINE_DAC_TIMED
268+
256269
STATIC mp_obj_t dac_write_timed(size_t n_args, const mp_obj_t *args) {
257270
Dac *dac = dac_bases[0]; // Just one DAC used
258271
dac_obj_t *self = args[0];
@@ -382,12 +395,26 @@ STATIC mp_obj_t machine_dac_busy(mp_obj_t self_in) {
382395
return self->busy ? mp_const_true : mp_const_false;
383396
}
384397
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_dac_busy_obj, machine_dac_busy);
398+
#else
399+
400+
void dac_deinit_all(void) {
401+
// Reset the DAC to lower the current consumption as SAMD21
402+
dac_bases[0]->CTRLA.bit.SWRST = 1;
403+
dac_obj[0].initialized = false;
404+
#if defined(MCU_SAMD51)
405+
dac_obj[1].initialized = false;
406+
#endif
407+
}
408+
409+
#endif
385410

386411
STATIC const mp_rom_map_elem_t dac_locals_dict_table[] = {
387412
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&dac_write_obj) },
413+
#if MICROPY_PY_MACHINE_DAC_TIMED
388414
{ MP_ROM_QSTR(MP_QSTR_busy), MP_ROM_PTR(&machine_dac_busy_obj) },
389415
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&dac_deinit_obj) },
390416
{ MP_ROM_QSTR(MP_QSTR_write_timed), MP_ROM_PTR(&dac_write_timed_obj) },
417+
#endif
391418
};
392419

393420
STATIC MP_DEFINE_CONST_DICT(dac_locals_dict, dac_locals_dict_table);

ports/samd/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,12 @@ void samd_main(void) {
8484

8585
soft_reset_exit:
8686
mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n");
87+
#if MICROPY_HW_DMA_MANAGER
8788
dma_deinit();
89+
#endif
90+
#if MICROPY_HW_TC_MANAGER
8891
tc_deinit();
92+
#endif
8993
adc_deinit_all();
9094
dac_deinit_all();
9195
pin_irq_deinit_all();

ports/samd/mpconfigport.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,17 @@
110110
#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/samd/machine_pwm.c"
111111
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
112112

113+
#ifndef MICROPY_PY_MACHINE_DAC_TIMED
114+
#define MICROPY_PY_MACHINE_DAC_TIMED (1)
115+
#endif
116+
#ifndef MICROPY_PY_MACHINE_ADC_TIMED
117+
#define MICROPY_PY_MACHINE_ADC_TIMED (1)
118+
#endif
119+
#if MICROPY_PY_MACHINE_DAC_TIMED || MICROPY_PY_MACHINE_ADC_TIMED
120+
#define MICROPY_HW_DMA_MANAGER (1)
121+
#define MICROPY_HW_TC_MANAGER (1)
122+
#endif
123+
113124
#define MP_STATE_PORT MP_STATE_VM
114125

115126
// Additional entries for use with pendsv_schedule_dispatch.

ports/samd/tc_manager.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "sam.h"
3030
#include "tc_manager.h"
3131

32+
#if MICROPY_HW_TC_MANAGER
33+
3234
// List of channel flags: true: channel used, false: channel available
3335
// Two Tc instances are used by the usec counter and cannot be assigned.
3436
#if defined(MCU_SAMD21)
@@ -179,3 +181,5 @@ void tc_deinit(void) {
179181
instance_flag[0] = instance_flag[1] = true;
180182
#endif
181183
}
184+
185+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy