From a7edf0107c13697e35b540cb9723681f2fe0f699 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 24 Oct 2023 10:01:25 +0200 Subject: [PATCH] samd/machine_adc.c: Factor out machine.adc_timed(). After machine.ADC has been moved to extmod/machine_adc.c. Adding adc.read_timed() and adc.busy() to extmod/machine_adc.c with a corresponding flag to enable them. ADC/DAC timed are by default enabled only at all SAMD51 devices and at SAMD21 devices with an external flash for the file system. Side changes: - Fix a type in pin_af.c, preventing to use a second ADC channel. - Remove a duplicate definition in mcu/samd21/mpconfigmcu.h. Signed-off-by: robert-hh --- extmod/machine_adc.c | 22 +++++++++++++ ports/samd/machine_adc.c | 49 +++++++++++++---------------- ports/samd/mcu/samd21/mpconfigmcu.h | 7 +++++ ports/samd/mcu/samd51/mpconfigmcu.h | 14 ++++++--- ports/samd/mpconfigport.h | 8 +---- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/extmod/machine_adc.c b/extmod/machine_adc.c index 11f1123dc7..bb7d2461f2 100644 --- a/extmod/machine_adc.c +++ b/extmod/machine_adc.c @@ -140,6 +140,24 @@ static mp_obj_t machine_adc_read(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_obj, machine_adc_read); #endif +#if MICROPY_PY_MACHINE_ADC_READ_TIMED +// ADC.atten(value) -- this is a legacy method. +static mp_obj_t machine_adc_read_timed(mp_obj_t self_in, mp_obj_t values, mp_obj_t freq_in) { + machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t freq = mp_obj_get_int(freq_in); + mp_machine_adc_read_timed(self, values, freq); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_3(machine_adc_read_timed_obj, machine_adc_read_timed); + +// ADC.busy()) +static mp_obj_t machine_adc_busy(mp_obj_t self_in) { + machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_machine_adc_busy(self); +} +static MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_busy_obj, machine_adc_busy); +#endif + static const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { #if MICROPY_PY_MACHINE_ADC_INIT { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_adc_init_obj) }, @@ -164,6 +182,10 @@ static const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { #if MICROPY_PY_MACHINE_ADC_READ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_adc_read_obj) }, #endif + #if MICROPY_PY_MACHINE_ADC_READ_TIMED + { MP_ROM_QSTR(MP_QSTR_read_timed), MP_ROM_PTR(&machine_adc_read_timed_obj) }, + { MP_ROM_QSTR(MP_QSTR_busy), MP_ROM_PTR(&machine_adc_busy_obj) }, + #endif // A port must add ADC class constants defining the following macro. // It can be defined to nothing if there are no constants. diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c index 8eb3fcc72a..e5028f2935 100644 --- a/ports/samd/machine_adc.c +++ b/ports/samd/machine_adc.c @@ -28,17 +28,13 @@ // This file is never compiled standalone, it's included directly from // extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE. -#if MICROPY_PY_MACHINE_ADC - #include #include "py/obj.h" -#include "py/runtime.h" #include "py/mperrno.h" -#include "py/mphal.h" +#include "mphalport.h" #include "sam.h" #include "pin_af.h" -#include "modmachine.h" #include "samd_soc.h" #include "dma_manager.h" #include "tc_manager.h" @@ -50,7 +46,7 @@ typedef struct _machine_adc_obj_t { uint8_t avg; uint8_t bits; uint8_t vref; - #if MICROPY_PY_MACHINE_ADC_TIMED + #if MICROPY_PY_MACHINE_ADC_READ_TIMED int8_t dma_channel; int8_t tc_index; #endif @@ -76,7 +72,7 @@ static uint8_t adc_vref_table[] = { typedef struct _device_mgmt_t { bool init; - #if MICROPY_PY_MACHINE_ADC_TIMED + #if MICROPY_PY_MACHINE_ADC_READ_TIMED bool busy; mp_obj_t callback; mp_obj_t self; @@ -124,7 +120,7 @@ static void adc_init(machine_adc_obj_t *self); extern mp_int_t log2i(mp_int_t num); -#if MICROPY_PY_MACHINE_ADC_TIMED +#if MICROPY_PY_MACHINE_ADC_READ_TIMED // Active just for SAMD21, stops the freerun mode // For SAMD51, just the INT flag is reset. @@ -166,8 +162,7 @@ static void mp_machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_p self->adc_config.channel, self->bits, 1 << self->avg, self->vref); } -static mp_obj_t adc_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, - const mp_obj_t *all_args) { +static mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_bits, ARG_average, ARG_vref, ARG_callback }; static const mp_arg_t allowed_args[] = { @@ -175,7 +170,7 @@ 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 + #if MICROPY_PY_MACHINE_ADC_READ_TIMED { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, #endif }; @@ -209,7 +204,7 @@ static mp_obj_t adc_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_ 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 + #if MICROPY_PY_MACHINE_ADC_READ_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; @@ -231,7 +226,7 @@ static mp_int_t mp_machine_adc_read_u16(machine_adc_obj_t *self) { // Set the reference voltage. Default: external AREFA. adc->REFCTRL.reg = adc_vref_table[self->vref]; - #if MICROPY_PY_MACHINE_ADC_TIMED + #if MICROPY_PY_MACHINE_ADC_READ_TIMED if (device_mgmt[self->adc_config.device].busy != 0) { mp_raise_OSError(MP_EBUSY); } @@ -260,13 +255,13 @@ static mp_int_t mp_machine_adc_read_u16(machine_adc_obj_t *self) { return adc->RESULT.reg * (65536 / (1 << self->bits)); } -static void machine_adc_read_timed(mp_obj_t self_in, mp_obj_t values, mp_obj_t freq_in) { - machine_adc_obj_t *self = self_in; +#if MICROPY_PY_MACHINE_ADC_READ_TIMED + +static void mp_machine_adc_read_timed(machine_adc_obj_t *self, mp_obj_t values, mp_int_t freq) { Adc *adc = adc_bases[self->adc_config.device]; mp_buffer_info_t src; mp_get_buffer_raise(values, &src, MP_BUFFER_READ); if (src.len >= 2) { - int freq = mp_obj_get_int(freq_in); if (self->tc_index == -1) { self->tc_index = allocate_tc_instance(); } @@ -359,12 +354,19 @@ static void machine_adc_read_timed(mp_obj_t self_in, mp_obj_t values, mp_obj_t f #endif // defined SAMD21 or SAMD51 } - return mp_const_none; } +// busy() : Report, if the ADC device is busy +static mp_obj_t mp_machine_adc_busy(machine_adc_obj_t *self) { + return device_mgmt[self->adc_config.device].busy ? mp_const_true : mp_const_false; +} + +#endif + // deinit() : release the ADC channel static void mp_machine_adc_deinit(machine_adc_obj_t *self) { - busy_flags &= ~((1 << (self->adc_config.device * 16 + self->adc_config.channel))); + ch_busy_flags &= ~((1 << (self->adc_config.device * 16 + self->adc_config.channel))); + #if MICROPY_PY_MACHINE_ADC_READ_TIMED if (self->dma_channel >= 0) { #if defined(MCU_SAMD51) if (self->dma_channel == device_mgmt[self->adc_config.device].dma_channel) { @@ -380,17 +382,10 @@ static void mp_machine_adc_deinit(machine_adc_obj_t *self) { free_tc_instance(self->tc_index); self->tc_index = -1; } + #endif } -// busy() : Report, if the ADC device is busy -static mp_int_t machine_adc_busy(mp_obj_t self_in) { - machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); - return device_mgmt[self->adc_config.device].busy ? true : false; -} - -#endif - -#if MICROPY_PY_MACHINE_ADC_TIMED +#if MICROPY_PY_MACHINE_ADC_READ_TIMED void adc_deinit_all(void) { ch_busy_flags = 0; device_mgmt[0].init = 0; diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index fdad3fee4a..43da221e13 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -70,6 +70,13 @@ unsigned long trng_random_u32(int delay); #define MICROPY_PY_DEFLATE (SAMD21_EXTRA_FEATURES) #define MICROPY_PY_ONEWIRE (SAMD21_EXTRA_FEATURES) +#ifndef MICROPY_PY_MACHINE_ADC_READ_TIMED +#define MICROPY_PY_MACHINE_ADC_READ_TIMED (SAMD21_EXTRA_FEATURES) +#endif +#ifndef MICROPY_PY_MACHINE_DAC_TIMED +#define MICROPY_PY_MACHINE_DAC_TIMED (SAMD21_EXTRA_FEATURES) +#endif + #ifndef MICROPY_PY_MACHINE_PIN_BOARD_CPU #define MICROPY_PY_MACHINE_PIN_BOARD_CPU (1) #endif diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index d567f28eb4..7c0cc0da52 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -17,10 +17,10 @@ unsigned long trng_random_u32(void); // fatfs configuration used in ffconf.h -#define MICROPY_FATFS_ENABLE_LFN (1) -#define MICROPY_FATFS_RPATH (2) -#define MICROPY_FATFS_MAX_SS (4096) -#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ +#define MICROPY_FATFS_ENABLE_LFN (1) +#define MICROPY_FATFS_RPATH (2) +#define MICROPY_FATFS_MAX_SS (4096) +#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define VFS_BLOCK_SIZE_BYTES (1536) // @@ -30,6 +30,12 @@ unsigned long trng_random_u32(void); #ifndef MICROPY_HW_UART_RTSCTS #define MICROPY_HW_UART_RTSCTS (1) #endif +#ifndef MICROPY_PY_MACHINE_ADC_READ_TIMED +#define MICROPY_PY_MACHINE_ADC_READ_TIMED (1) +#endif +#ifndef MICROPY_PY_MACHINE_DAC_TIMED +#define MICROPY_PY_MACHINE_DAC_TIMED (1) +#endif #define CPU_FREQ (120000000) #define DFLL48M_FREQ (48000000) diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 1a3f5c32fb..1a4a2741a3 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -128,13 +128,7 @@ #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 +#if MICROPY_PY_MACHINE_DAC_TIMED || MICROPY_PY_MACHINE_ADC_READ_TIMED #define MICROPY_HW_DMA_MANAGER (1) #define MICROPY_HW_TC_MANAGER (1) #endif