From 47fa723586dc4ae81df02f5a0a10b2b018045ab0 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 11 Mar 2023 08:03:18 +0100 Subject: [PATCH] samd/modmachine: Make some machine classes configurable by #defines. These include ADC, DAC, I2C, SoftI2C, SPI, SoftI2C, PWM, UART, pulse. This is useful for devices like the Adafruit Trinket series which have almost no accessible GPIO pins. Signed-off-by: robert-hh --- ports/samd/machine_adc.c | 16 +++++++--------- ports/samd/machine_dac.c | 7 ++++++- ports/samd/machine_i2c.c | 5 +++++ ports/samd/machine_pwm.c | 7 ++++++- ports/samd/machine_spi.c | 17 ++++++----------- ports/samd/machine_uart.c | 33 ++++++++++++++++++++++++++------- ports/samd/machine_wdt.c | 9 ++++++++- ports/samd/main.c | 6 ++++++ ports/samd/modmachine.c | 18 ++++++++++++++++++ ports/samd/modmachine.h | 12 ++++++++++++ ports/samd/mpconfigport.h | 25 +++++++++++++++++++++++-- ports/samd/pin_af.c | 8 ++++++++ 12 files changed, 131 insertions(+), 32 deletions(-) diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c index 8f47fc6d1..1d848e32b 100644 --- a/ports/samd/machine_adc.c +++ b/ports/samd/machine_adc.c @@ -25,9 +25,12 @@ * THE SOFTWARE. */ +#include "py/runtime.h" + +#if MICROPY_PY_MACHINE_ADC + #include #include "py/obj.h" -#include "py/runtime.h" #include "py/mphal.h" #include "sam.h" @@ -82,14 +85,7 @@ static uint8_t resolution[] = { ADC_CTRLB_RESSEL_8BIT_Val, ADC_CTRLB_RESSEL_10BIT_Val, ADC_CTRLB_RESSEL_12BIT_Val }; -// Calculate the floor value of log2(n) -mp_int_t log2i(mp_int_t num) { - mp_int_t res = 0; - for (; num > 1; num >>= 1) { - res += 1; - } - return res; -} +extern mp_int_t log2i(mp_int_t num); STATIC void adc_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { (void)kind; @@ -274,3 +270,5 @@ static void adc_init(machine_adc_obj_t *self) { // Set the port as given in self->id as ADC mp_hal_set_pin_mux(self->id, ALT_FCT_ADC); } + +#endif diff --git a/ports/samd/machine_dac.c b/ports/samd/machine_dac.c index a1da9285e..195c06e4f 100644 --- a/ports/samd/machine_dac.c +++ b/ports/samd/machine_dac.c @@ -25,9 +25,12 @@ * THE SOFTWARE. */ +#include "py/runtime.h" + +#if MICROPY_PY_MACHINE_DAC + #include #include "py/obj.h" -#include "py/runtime.h" #include "py/mphal.h" #include "sam.h" @@ -183,3 +186,5 @@ MP_DEFINE_CONST_OBJ_TYPE( print, dac_print, locals_dict, &dac_locals_dict ); + +#endif diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c index 330fa433d..f3364950b 100644 --- a/ports/samd/machine_i2c.c +++ b/ports/samd/machine_i2c.c @@ -26,6 +26,9 @@ */ #include "py/runtime.h" + +#if MICROPY_PY_MACHINE_I2C + #include "py/mphal.h" #include "py/mperrno.h" #include "extmod/machine_i2c.h" @@ -274,3 +277,5 @@ MP_DEFINE_CONST_OBJ_TYPE( protocol, &machine_i2c_p, locals_dict, &mp_machine_i2c_locals_dict ); + +#endif diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c index d01ce2ff1..1b5f6c3ed 100644 --- a/ports/samd/machine_pwm.c +++ b/ports/samd/machine_pwm.c @@ -25,8 +25,11 @@ * THE SOFTWARE. */ -#include #include "py/runtime.h" + +#if MICROPY_PY_MACHINE_PWM + +#include #include "py/mphal.h" #include "modmachine.h" #include "clock_config.h" @@ -393,3 +396,5 @@ STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns duty_type_flags[self->device] &= ~(1 << self->channel); mp_machine_pwm_start(self); } + +#endif diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c index bbd7031e9..99eb4e17f 100644 --- a/ports/samd/machine_spi.c +++ b/ports/samd/machine_spi.c @@ -24,7 +24,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #include "py/runtime.h" + +#if MICROPY_PY_MACHINE_SPI + #include "py/mphal.h" #include "extmod/machine_spi.h" #include "modmachine.h" @@ -57,7 +61,6 @@ typedef struct _machine_spi_obj_t { } machine_spi_obj_t; extern Sercom *sercom_instance[]; -MP_REGISTER_ROOT_POINTER(void *sercom_table[SERCOM_INST_NUM]); void common_spi_irq_handler(int spi_id) { // handle Sercom IRQ RXC @@ -270,16 +273,6 @@ STATIC void machine_sercom_deinit(mp_obj_base_t *self_in) { MP_STATE_PORT(sercom_table[self->id]) = NULL; } -void sercom_deinit_all(void) { - for (int i = 0; i < SERCOM_INST_NUM; i++) { - Sercom *spi = sercom_instance[i]; - spi->SPI.INTENCLR.reg = 0xff; - sercom_register_irq(i, NULL); - sercom_enable(spi, 0); - MP_STATE_PORT(sercom_table[i]) = NULL; - } -} - STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { machine_spi_obj_t *self = (machine_spi_obj_t *)self_in; @@ -341,3 +334,5 @@ MP_DEFINE_CONST_OBJ_TYPE( protocol, &machine_spi_p, locals_dict, &mp_machine_spi_locals_dict ); + +#endif diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index ec1b42de9..8028d8872 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -25,6 +25,9 @@ * THE SOFTWARE. */ #include "py/runtime.h" + +#if MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_UART + #include "py/mphal.h" #include "py/stream.h" #include "py/ringbuf.h" @@ -59,6 +62,28 @@ typedef struct _machine_uart_obj_t { } machine_uart_obj_t; Sercom *sercom_instance[] = SERCOM_INSTS; +MP_REGISTER_ROOT_POINTER(void *sercom_table[SERCOM_INST_NUM]); + +// Common Sercom functions used by all Serial devices +void sercom_enable(Sercom *uart, int state) { + uart->USART.CTRLA.bit.ENABLE = state; // Set the state on/off + // Wait for the Registers to update. + while (uart->USART.SYNCBUSY.bit.ENABLE) { + } +} + +void sercom_deinit_all(void) { + for (int i = 0; i < SERCOM_INST_NUM; i++) { + Sercom *uart = sercom_instance[i]; + uart->USART.INTENCLR.reg = 0xff; + sercom_register_irq(i, NULL); + sercom_enable(uart, 0); + MP_STATE_PORT(sercom_table[i]) = NULL; + } +} +#endif + +#if MICROPY_PY_MACHINE_UART STATIC const char *_parity_name[] = {"None", "", "0", "1"}; // Is defined as 0, 2, 3 @@ -105,13 +130,6 @@ void common_uart_irq_handler(int uart_id) { } } -void sercom_enable(Sercom *uart, int state) { - uart->USART.CTRLA.bit.ENABLE = state; // Set the state on/off - // Wait for the Registers to update. - while (uart->USART.SYNCBUSY.bit.ENABLE) { - } -} - STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, " @@ -544,3 +562,4 @@ MP_DEFINE_CONST_OBJ_TYPE( protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict ); +#endif diff --git a/ports/samd/machine_wdt.c b/ports/samd/machine_wdt.c index c0fbfdbfb..d7dcfcf54 100644 --- a/ports/samd/machine_wdt.c +++ b/ports/samd/machine_wdt.c @@ -36,7 +36,14 @@ typedef struct _machine_wdt_obj_t { mp_obj_base_t base; } machine_wdt_obj_t; -extern mp_int_t log2i(mp_int_t num); +// Calculate the floor value of log2(n) +mp_int_t log2i(mp_int_t num) { + mp_int_t res = 0; + for (; num > 1; num >>= 1) { + res += 1; + } + return res; +} STATIC const machine_wdt_obj_t machine_wdt = {{&machine_wdt_type}}; diff --git a/ports/samd/main.c b/ports/samd/main.c index 1e30df13d..74eb5e328 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -81,12 +81,18 @@ void samd_main(void) { soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); + #if MICROPY_PY_MACHINE_ADC adc_deinit_all(); + #endif pin_irq_deinit_all(); + #if MICROPY_PY_MACHINE_PWM pwm_deinit_all(); + #endif soft_timer_deinit(); gc_sweep_all(); + #if MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_UART sercom_deinit_all(); + #endif mp_deinit(); } } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index a2ef34b99..58ca895b4 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -234,17 +234,33 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) }, + #if MICROPY_PY_MACHINE_ADC { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, + #endif + #if MICROPY_PY_MACHINE_DAC { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, + #if MICROPY_PY_MACHINE_PWM { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, + #endif + #if MICROPY_PY_MACHINE_SOFTI2C { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, + #endif + #if MICROPY_PY_MACHINE_I2C { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, + #endif + #if MICROPY_PY_MACHINE_SOFTSPI { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, + #endif + #if MICROPY_PY_MACHINE_SPI { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, + #if MICROPY_PY_MACHINE_UART { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) }, #if MICROPY_PY_MACHINE_RTC { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, @@ -254,7 +270,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, + #if MICROPY_PY_MACHINE_PULSE { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_lightsleep), MP_ROM_PTR(&machine_lightsleep_obj) }, { MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_lightsleep_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 8b3059d9f..b3ba44039 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -29,14 +29,26 @@ #include "py/obj.h" #include "shared/timeutils/timeutils.h" +#if MICROPY_PY_MACHINE_ADC extern const mp_obj_type_t machine_adc_type; +#endif +#if MICROPY_PY_MACHINE_DAC extern const mp_obj_type_t machine_dac_type; +#endif +#if MICROPY_PY_MACHINE_I2C extern const mp_obj_type_t machine_i2c_type; +#endif extern const mp_obj_type_t machine_pin_type; +#if MICROPY_PY_MACHINE_PWM extern const mp_obj_type_t machine_pwm_type; +#endif +#if MICROPY_PY_MACHINE_SPI extern const mp_obj_type_t machine_spi_type; +#endif extern const mp_obj_type_t machine_timer_type; +#if MICROPY_PY_MACHINE_UART extern const mp_obj_type_t machine_uart_type; +#endif extern const mp_obj_type_t machine_wdt_type; #if MICROPY_PY_MACHINE_RTC extern const mp_obj_type_t machine_rtc_type; diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 3b89ee082..bf03b5f7b 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -94,18 +94,39 @@ #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_UASYNCIO (1) -#define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_RTC (1) -#define MICROPY_PY_MACHINE_SOFTI2C (1) +#ifndef MICROPY_PY_MACHINE_ADC +#define MICROPY_PY_MACHINE_ADC (1) +#endif +#ifndef MICROPY_PY_MACHINE_DAC +#define MICROPY_PY_MACHINE_DAC (1) +#endif +#ifndef MICROPY_PY_MACHINE_I2C +#define MICROPY_PY_MACHINE_I2C (1) +#endif +#ifndef MICROPY_PY_MACHINE_SPI #define MICROPY_PY_MACHINE_SPI (1) +#endif +#ifndef MICROPY_PY_MACHINE_SOFTI2C +#define MICROPY_PY_MACHINE_SOFTI2C (1) +#endif +#ifndef MICROPY_PY_MACHINE_SOFTSPI #define MICROPY_PY_MACHINE_SOFTSPI (1) +#endif +#ifndef MICROPY_PY_MACHINE_UART +#define MICROPY_PY_MACHINE_UART (1) +#endif #define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_SOFT_TIMER_TICKS_MS systick_ms #define MICROPY_PY_OS_DUPTERM (3) #define MICROPY_PY_MACHINE_BITSTREAM (1) +#ifndef MICROPY_PY_MACHINE_PULSE #define MICROPY_PY_MACHINE_PULSE (1) +#endif +#ifndef MICROPY_PY_MACHINE_PWM #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/samd/machine_pwm.c" +#endif #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/samd/pin_af.c b/ports/samd/pin_af.c index 15743d1df..419b81477 100644 --- a/ports/samd/pin_af.c +++ b/ports/samd/pin_af.c @@ -121,6 +121,7 @@ const char *pin_name(int id) { return "-"; } +#if MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_UART // Test, whether the given pin is defined and has signals for sercom. // If that applies return the alt_fct and pad_nr. // If not, an error will be raised. @@ -135,7 +136,9 @@ sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) { mp_raise_ValueError(MP_ERROR_TEXT("wrong serial device")); } } +#endif +#if MICROPY_PY_MACHINE_ADC // Test, whether the given pin is defined as ADC. // If that applies return the adc instance and channel. // If not, an error will be raised. @@ -152,6 +155,9 @@ adc_config_t get_adc_config(int pin_id, int32_t flag) { mp_raise_ValueError(MP_ERROR_TEXT("ADC pin used")); } } +#endif + +#if MICROPY_PY_MACHINE_PWM // Test, whether the given pin is defined and has signals for pwm. // If that applies return the alt_fct, tcc number and channel number. @@ -188,3 +194,5 @@ pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t device_status[]) } mp_raise_ValueError(MP_ERROR_TEXT("not a PWM Pin")); } + +#endif