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 <robert@hammelrath.com>
This commit is contained in:
parent
b2df094bf8
commit
47fa723586
@ -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"
|
||||
@ -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
|
||||
|
@ -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"
|
||||
@ -183,3 +186,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
||||
print, dac_print,
|
||||
locals_dict, &dac_locals_dict
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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) },
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user