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 <robert@hammelrath.com>
robert-hh 2023-10-24 10:01:25 +02:00
rodzic 42aef1a6ce
commit a7edf0107c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 32EC5F755D5A3A93
5 zmienionych plików z 62 dodań i 38 usunięć

Wyświetl plik

@ -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); static MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_obj, machine_adc_read);
#endif #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[] = { static const mp_rom_map_elem_t machine_adc_locals_dict_table[] = {
#if MICROPY_PY_MACHINE_ADC_INIT #if MICROPY_PY_MACHINE_ADC_INIT
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_adc_init_obj) }, { 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 #if MICROPY_PY_MACHINE_ADC_READ
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_adc_read_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_adc_read_obj) },
#endif #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. // A port must add ADC class constants defining the following macro.
// It can be defined to nothing if there are no constants. // It can be defined to nothing if there are no constants.

Wyświetl plik

@ -28,17 +28,13 @@
// This file is never compiled standalone, it's included directly from // This file is never compiled standalone, it's included directly from
// extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE. // extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE.
#if MICROPY_PY_MACHINE_ADC
#include <stdint.h> #include <stdint.h>
#include "py/obj.h" #include "py/obj.h"
#include "py/runtime.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#include "py/mphal.h" #include "mphalport.h"
#include "sam.h" #include "sam.h"
#include "pin_af.h" #include "pin_af.h"
#include "modmachine.h"
#include "samd_soc.h" #include "samd_soc.h"
#include "dma_manager.h" #include "dma_manager.h"
#include "tc_manager.h" #include "tc_manager.h"
@ -50,7 +46,7 @@ typedef struct _machine_adc_obj_t {
uint8_t avg; uint8_t avg;
uint8_t bits; uint8_t bits;
uint8_t vref; uint8_t vref;
#if MICROPY_PY_MACHINE_ADC_TIMED #if MICROPY_PY_MACHINE_ADC_READ_TIMED
int8_t dma_channel; int8_t dma_channel;
int8_t tc_index; int8_t tc_index;
#endif #endif
@ -76,7 +72,7 @@ static uint8_t adc_vref_table[] = {
typedef struct _device_mgmt_t { typedef struct _device_mgmt_t {
bool init; bool init;
#if MICROPY_PY_MACHINE_ADC_TIMED #if MICROPY_PY_MACHINE_ADC_READ_TIMED
bool busy; bool busy;
mp_obj_t callback; mp_obj_t callback;
mp_obj_t self; 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); 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 // Active just for SAMD21, stops the freerun mode
// For SAMD51, just the INT flag is reset. // 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); 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, 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) {
const mp_obj_t *all_args) {
enum { ARG_id, ARG_bits, ARG_average, ARG_vref, ARG_callback }; enum { ARG_id, ARG_bits, ARG_average, ARG_vref, ARG_callback };
static const mp_arg_t allowed_args[] = { 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_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_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} }, { 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} }, { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
#endif #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)); ch_busy_flags |= (1 << (self->adc_config.device * 16 + self->adc_config.channel));
device_mgmt[self->adc_config.device].init = false; 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; device_mgmt[adc_config.device].callback = args[ARG_callback].u_obj;
if (device_mgmt[adc_config.device].callback == mp_const_none) { if (device_mgmt[adc_config.device].callback == mp_const_none) {
device_mgmt[adc_config.device].callback = MP_OBJ_NULL; 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. // Set the reference voltage. Default: external AREFA.
adc->REFCTRL.reg = adc_vref_table[self->vref]; 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) { if (device_mgmt[self->adc_config.device].busy != 0) {
mp_raise_OSError(MP_EBUSY); 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)); 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) { #if MICROPY_PY_MACHINE_ADC_READ_TIMED
machine_adc_obj_t *self = self_in;
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]; Adc *adc = adc_bases[self->adc_config.device];
mp_buffer_info_t src; mp_buffer_info_t src;
mp_get_buffer_raise(values, &src, MP_BUFFER_READ); mp_get_buffer_raise(values, &src, MP_BUFFER_READ);
if (src.len >= 2) { if (src.len >= 2) {
int freq = mp_obj_get_int(freq_in);
if (self->tc_index == -1) { if (self->tc_index == -1) {
self->tc_index = allocate_tc_instance(); 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 #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 // deinit() : release the ADC channel
static void mp_machine_adc_deinit(machine_adc_obj_t *self) { 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 (self->dma_channel >= 0) {
#if defined(MCU_SAMD51) #if defined(MCU_SAMD51)
if (self->dma_channel == device_mgmt[self->adc_config.device].dma_channel) { 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); free_tc_instance(self->tc_index);
self->tc_index = -1; self->tc_index = -1;
} }
#endif
} }
// busy() : Report, if the ADC device is busy #if MICROPY_PY_MACHINE_ADC_READ_TIMED
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
void adc_deinit_all(void) { void adc_deinit_all(void) {
ch_busy_flags = 0; ch_busy_flags = 0;
device_mgmt[0].init = 0; device_mgmt[0].init = 0;

Wyświetl plik

@ -70,6 +70,13 @@ unsigned long trng_random_u32(int delay);
#define MICROPY_PY_DEFLATE (SAMD21_EXTRA_FEATURES) #define MICROPY_PY_DEFLATE (SAMD21_EXTRA_FEATURES)
#define MICROPY_PY_ONEWIRE (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 #ifndef MICROPY_PY_MACHINE_PIN_BOARD_CPU
#define MICROPY_PY_MACHINE_PIN_BOARD_CPU (1) #define MICROPY_PY_MACHINE_PIN_BOARD_CPU (1)
#endif #endif

Wyświetl plik

@ -17,10 +17,10 @@
unsigned long trng_random_u32(void); unsigned long trng_random_u32(void);
// fatfs configuration used in ffconf.h // fatfs configuration used in ffconf.h
#define MICROPY_FATFS_ENABLE_LFN (1) #define MICROPY_FATFS_ENABLE_LFN (1)
#define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_RPATH (2)
#define MICROPY_FATFS_MAX_SS (4096) #define MICROPY_FATFS_MAX_SS (4096)
#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
#define VFS_BLOCK_SIZE_BYTES (1536) // #define VFS_BLOCK_SIZE_BYTES (1536) //
@ -30,6 +30,12 @@ unsigned long trng_random_u32(void);
#ifndef MICROPY_HW_UART_RTSCTS #ifndef MICROPY_HW_UART_RTSCTS
#define MICROPY_HW_UART_RTSCTS (1) #define MICROPY_HW_UART_RTSCTS (1)
#endif #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 CPU_FREQ (120000000)
#define DFLL48M_FREQ (48000000) #define DFLL48M_FREQ (48000000)

Wyświetl plik

@ -128,13 +128,7 @@
#define MICROPY_PY_MACHINE_WDT_TIMEOUT_MS (1) #define MICROPY_PY_MACHINE_WDT_TIMEOUT_MS (1)
#define MICROPY_PLATFORM_VERSION "ASF4" #define MICROPY_PLATFORM_VERSION "ASF4"
#ifndef MICROPY_PY_MACHINE_DAC_TIMED #if MICROPY_PY_MACHINE_DAC_TIMED || MICROPY_PY_MACHINE_ADC_READ_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_DMA_MANAGER (1)
#define MICROPY_HW_TC_MANAGER (1) #define MICROPY_HW_TC_MANAGER (1)
#endif #endif