diff --git a/ports/samd/dma_manager.c b/ports/samd/dma_manager.c index 868606e66b7f..2ca7f7ba106d 100644 --- a/ports/samd/dma_manager.c +++ b/ports/samd/dma_manager.c @@ -30,6 +30,8 @@ #include "dma_manager.h" #include "samd_soc.h" +#if MICROPY_HW_DMA_MANAGER + // Set a number of dma channels managed here. samd21 has 21 dma channels, samd51 // has 32 channels, as defined by the lib macro DMAC_CH_NUM. // 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) { } #endif } + +#endif diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c index 4b1c38797b0e..efaf2b708a59 100644 --- a/ports/samd/machine_adc.c +++ b/ports/samd/machine_adc.c @@ -50,8 +50,10 @@ typedef struct _machine_adc_obj_t { uint8_t avg; uint8_t bits; uint8_t vref; + #if MICROPY_PY_MACHINE_ADC_TIMED int8_t dma_channel; int8_t tc_index; + #endif } machine_adc_obj_t; #define DEFAULT_ADC_BITS 12 @@ -74,9 +76,11 @@ static uint8_t adc_vref_table[] = { typedef struct _device_mgmt_t { bool init; + #if MICROPY_PY_MACHINE_ADC_TIMED bool busy; mp_obj_t callback; mp_obj_t self; + #endif } device_mgmt_t; device_mgmt_t device_mgmt[ADC_INST_NUM]; @@ -103,10 +107,7 @@ typedef struct _device_mgmt_t { mp_obj_t self; } device_mgmt_t; -device_mgmt_t device_mgmt[ADC_INST_NUM] = { - { 0, 0, -1, MP_OBJ_NULL, MP_OBJ_NULL}, - { 0, 0, -1, MP_OBJ_NULL, MP_OBJ_NULL} -}; +device_mgmt_t device_mgmt[ADC_INST_NUM]; #endif // defined(MCU_SAMD21) @@ -123,6 +124,8 @@ static void adc_init(machine_adc_obj_t *self); extern mp_int_t log2i(mp_int_t num); +#if MICROPY_PY_MACHINE_ADC_TIMED + // Active just for SAMD21, stops the freerun mode // For SAMD51, just the INT flag is reset. void adc_irq_handler(int dma_channel) { @@ -152,6 +155,7 @@ void adc_irq_handler(int dma_channel) { } #endif } +#endif static void mp_machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; @@ -171,7 +175,9 @@ static mp_obj_t adc_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_ { MP_QSTR_bits, MP_ARG_INT, {.u_int = DEFAULT_ADC_BITS} }, { MP_QSTR_average, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_ADC_AVG} }, { MP_QSTR_vref, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_ADC_VREF} }, + #if MICROPY_PY_MACHINE_ADC_TIMED { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + #endif }; // Parse the arguments. @@ -199,18 +205,20 @@ static mp_obj_t adc_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_ if (0 <= vref && vref <= MAX_ADC_VREF) { self->vref = vref; } + // flag the device/channel as being in use. + ch_busy_flags |= (1 << (self->adc_config.device * 16 + self->adc_config.channel)); + device_mgmt[self->adc_config.device].init = false; + + #if MICROPY_PY_MACHINE_ADC_TIMED device_mgmt[adc_config.device].callback = args[ARG_callback].u_obj; if (device_mgmt[adc_config.device].callback == mp_const_none) { device_mgmt[adc_config.device].callback = MP_OBJ_NULL; } else { device_mgmt[adc_config.device].self = self; } - - // flag the device/channel as being in use. - ch_busy_flags |= (1 << (self->adc_config.device * 16 + self->adc_config.channel)); - device_mgmt[self->adc_config.device].init = false; self->dma_channel = -1; self->tc_index = -1; + #endif adc_init(self); @@ -222,9 +230,12 @@ static mp_int_t mp_machine_adc_read_u16(machine_adc_obj_t *self) { Adc *adc = adc_bases[self->adc_config.device]; // Set the reference voltage. Default: external AREFA. adc->REFCTRL.reg = adc_vref_table[self->vref]; + + #if MICROPY_PY_MACHINE_ADC_TIMED if (device_mgmt[self->adc_config.device].busy != 0) { mp_raise_OSError(MP_EBUSY); } + #endif // Set the reference voltage. Default: external AREFA. adc->REFCTRL.reg = adc_vref_table[self->vref]; @@ -375,6 +386,9 @@ static mp_int_t machine_adc_busy(mp_obj_t self_in) { return device_mgmt[self->adc_config.device].busy ? true : false; } +#endif + +#if MICROPY_PY_MACHINE_ADC_TIMED void adc_deinit_all(void) { ch_busy_flags = 0; device_mgmt[0].init = 0; @@ -384,6 +398,15 @@ void adc_deinit_all(void) { device_mgmt[1].dma_channel = -1; #endif } +#else +void adc_deinit_all(void) { + ch_busy_flags = 0; + device_mgmt[0].init = 0; + #if defined(MCU_SAMD51) + device_mgmt[1].init = 0; + #endif +} +#endif static void adc_init(machine_adc_obj_t *self) { // ADC & clock init is done only once per ADC diff --git a/ports/samd/machine_dac.c b/ports/samd/machine_dac.c index 3b98c3cc4181..21b0e67d4d6a 100644 --- a/ports/samd/machine_dac.c +++ b/ports/samd/machine_dac.c @@ -48,15 +48,16 @@ typedef struct _dac_obj_t { bool initialized; uint8_t vref; mp_hal_pin_obj_t gpio_id; + #if MICROPY_PY_MACHINE_DAC_TIMED int8_t dma_channel; int8_t tc_index; bool busy; uint32_t count; mp_obj_t callback; + #endif } dac_obj_t; Dac *const dac_bases[] = DAC_INSTS; static void dac_init(dac_obj_t *self); -static mp_obj_t dac_deinit(mp_obj_t self_in); #if defined(MCU_SAMD21) @@ -88,6 +89,8 @@ static uint8_t dac_vref_table[] = { #endif // defined SAMD21 or SAMD51 +#if MICROPY_PY_MACHINE_DAC_TIMED + void dac_irq_handler(int dma_channel) { dac_obj_t *self; @@ -126,6 +129,8 @@ void dac_irq_handler(int dma_channel) { #endif } +#endif + static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { @@ -133,7 +138,9 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_vref, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_DAC_VREF} }, + #if MICROPY_PY_MACHINE_DAC_TIMED { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + #endif }; // Parse the arguments. @@ -153,15 +160,17 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ self->vref = vref; } + #if MICROPY_PY_MACHINE_DAC_TIMED self->callback = args[ARG_callback].u_obj; if (self->callback == mp_const_none) { self->callback = MP_OBJ_NULL; } - self->dma_channel = -1; self->tc_index = -1; - self->initialized = false; self->busy = false; + #endif + + self->initialized = false; dac_init(self); // Set the port as given in self->gpio_id as DAC @@ -238,9 +247,11 @@ static mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) { if (self->initialized == false) { mp_raise_OSError(MP_ENODEV); } + #if MICROPY_PY_MACHINE_DAC_TIMED if (self->busy != false) { mp_raise_OSError(MP_EBUSY); } + #endif int value = mp_obj_get_int(value_in); @@ -257,6 +268,8 @@ static mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) { } MP_DEFINE_CONST_FUN_OBJ_2(dac_write_obj, dac_write); +#if MICROPY_PY_MACHINE_DAC_TIMED + static mp_obj_t dac_write_timed(size_t n_args, const mp_obj_t *args) { Dac *dac = dac_bases[0]; // Just one DAC used dac_obj_t *self = args[0]; @@ -386,12 +399,26 @@ static mp_obj_t machine_dac_busy(mp_obj_t self_in) { return self->busy ? mp_const_true : mp_const_false; } static MP_DEFINE_CONST_FUN_OBJ_1(machine_dac_busy_obj, machine_dac_busy); +#else + +void dac_deinit_all(void) { + // Reset the DAC to lower the current consumption as SAMD21 + dac_bases[0]->CTRLA.bit.SWRST = 1; + dac_obj[0].initialized = false; + #if defined(MCU_SAMD51) + dac_obj[1].initialized = false; + #endif +} + +#endif static const mp_rom_map_elem_t dac_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&dac_write_obj) }, + #if MICROPY_PY_MACHINE_DAC_TIMED { MP_ROM_QSTR(MP_QSTR_busy), MP_ROM_PTR(&machine_dac_busy_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&dac_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_write_timed), MP_ROM_PTR(&dac_write_timed_obj) }, + #endif }; static MP_DEFINE_CONST_DICT(dac_locals_dict, dac_locals_dict_table); diff --git a/ports/samd/main.c b/ports/samd/main.c index 1c1b6c7d6e6b..b9758c2eb77e 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -90,8 +90,12 @@ void samd_main(void) { soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); + #if MICROPY_HW_DMA_MANAGER dma_deinit(); + #endif + #if MICROPY_HW_TC_MANAGER tc_deinit(); + #endif #if MICROPY_PY_MACHINE_ADC adc_deinit_all(); #endif diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 0b47500bf7e7..1a3f5c32fb8e 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -128,6 +128,17 @@ #define MICROPY_PY_MACHINE_WDT_TIMEOUT_MS (1) #define MICROPY_PLATFORM_VERSION "ASF4" +#ifndef MICROPY_PY_MACHINE_DAC_TIMED +#define MICROPY_PY_MACHINE_DAC_TIMED (1) +#endif +#ifndef MICROPY_PY_MACHINE_ADC_TIMED +#define MICROPY_PY_MACHINE_ADC_TIMED (1) +#endif +#if MICROPY_PY_MACHINE_DAC_TIMED || MICROPY_PY_MACHINE_ADC_TIMED +#define MICROPY_HW_DMA_MANAGER (1) +#define MICROPY_HW_TC_MANAGER (1) +#endif + #define MP_STATE_PORT MP_STATE_VM // Miscellaneous settings diff --git a/ports/samd/tc_manager.c b/ports/samd/tc_manager.c index fb0c3b77ff48..b6b981087c43 100644 --- a/ports/samd/tc_manager.c +++ b/ports/samd/tc_manager.c @@ -29,6 +29,8 @@ #include "sam.h" #include "tc_manager.h" +#if MICROPY_HW_TC_MANAGER + // List of channel flags: true: channel used, false: channel available // Two Tc instances are used by the usec counter and cannot be assigned. #if defined(MCU_SAMD21) @@ -179,3 +181,5 @@ void tc_deinit(void) { instance_flag[0] = instance_flag[1] = true; #endif } + +#endif