Skip to content

Commit

Permalink
samd/modmachine: Make some machine classes configurable by #defines.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
robert-hh authored and dpgeorge committed May 22, 2023
1 parent b2df094 commit 47fa723
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 32 deletions.
16 changes: 7 additions & 9 deletions ports/samd/machine_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
* THE SOFTWARE.
*/

#include "py/runtime.h"

#if MICROPY_PY_MACHINE_ADC

#include <stdint.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "py/mphal.h"

#include "sam.h"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
7 changes: 6 additions & 1 deletion ports/samd/machine_dac.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
* THE SOFTWARE.
*/

#include "py/runtime.h"

#if MICROPY_PY_MACHINE_DAC

#include <stdint.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "py/mphal.h"

#include "sam.h"
Expand Down Expand Up @@ -183,3 +186,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
print, dac_print,
locals_dict, &dac_locals_dict
);

#endif
5 changes: 5 additions & 0 deletions ports/samd/machine_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -274,3 +277,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
protocol, &machine_i2c_p,
locals_dict, &mp_machine_i2c_locals_dict
);

#endif
7 changes: 6 additions & 1 deletion ports/samd/machine_pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
* THE SOFTWARE.
*/

#include <string.h>
#include "py/runtime.h"

#if MICROPY_PY_MACHINE_PWM

#include <string.h>
#include "py/mphal.h"
#include "modmachine.h"
#include "clock_config.h"
Expand Down Expand Up @@ -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
17 changes: 6 additions & 11 deletions ports/samd/machine_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -341,3 +334,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
protocol, &machine_spi_p,
locals_dict, &mp_machine_spi_locals_dict
);

#endif
33 changes: 26 additions & 7 deletions ports/samd/machine_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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, "
Expand Down Expand Up @@ -544,3 +562,4 @@ MP_DEFINE_CONST_OBJ_TYPE(
protocol, &uart_stream_p,
locals_dict, &machine_uart_locals_dict
);
#endif
9 changes: 8 additions & 1 deletion ports/samd/machine_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}};

Expand Down
6 changes: 6 additions & 0 deletions ports/samd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
18 changes: 18 additions & 0 deletions ports/samd/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
Expand All @@ -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) },

Expand Down
12 changes: 12 additions & 0 deletions ports/samd/modmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
25 changes: 23 additions & 2 deletions ports/samd/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions ports/samd/pin_af.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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

0 comments on commit 47fa723

Please sign in to comment.