From 9d58d46e0a28b7bd3344cae049e8085bcd75cb75 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 28 Jul 2020 16:27:19 +1000 Subject: [PATCH 0001/4290] docs/library/pyb.Pin.rst: Update the arguments for Pin.init(). Add details for Pin.init() value and alt arguments. --- docs/library/pyb.Pin.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 3d019cd8e067..6465653f74cb 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -98,11 +98,11 @@ Class methods Methods ------- -.. method:: Pin.init(mode, pull=Pin.PULL_NONE, af=-1) +.. method:: Pin.init(mode, pull=Pin.PULL_NONE, \*, value=None, alt=-1) Initialise the pin: - - ``mode`` can be one of: + - *mode* can be one of: - ``Pin.IN`` - configure the pin for input; - ``Pin.OUT_PP`` - configure the pin for output, with push-pull control; @@ -111,14 +111,17 @@ Methods - ``Pin.AF_OD`` - configure the pin for alternate function, open-drain; - ``Pin.ANALOG`` - configure the pin for analog. - - ``pull`` can be one of: + - *pull* can be one of: - ``Pin.PULL_NONE`` - no pull up or down resistors; - ``Pin.PULL_UP`` - enable the pull-up resistor; - ``Pin.PULL_DOWN`` - enable the pull-down resistor. - - when mode is ``Pin.AF_PP`` or ``Pin.AF_OD``, then af can be the index or name - of one of the alternate functions associated with a pin. + - *value* if not None will set the port output value before enabling the pin. + + - *alt* can be used when mode is ``Pin.AF_PP`` or ``Pin.AF_OD`` to set the + index or name of one of the alternate functions associated with a pin. + This arg was previously called *af* which can still be used if needed. Returns: ``None``. From c24003abec78ee443ddc1bdc375c48513e45a54a Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Mon, 13 Jan 2020 17:25:01 +1100 Subject: [PATCH 0002/4290] stm32/boards: Add VCC_GND_F407VE board. --- ports/stm32/boards/VCC_GND_F407VE/bdev.c | 28 +++ .../stm32/boards/VCC_GND_F407VE/board_init.c | 7 + .../boards/VCC_GND_F407VE/mpconfigboard.h | 163 ++++++++++++++++++ .../boards/VCC_GND_F407VE/mpconfigboard.mk | 6 + ports/stm32/boards/VCC_GND_F407VE/pins.csv | 112 ++++++++++++ .../VCC_GND_F407VE/stm32f4xx_hal_conf.h | 15 ++ 6 files changed, 331 insertions(+) create mode 100644 ports/stm32/boards/VCC_GND_F407VE/bdev.c create mode 100644 ports/stm32/boards/VCC_GND_F407VE/board_init.c create mode 100644 ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h create mode 100644 ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk create mode 100644 ports/stm32/boards/VCC_GND_F407VE/pins.csv create mode 100644 ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/VCC_GND_F407VE/bdev.c b/ports/stm32/boards/VCC_GND_F407VE/bdev.c new file mode 100644 index 000000000000..18b5b85b18f8 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/bdev.c @@ -0,0 +1,28 @@ +#include "storage.h" + +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// External SPI flash uses standard SPI interface + +STATIC const mp_soft_spi_obj_t soft_spi_bus = { + .delay_half = MICROPY_HW_SOFTSPI_MIN_DELAY, + .polarity = 0, + .phase = 0, + .sck = MICROPY_HW_SPIFLASH_SCK, + .mosi = MICROPY_HW_SPIFLASH_MOSI, + .miso = MICROPY_HW_SPIFLASH_MISO, +}; + +STATIC mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = MICROPY_HW_SPIFLASH_CS, + .bus.u_spi.data = (void*)&soft_spi_bus, + .bus.u_spi.proto = &mp_soft_spi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; + +#endif diff --git a/ports/stm32/boards/VCC_GND_F407VE/board_init.c b/ports/stm32/boards/VCC_GND_F407VE/board_init.c new file mode 100644 index 000000000000..1d5900de5585 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/board_init.c @@ -0,0 +1,7 @@ +#include "py/mphal.h" + +void VCC_GND_F407VE_board_early_init(void) { + // set SPI flash CS pin high + mp_hal_pin_output(pin_A4); + mp_hal_pin_write(pin_A4, 1); +} diff --git a/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h new file mode 100644 index 000000000000..fd896c666688 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h @@ -0,0 +1,163 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * MIT License; Copyright (c) 2021 Damien P. George + */ + +// STM32F407VET6 Mini by VCC-GND Studio +// http://vcc-gnd.com/ +// https://item.taobao.com/item.htm?ft=t&id=523361737493 +// https://www.aliexpress.com/wholesale?SearchText=STM32F407VET6+Mini + +// DFU mode can be accessed by switching BOOT0 DIP ON (towards USB) + +#define MICROPY_HW_BOARD_NAME "VCC-GND STM32F407VE" +#define MICROPY_HW_MCU_NAME "STM32F407VE" +#define MICROPY_HW_FLASH_FS_LABEL "VCCGNDF407VE" + +// 1 = use internal flash (512 KByte) +// 0 = use external SPI flash +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) + +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) + +// HSE is 25MHz +#define MICROPY_HW_CLK_PLLM (25) // divide external clock by this to get 1MHz +#define MICROPY_HW_CLK_PLLN (336) // PLL clock in MHz +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) // divide PLL clock by this to get core clock +#define MICROPY_HW_CLK_PLLQ (7) // divide core clock by this to get 48MHz + +// The board has a 32kHz crystal for the RTC +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_RTC_USE_US (0) +// #define MICROPY_HW_RTC_USE_CALOUT (1) // turn on/off PC13 512Hz output + +// USART1 +#define MICROPY_HW_UART1_TX (pin_A9) // PA9,PB6 +#define MICROPY_HW_UART1_RX (pin_A10) // PA10,PB7 + +// USART2 +#define MICROPY_HW_UART2_TX (pin_A2) // PA2,PD5 +#define MICROPY_HW_UART2_RX (pin_A3) // PA3,PD6 +#define MICROPY_HW_UART2_RTS (pin_A1) // PA1,PD4 +#define MICROPY_HW_UART2_CTS (pin_A0) // PA0,PD3 + +// USART3 +#define MICROPY_HW_UART3_TX (pin_D8) // PB10,PC10,PD8 +#define MICROPY_HW_UART3_RX (pin_D9) // PB11,PC11,PD9 +#define MICROPY_HW_UART3_RTS (pin_D12) // PB14,PD12 +#define MICROPY_HW_UART3_CTS (pin_D11) // PB13,PD11 + +// UART4 +#define MICROPY_HW_UART4_TX (pin_A0) // PA0,PC10 +#define MICROPY_HW_UART4_RX (pin_A1) // PA1,PC11 + +// UART5 +#define MICROPY_HW_UART5_TX (pin_C12) // PC12 +#define MICROPY_HW_UART5_RX (pin_D2) // PD2 + +// USART6 +#define MICROPY_HW_UART6_TX (pin_C6) // PC6,PG14 +#define MICROPY_HW_UART6_RX (pin_C7) // PC7,PG9 + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B6) // PB8,PB6 +#define MICROPY_HW_I2C1_SDA (pin_B7) // PB9,PB7 +#define MICROPY_HW_I2C2_SCL (pin_B10) // PB10 +#define MICROPY_HW_I2C2_SDA (pin_B11) // PB11 +#define MICROPY_HW_I2C3_SCL (pin_A8) // PA8 +#define MICROPY_HW_I2C3_SDA (pin_C9) // PC9 +// AT24C08 EEPROM on I2C1 0x50-0x53 + +// I2S buses +// I2S2_CK PB13 +// I2S2_MCK PC6 +// I2S2_SD PB15 +// I2S2_WS PB12 +// I2S3_CK PB3 +// I2S3_MCK PC7 +// I2S3_SD PB5 +// I2S3_WS PA15 + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) // PA4 +#define MICROPY_HW_SPI1_SCK (pin_A5) // PA5,PB3 +#define MICROPY_HW_SPI1_MISO (pin_A6) // PA6,PB4 +#define MICROPY_HW_SPI1_MOSI (pin_A7) // PA7,PB5 + +#define MICROPY_HW_SPI2_NSS (pin_B12) // PB12 +#define MICROPY_HW_SPI2_SCK (pin_B13) // PB13 +#define MICROPY_HW_SPI2_MISO (pin_B14) // PB14 +#define MICROPY_HW_SPI2_MOSI (pin_B15) // PB15 + +#define MICROPY_HW_SPI3_NSS (pin_A15) // PA15 +#define MICROPY_HW_SPI3_SCK (pin_B3) // PB3 +#define MICROPY_HW_SPI3_MISO (pin_B4) // PB4 +#define MICROPY_HW_SPI3_MOSI (pin_B5) // PB5 + +// CAN buses +#define MICROPY_HW_CAN1_TX (pin_B9) // PB9,PD1,PA12 +#define MICROPY_HW_CAN1_RX (pin_B8) // PB8,PD0,PA11 +#define MICROPY_HW_CAN2_TX (pin_B13) // PB13 +#define MICROPY_HW_CAN2_RX (pin_B12) // PB12 + +// DAC +// DAC_OUT1 PA4 +// DAC_OUT2 PA5 + +// LEDs +#define MICROPY_HW_LED1 (pin_B9) // blue +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +// If using external SPI flash +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// The board does not have onboard SPI flash. You need to add an external one. +#define MICROPY_HW_SPIFLASH_SIZE_BITS (4 * 1024 * 1024) // W25X40 - 4 Mbit (512 KByte) +// #define MICROPY_HW_SPIFLASH_SIZE_BITS (32 * 1024 * 1024) // W25Q32 - 32 Mbit (4 MByte) +// #define MICROPY_HW_SPIFLASH_SIZE_BITS (64 * 1024 * 1024) // W25Q64 - 64 Mbit (8 MByte) +// #define MICROPY_HW_SPIFLASH_SIZE_BITS (128 * 1024 * 1024) // W25Q128 - 128 Mbit (16 MByte) + +#define MICROPY_HW_SPIFLASH_CS (pin_A4) // also in board_init.c +#define MICROPY_HW_SPIFLASH_SCK (pin_A5) +#define MICROPY_HW_SPIFLASH_MISO (pin_A6) +#define MICROPY_HW_SPIFLASH_MOSI (pin_A7) + +#define MICROPY_BOARD_EARLY_INIT VCC_GND_F407VE_board_early_init +void VCC_GND_F407VE_board_early_init(void); + +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \ + (op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ +) +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) spi_bdev_readblocks(&spi_bdev, (dest), (bl), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(&spi_bdev, (src), (bl), (n)) + +#endif + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) +// 1 - PC10 - DAT2/RES +// 2 - PC11 - CD/DAT3/CS +// 3 - PD2 - CMD/DI +// 4 - VCC - VDD +// 5 - PC12 - CLK/SCLK +// 6 - GND - VSS +// 7 - PC8 - DAT0/D0 +// 8 - PC9 - DAT1/RES +// 9 SW2 - GND +// 10 SW1 - PA8 + +// USB config +#define MICROPY_HW_USB_FS (1) +// #define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +// #define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) diff --git a/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk new file mode 100644 index 000000000000..b154dcfbacdc --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk @@ -0,0 +1,6 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F407xx +AF_FILE = boards/stm32f405_af.csv +LD_FILES = boards/stm32f405.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 diff --git a/ports/stm32/boards/VCC_GND_F407VE/pins.csv b/ports/stm32/boards/VCC_GND_F407VE/pins.csv new file mode 100644 index 000000000000..f04d96771b05 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/pins.csv @@ -0,0 +1,112 @@ +P1_1,GND +P1_2,GND +P1_3,VBAT +P1_4,VCC_3V3 +P1_5,VIN_5V +P1_6,VIN_5V +P1_7,PE0 +P1_8,PE1 +P1_9,PE2 +P1_10,PE3 +P1_11,PE4 +P1_12,PE5 +P1_13,PE6 +P1_14,PC13 +P1_15,PC14 +P1_16,PC15 +P1_17,PC0 +P1_18,PC1 +P1_19,PC2 +P1_20,PC3 +P1_21,PA0 +P1_22,PA2 +P1_23,PA1 +P1_24,PA3 +P1_25,PA4 +P1_26,PA5 +P1_27,PA6 +P1_28,PA7 +P1_29,PC4 +P1_30,PC5 +P1_31,PB0 +P1_32,PB1 +P1_33,PB2 +P1_34,PE7 +P1_35,PE8 +P1_36,PE9 +P2_1,PE11 +P2_2,PE10 +P2_3,PE13 +P2_4,PE12 +P2_5,PE15 +P2_6,PE14 +P2_7,PB11 +P2_8,PB10 +P2_9,PB13 +P2_10,PB12 +P2_11,PB15 +P2_12,PB14 +P2_13,PD9 +P2_14,PD8 +P2_15,PD11 +P2_16,PD10 +P2_17,PD13 +P2_18,PD12 +P2_19,PD15 +P2_20,PD14 +P3_1,PC8 +P3_2,PC6 +P3_3,PC9 +P3_4,PC7 +P3_5,PA9 +P3_6,PA8 +P3_7,PA11 +P3_8,PA10 +P3_9,PA13 +P3_10,PA12 +P3_11,PA15 +P3_12,PA14 +P3_13,PC11 +P3_14,PC10 +P3_15,PC12 +P3_16,PD0 +P3_17,PD1 +P3_18,PD2 +P3_19,PD3 +P3_20,PD4 +P3_21,PD5 +P3_22,PD6 +P3_23,PD7 +P3_24,PB3 +P3_25,PB4 +P3_26,PB5 +P3_27,PB6 +P3_28,PB7 +P3_29,PB8 +P3_30,PB9 +P3_31,GND +P3_32,GND +P3_33,VCC_3V3 +P3_34,VCC_3V3 +P3_35,GND +P3_36,GND +DAC1,PA4 +DAC2,PA5 +BLUE_LED,PB9 +BOOT1,PB2 +USB_VBUS,PA9 +USB_ID,PA10 +USB_DM,PA11 +USB_DP,PA12 +SWCLK,PA14 +SWDIO,PA13 +OSC32_IN,PC14 +OSC32_OUT,PC15 +SD_D0,PC8 +SD_D1,PC9 +SD_D2,PC10 +SD_D3,PC11 +SD_CK,PC12 +SD_CMD,PD2 +SD,PA8 +SD_SW,PA8 diff --git a/ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h b/ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h new file mode 100644 index 000000000000..fe2069fe1418 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (25000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From 1ca66efbf7be4f57ab31df5ecb81d27da4aefd0d Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Mon, 13 Jan 2020 17:26:01 +1100 Subject: [PATCH 0003/4290] stm32/boards: Add VCC_GND_F407ZG board. --- ports/stm32/boards/VCC_GND_F407ZG/bdev.c | 28 +++ .../stm32/boards/VCC_GND_F407ZG/board_init.c | 7 + .../boards/VCC_GND_F407ZG/mpconfigboard.h | 182 ++++++++++++++++++ .../boards/VCC_GND_F407ZG/mpconfigboard.mk | 10 + ports/stm32/boards/VCC_GND_F407ZG/pins.csv | 157 +++++++++++++++ .../VCC_GND_F407ZG/stm32f4xx_hal_conf.h | 15 ++ 6 files changed, 399 insertions(+) create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/bdev.c create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/board_init.c create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/pins.csv create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/VCC_GND_F407ZG/bdev.c b/ports/stm32/boards/VCC_GND_F407ZG/bdev.c new file mode 100644 index 000000000000..18b5b85b18f8 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/bdev.c @@ -0,0 +1,28 @@ +#include "storage.h" + +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// External SPI flash uses standard SPI interface + +STATIC const mp_soft_spi_obj_t soft_spi_bus = { + .delay_half = MICROPY_HW_SOFTSPI_MIN_DELAY, + .polarity = 0, + .phase = 0, + .sck = MICROPY_HW_SPIFLASH_SCK, + .mosi = MICROPY_HW_SPIFLASH_MOSI, + .miso = MICROPY_HW_SPIFLASH_MISO, +}; + +STATIC mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = MICROPY_HW_SPIFLASH_CS, + .bus.u_spi.data = (void*)&soft_spi_bus, + .bus.u_spi.proto = &mp_soft_spi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; + +#endif diff --git a/ports/stm32/boards/VCC_GND_F407ZG/board_init.c b/ports/stm32/boards/VCC_GND_F407ZG/board_init.c new file mode 100644 index 000000000000..1f4663fdf9ba --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/board_init.c @@ -0,0 +1,7 @@ +#include "py/mphal.h" + +void VCC_GND_F407ZG_board_early_init(void) { + // set SPI flash CS pin high + mp_hal_pin_output(pin_C4); + mp_hal_pin_write(pin_C4, 1); +} diff --git a/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h new file mode 100644 index 000000000000..bd17ab410f7c --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h @@ -0,0 +1,182 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * MIT License; Copyright (c) 2021 Damien P. George + */ + +// STM32F407ZGT6 Mini by VCC-GND Studio +// http://vcc-gnd.com/ +// https://item.taobao.com/item.htm?ft=t&id=523383164199 +// https://www.aliexpress.com/wholesale?SearchText=STM32F407ZGT6+Mini + +// DFU mode can be accessed by switching BOOT0 DIP ON (towards USB) + +#define MICROPY_HW_BOARD_NAME "VCC-GND STM32F407ZG" +#define MICROPY_HW_MCU_NAME "STM32F407ZG" +#define MICROPY_HW_FLASH_FS_LABEL "VCCGNDF407ZG" + +// 1 = use internal flash (1 MByte) +// 0 = use onboard SPI flash (512 KByte) Winbond W25X40 +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) + +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) + +// HSE is 25MHz +#define MICROPY_HW_CLK_PLLM (25) // divide external clock by this to get 1MHz +#define MICROPY_HW_CLK_PLLN (336) // PLL clock in MHz +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) // divide PLL clock by this to get core clock +#define MICROPY_HW_CLK_PLLQ (7) // divide core clock by this to get 48MHz + +// The board has a 32kHz crystal for the RTC +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_RTC_USE_US (0) +// #define MICROPY_HW_RTC_USE_CALOUT (1) // turn on/off PC13 512Hz output + +// USART1 +#define MICROPY_HW_UART1_TX (pin_A9) // PA9,PB6 +#define MICROPY_HW_UART1_RX (pin_A10) // PA10,PB7 +#define MICROPY_HW_UART1_RTS (pin_A12) +#define MICROPY_HW_UART1_CTS (pin_A11) +// USART1_CK PA8 + +// USART2 +#define MICROPY_HW_UART2_TX (pin_A2) // PA2,PD5 +#define MICROPY_HW_UART2_RX (pin_A3) // PA3,PD6 +#define MICROPY_HW_UART2_RTS (pin_A1) // PA1,PD4 +#define MICROPY_HW_UART2_CTS (pin_A0) // PA0,PD3 +// USART2_CK PA4,PD7 + +// USART3 +#define MICROPY_HW_UART3_TX (pin_D8) // PB10,PC10,PD8 +#define MICROPY_HW_UART3_RX (pin_D9) // PB11,PC11,PD9 +#define MICROPY_HW_UART3_RTS (pin_D12) // PB14,PD12 +#define MICROPY_HW_UART3_CTS (pin_D11) // PB13,PD11 +// USART3_CK PB12,PC12,PD10 + +// UART4 +#define MICROPY_HW_UART4_TX (pin_A0) // PA0,PC10 +#define MICROPY_HW_UART4_RX (pin_A1) // PA1,PC11 + +// UART5 +#define MICROPY_HW_UART5_TX (pin_C12) // PC12 +#define MICROPY_HW_UART5_RX (pin_D2) // PD2 + +// USART6 +#define MICROPY_HW_UART6_TX (pin_C6) // PC6,PG14 +#define MICROPY_HW_UART6_RX (pin_C7) // PC7,PG9 +#define MICROPY_HW_UART6_RTS (pin_G8) // PG8,PG12 +#define MICROPY_HW_UART6_CTS (pin_G13) // PG13,PG15 +// USART6_CK PC8,PG7 + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B6) // PB8,PB6 +#define MICROPY_HW_I2C1_SDA (pin_B7) // PB9,PB7 +// I2C1_SMBA PB5 +#define MICROPY_HW_I2C2_SCL (pin_B10) // PB10,PF1 +#define MICROPY_HW_I2C2_SDA (pin_B11) // PB11,PF0 +// I2C2_SMBA PB12,PF2 +#define MICROPY_HW_I2C3_SCL (pin_A8) // PA8 +#define MICROPY_HW_I2C3_SDA (pin_C9) // PC9 +// I2C3_SMBA PA9 + +// AT24C08 EEPROM on I2C1 0x50-0x53 + +// I2S buses - multiplexed with SPI2 and SPI3 +// I2S2_CK PB10,PB13 +// I2S2_MCK PC6 +// I2S2_SD PB15,PC3 +// I2S2_WS PB9,PB12 +// I2S3_CK PB3,PC10 +// I2S3_MCK PC7 +// I2S3_SD PB5,PC12 +// I2S3_WS PA4,PA15 + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) // PA4,PA15 +#define MICROPY_HW_SPI1_SCK (pin_A5) // PA5,PB3 +#define MICROPY_HW_SPI1_MISO (pin_A6) // PA6,PB4 +#define MICROPY_HW_SPI1_MOSI (pin_A7) // PA7,PB5 + +#define MICROPY_HW_SPI2_NSS (pin_B12) // PB12,PB9 +#define MICROPY_HW_SPI2_SCK (pin_B13) // PB13,PB10 +#define MICROPY_HW_SPI2_MISO (pin_B14) // PB14,PC2 +#define MICROPY_HW_SPI2_MOSI (pin_B15) // PB15,PC3 + +#define MICROPY_HW_SPI3_NSS (pin_A15) // PA15,PA4 +#define MICROPY_HW_SPI3_SCK (pin_B3) // PB3,PC10 +#define MICROPY_HW_SPI3_MISO (pin_B4) // PB4,PC11 +#define MICROPY_HW_SPI3_MOSI (pin_B5) // PB5,PC12 + +// CAN buses +#define MICROPY_HW_CAN1_TX (pin_B9) // PB9,PD1,PA12 +#define MICROPY_HW_CAN1_RX (pin_B8) // PB8,PD0,PA11 +#define MICROPY_HW_CAN2_TX (pin_B13) // PB13,PB6 +#define MICROPY_HW_CAN2_RX (pin_B12) // PB12,PB5 + +// DAC +// DAC_OUT1 PA4 +// DAC_OUT2 PA5 + +// LEDs +#define MICROPY_HW_LED1 (pin_G15) // blue +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +// If using onboard SPI flash +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// W25X40 SPI Flash = 4 Mbit (512 KByte) +#define MICROPY_HW_SPIFLASH_SIZE_BITS (4 * 1024 * 1024) +#define MICROPY_HW_SPIFLASH_CS (pin_C4) +#define MICROPY_HW_SPIFLASH_SCK (pin_A5) +#define MICROPY_HW_SPIFLASH_MISO (pin_A6) +#define MICROPY_HW_SPIFLASH_MOSI (pin_A7) + +#define MICROPY_BOARD_EARLY_INIT VCC_GND_F407ZG_board_early_init +void VCC_GND_F407ZG_board_early_init(void); + +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \ + (op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ +) +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) spi_bdev_readblocks(&spi_bdev, (dest), (bl), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(&spi_bdev, (src), (bl), (n)) + +#endif + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_F10) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) +// 1 - PC10 - DAT2/RES +// 2 - PC11 - CD/DAT3/CS +// 3 - PD2 - CMD/DI +// 4 - VCC - VDD +// 5 - PC12 - CLK/SCLK +// 6 - GND - VSS +// 7 - PC8 - DAT0/D0 +// 8 - PC9 - DAT1/RES +// 9 SW2 - GND +// 10 SW1 - PF10 + +// USB config +#define MICROPY_HW_USB_FS (1) +// #define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +// #define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) + +// Ethernet via RMII +#define MICROPY_HW_ETH_MDC (pin_C1) +#define MICROPY_HW_ETH_MDIO (pin_A2) +#define MICROPY_HW_ETH_RMII_REF_CLK (pin_A1) +#define MICROPY_HW_ETH_RMII_CRS_DV (pin_A7) +#define MICROPY_HW_ETH_RMII_RXD0 (pin_C4) +#define MICROPY_HW_ETH_RMII_RXD1 (pin_C5) +#define MICROPY_HW_ETH_RMII_TX_EN (pin_B11) +#define MICROPY_HW_ETH_RMII_TXD0 (pin_B12) +#define MICROPY_HW_ETH_RMII_TXD1 (pin_B13) diff --git a/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk new file mode 100644 index 000000000000..c67807867ef1 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk @@ -0,0 +1,10 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F407xx +AF_FILE = boards/stm32f405_af.csv +LD_FILES = boards/stm32f405.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 + +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/stm32/boards/VCC_GND_F407ZG/pins.csv b/ports/stm32/boards/VCC_GND_F407ZG/pins.csv new file mode 100644 index 000000000000..780523a075f4 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/pins.csv @@ -0,0 +1,157 @@ +P1_1,GND +P1_2,GND +P1_3,VBAT +P1_4,VCC_3V3 +P1_5,VIN_5V +P1_6,VIN_5V +P1_7,PF2 +P1_8,PF3 +P1_9,PF4 +P1_10,PF5 +P1_11,PF6 +P1_12,PF7 +P1_13,PF8 +P1_14,PF9 +P1_15,PF10 +P1_16,PC0 +P1_17,PC1 +P1_18,PC2 +P1_19,PC3 +P1_20,PA0 +P1_21,PA1 +P1_22,PA2 +P1_23,PA3 +P1_24,PA4 +P1_25,PA5 +P1_26,PA6 +P1_27,PA7 +P1_28,PC4 +P1_29,PC5 +P1_30,PB0 +P1_31,PB1 +P1_32,PB2 +P1_33,PF11 +P1_34,PF12 +P1_35,PF13 +P1_36,PF14 +P1_37,PF15 +P1_38,PG0 +P1_39,PG1 +P1_40,PE7 +P1_41,PE8 +P1_42,PE9 +P1_43,GND +P1_44,GND +P2_1,PG7 +P2_2,PG6 +P2_3,PG5 +P2_4,PG4 +P2_5,PG3 +P2_6,PG2 +P2_7,PD15 +P2_8,PD14 +P2_9,PD13 +P2_10,PD12 +P2_11,PD11 +P2_12,PD10 +P2_13,PD9 +P2_14,PD8 +P2_15,PB15 +P2_16,PB14 +P2_17,PB13 +P2_18,PB12 +P2_19,PB11 +P2_20,PB10 +P2_21,PE15 +P2_22,PE14 +P2_23,PE13 +P2_24,PE12 +P2_25,PE11 +P2_26,PE10 +P3_1,PF1 +P3_2,PF0 +P3_3,PC15 +P3_4,PC14 +P3_5,PC13 +P3_6,PE6 +P3_7,PE5 +P3_8,PE4 +P3_9,PE3 +P3_10,PE2 +P3_11,PE1 +P3_12,PE0 +P4_1,GND +P4_2,GND +P4_3,VCC_3V3 +P4_4,VCC_3V3 +P4_5,PB9 +P4_6,PB8 +P4_7,PB7 +P4_8,PB6 +P4_9,PB5 +P4_10,PB4 +P4_11,PB3 +P4_12,PG15 +P4_13,PG14 +P4_14,PG13 +P4_15,PG12 +P4_16,PG11 +P4_17,PG10 +P4_18,PG9 +P4_19,PD7 +P4_20,PD6 +P4_21,PD5 +P4_22,PD4 +P4_23,PD3 +P4_24,PD2 +P4_25,PD1 +P4_26,PD0 +P4_27,PC12 +P4_28,PC11 +P4_29,PC10 +P4_30,PA15 +P4_31,PA14 +P4_32,PA13 +P4_33,PA12 +P4_34,PA11 +P4_35,PA10 +P4_36,PA9 +P4_37,PA8 +P4_38,PC9 +P4_39,PC8 +P4_40,PC7 +P4_41,PC6 +P4_42,PG8 +P4_43,GND +P4_44,GND +DAC1,PA4 +DAC2,PA5 +SRAM_CS,PG10 +SF_CS,PB12 +BLUE_LED,PG15 +BOOT1,PB2 +USB_VBUS,PA9 +USB_ID,PA10 +USB_DM,PA11 +USB_DP,PA12 +SWCLK,PA14 +SWDIO,PA13 +OSC32_IN,PC14 +OSC32_OUT,PC15 +SD_D0,PC8 +SD_D1,PC9 +SD_D2,PC10 +SD_D3,PC11 +SD_CK,PC12 +SD_CMD,PD2 +SD,PF10 +SD_SW,PF10 +ETH_MDC,PC1 +ETH_MDIO,PA2 +ETH_RMII_REF_CLK,PA1 +ETH_RMII_CRS_DV,PA7 +ETH_RMII_RXD0,PC4 +ETH_RMII_RXD1,PC5 +ETH_RMII_TX_EN,PB11 +ETH_RMII_TXD0,PB12 +ETH_RMII_TXD1,PB13 diff --git a/ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h b/ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h new file mode 100644 index 000000000000..fe2069fe1418 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (25000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From 47b778332a0e89740775db544e7c22065df528c2 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Thu, 20 May 2021 16:21:47 +1000 Subject: [PATCH 0004/4290] all: Replace busses with buses. "buses" is the widely accepted plural form of "bus". --- docs/library/network.CC3K.rst | 2 +- docs/library/network.WIZNET5K.rst | 2 +- docs/library/pyb.CAN.rst | 2 +- docs/library/pyb.I2C.rst | 2 +- docs/library/pyb.SPI.rst | 2 +- docs/library/pyb.UART.rst | 2 +- docs/library/pyb.rst | 2 +- ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h | 6 +++--- ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h | 4 ++-- ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h | 6 +++--- ports/stm32/boards/CERB40/mpconfigboard.h | 6 +++--- ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h | 4 ++-- ports/stm32/boards/HYDRABUS/mpconfigboard.h | 4 ++-- ports/stm32/boards/LIMIFROG/mpconfigboard.h | 4 ++-- ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h | 6 +++--- ports/stm32/boards/OLIMEX_E407/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBD_SF6/mpconfigboard.h | 2 +- ports/stm32/boards/PYBLITEV10/mpconfigboard.h | 4 ++-- ports/stm32/boards/PYBV10/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBV11/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBV3/mpconfigboard.h | 4 ++-- ports/stm32/boards/PYBV4/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F411DISC/mpconfigboard.h | 4 ++-- ports/stm32/boards/STM32F429DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F439/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F4DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F769DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F7DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32L476DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32L496GDISC/mpconfigboard.h | 4 ++-- ports/stm32/machine_uart.c | 2 +- ports/stm32/pyb_i2c.c | 2 +- ports/stm32/pyb_spi.c | 2 +- ports/stm32/spi.c | 2 +- ports/teensy/uart.c | 2 +- 49 files changed, 105 insertions(+), 105 deletions(-) diff --git a/docs/library/network.CC3K.rst b/docs/library/network.CC3K.rst index 18210e2d26d5..41d3fb437e99 100644 --- a/docs/library/network.CC3K.rst +++ b/docs/library/network.CC3K.rst @@ -25,7 +25,7 @@ For this example to work the CC3000 module must have the following connections: - VBEN connected to Y4 - IRQ connected to Y3 -It is possible to use other SPI busses and other pins for CS, VBEN and IRQ. +It is possible to use other SPI buses and other pins for CS, VBEN and IRQ. Constructors ------------ diff --git a/docs/library/network.WIZNET5K.rst b/docs/library/network.WIZNET5K.rst index e21e3a4978f5..9e2c40f7f393 100644 --- a/docs/library/network.WIZNET5K.rst +++ b/docs/library/network.WIZNET5K.rst @@ -26,7 +26,7 @@ For this example to work the WIZnet5x00 module must have the following connectio - nSS connected to X5 - nRESET connected to X4 -It is possible to use other SPI busses and other pins for nSS and nRESET. +It is possible to use other SPI buses and other pins for nSS and nRESET. Constructors ------------ diff --git a/docs/library/pyb.CAN.rst b/docs/library/pyb.CAN.rst index 649bcda108fc..bcaeeba9df95 100644 --- a/docs/library/pyb.CAN.rst +++ b/docs/library/pyb.CAN.rst @@ -30,7 +30,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See :meth:`CAN.init` for parameters of initialisation. - The physical pins of the CAN busses are: + The physical pins of the CAN buses are: - ``CAN(1)`` is on ``YA``: ``(RX, TX) = (Y3, Y4) = (PB8, PB9)`` - ``CAN(2)`` is on ``YB``: ``(RX, TX) = (Y5, Y6) = (PB12, PB13)`` diff --git a/docs/library/pyb.I2C.rst b/docs/library/pyb.I2C.rst index 641dcb881587..56b036e07447 100644 --- a/docs/library/pyb.I2C.rst +++ b/docs/library/pyb.I2C.rst @@ -64,7 +64,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See ``init`` for parameters of initialisation. - The physical pins of the I2C busses on Pyboards V1.0 and V1.1 are: + The physical pins of the I2C buses on Pyboards V1.0 and V1.1 are: - ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)`` - ``I2C(2)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PB10, PB11)`` diff --git a/docs/library/pyb.SPI.rst b/docs/library/pyb.SPI.rst index 24e2ec5a73d2..c76b16789ad4 100644 --- a/docs/library/pyb.SPI.rst +++ b/docs/library/pyb.SPI.rst @@ -36,7 +36,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See ``init`` for parameters of initialisation. - The physical pins of the SPI busses are: + The physical pins of the SPI buses are: - ``SPI(1)`` is on the X position: ``(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)`` - ``SPI(2)`` is on the Y position: ``(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)`` diff --git a/docs/library/pyb.UART.rst b/docs/library/pyb.UART.rst index a1d6e5900255..e1735403c44a 100644 --- a/docs/library/pyb.UART.rst +++ b/docs/library/pyb.UART.rst @@ -57,7 +57,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See ``init`` for parameters of initialisation. - The physical pins of the UART busses on Pyboard are: + The physical pins of the UART buses on Pyboard are: - ``UART(4)`` is on ``XA``: ``(TX, RX) = (X1, X2) = (PA0, PA1)`` - ``UART(1)`` is on ``XB``: ``(TX, RX) = (X9, X10) = (PB6, PB7)`` diff --git a/docs/library/pyb.rst b/docs/library/pyb.rst index addcd20a91ae..321be3c52f2f 100644 --- a/docs/library/pyb.rst +++ b/docs/library/pyb.rst @@ -126,7 +126,7 @@ Power related functions - pclk2: frequency of the APB2 bus If given any arguments then the function sets the frequency of the CPU, - and the busses if additional arguments are given. Frequencies are given in + and the buses if additional arguments are given. Frequencies are given in Hz. Eg freq(120000000) sets sysclk (the CPU frequency) to 120MHz. Note that not all values are supported and the largest supported frequency not greater than the given value will be selected. diff --git a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h index 36d1d31315e3..afa81a5ba093 100644 --- a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h +++ b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h @@ -39,7 +39,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) // D6 #define MICROPY_HW_UART6_RX (pin_C7) // D5 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "I2C1" #define MICROPY_HW_I2C1_SCL (pin_B6) // SCL #define MICROPY_HW_I2C1_SDA (pin_B7) // SDA @@ -47,7 +47,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) // TX #define MICROPY_HW_I2C2_SDA (pin_B11) // RX -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "SPIFLASH" #define MICROPY_HW_SPI1_NSS (pin_A15) // FLASH CS #define MICROPY_HW_SPI1_SCK (pin_B3) // FLASH CLK @@ -59,7 +59,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // MISO #define MICROPY_HW_SPI2_MOSI (pin_B15) // MOSI -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "CAN1" #define MICROPY_HW_CAN1_TX (pin_B9) // D10 #define MICROPY_HW_CAN1_RX (pin_B8) // D9 diff --git a/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h b/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h index b330e8fdc1f2..0cded1bc866a 100644 --- a/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h +++ b/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h @@ -35,11 +35,11 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h b/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h index a88bcf675685..b017edab9931 100644 --- a/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h +++ b/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h @@ -28,20 +28,20 @@ // USART3 config for internal use #define MICROPY_HW_UART3_TX (pin_D8) #define MICROPY_HW_UART3_RX (pin_D9) -// USART4 config +// USART4 config #define MICROPY_HW_UART4_TX (pin_A0) #define MICROPY_HW_UART4_RX (pin_A1) // USART 1 is connected to the virtual com port on the ST-LINK #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/CERB40/mpconfigboard.h b/ports/stm32/boards/CERB40/mpconfigboard.h index 7c166922be67..2f9199d4e02b 100644 --- a/ports/stm32/boards/CERB40/mpconfigboard.h +++ b/ports/stm32/boards/CERB40/mpconfigboard.h @@ -31,7 +31,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) @@ -39,7 +39,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -49,7 +49,7 @@ #define MICROPY_HW_SPI3_MISO (pin_B4) #define MICROPY_HW_SPI3_MOSI (pin_B5) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h b/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h index 53c7f3cd5093..ed8178d7d4d6 100644 --- a/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h +++ b/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h @@ -32,7 +32,7 @@ #define MICROPY_HW_UART6_TX (pin_A11) #define MICROPY_HW_UART6_RX (pin_A12) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) @@ -40,7 +40,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_B4) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/HYDRABUS/mpconfigboard.h b/ports/stm32/boards/HYDRABUS/mpconfigboard.h index d8f1a864b29a..d894f1606cea 100644 --- a/ports/stm32/boards/HYDRABUS/mpconfigboard.h +++ b/ports/stm32/boards/HYDRABUS/mpconfigboard.h @@ -30,13 +30,13 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/LIMIFROG/mpconfigboard.h b/ports/stm32/boards/LIMIFROG/mpconfigboard.h index 4b750c17ff4f..be9b5a8bb878 100644 --- a/ports/stm32/boards/LIMIFROG/mpconfigboard.h +++ b/ports/stm32/boards/LIMIFROG/mpconfigboard.h @@ -25,13 +25,13 @@ void LIMIFROG_board_early_init(void); #define MICROPY_HW_UART3_TX (pin_C10) #define MICROPY_HW_UART3_RX (pin_C11) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h b/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h index d2075b52bf5f..38bf8b41e910 100644 --- a/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h +++ b/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h @@ -39,11 +39,11 @@ void NETDUINO_PLUS_2_board_early_init(void); #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) -// SPI busses +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_B12) #define MICROPY_HW_SPI2_SCK (pin_B13) #define MICROPY_HW_SPI2_MISO (pin_B14) diff --git a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h index fb8de60221e9..7333dcd0c1dc 100644 --- a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h @@ -49,13 +49,13 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 #define MICROPY_HW_I2C2_SDA (pin_B11) // pin 18 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h index babf63c7a1c9..6b874e298c1b 100644 --- a/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h @@ -30,7 +30,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -38,7 +38,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h index 26b1e0b619d2..e37ce889c38b 100644 --- a/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h @@ -21,7 +21,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -29,7 +29,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h index 2f488159a4f0..5297ceda5c4e 100644 --- a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h @@ -41,7 +41,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_F1) @@ -49,7 +49,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) // shared with DAC #define MICROPY_HW_SPI1_SCK (pin_A5) // shared with DAC #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -71,7 +71,7 @@ #define MICROPY_HW_SPI5_MISO (pin_E13) #define MICROPY_HW_SPI5_MOSI (pin_E14) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_G1) #define MICROPY_HW_CAN1_RX (pin_G0) #define MICROPY_HW_CAN2_TX (pin_G12) diff --git a/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h index 05c98e113f7e..86c02b517879 100644 --- a/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h @@ -38,11 +38,11 @@ #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_B3) #define MICROPY_HW_SPI1_MISO (pin_B4) @@ -58,7 +58,7 @@ #define MICROPY_HW_SPI5_MISO (pin_F8) #define MICROPY_HW_SPI5_MOSI (pin_F9) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h index cd4ad36fa0ee..27845b33aa83 100644 --- a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h @@ -24,7 +24,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) // Arduino D10, pin 17 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B7) // pin 21 on CN7 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -32,7 +32,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h index c9b0c60f274b..402efcfe31be 100644 --- a/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h @@ -40,19 +40,19 @@ #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C3_SCL (pin_H7) #define MICROPY_HW_I2C3_SDA (pin_H8) -// SPI +// SPI buses #define MICROPY_HW_SPI3_NSS (pin_A4) #define MICROPY_HW_SPI3_SCK (pin_B3) #define MICROPY_HW_SPI3_MISO (pin_B4) #define MICROPY_HW_SPI3_MOSI (pin_B5) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h index b659223b4d94..4ed9f41832d8 100644 --- a/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h @@ -41,7 +41,7 @@ void NUCLEO_F767ZI_board_early_init(void); #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_F1) @@ -49,13 +49,13 @@ void NUCLEO_F767ZI_board_early_init(void); #define MICROPY_HW_I2C4_SCL (pin_F14) #define MICROPY_HW_I2C4_SDA (pin_F15) -// SPI +// SPI buses #define MICROPY_HW_SPI3_NSS (pin_A4) #define MICROPY_HW_SPI3_SCK (pin_B3) #define MICROPY_HW_SPI3_MISO (pin_B4) #define MICROPY_HW_SPI3_MOSI (pin_B5) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_D1) #define MICROPY_HW_CAN1_RX (pin_D0) diff --git a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h index 324f2b03ce0d..f25263fd2b13 100644 --- a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h @@ -49,7 +49,7 @@ void NUCLEO_H743ZI_board_early_init(void); #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_F1) @@ -57,7 +57,7 @@ void NUCLEO_H743ZI_board_early_init(void); #define MICROPY_HW_I2C4_SCL (pin_F14) #define MICROPY_HW_I2C4_SDA (pin_F15) -// SPI +// SPI buses #define MICROPY_HW_SPI3_NSS (pin_A4) #define MICROPY_HW_SPI3_SCK (pin_B3) #define MICROPY_HW_SPI3_MISO (pin_B4) diff --git a/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h index a5c5dc9a0ee7..b7f7bc4c885b 100644 --- a/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h @@ -34,11 +34,11 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino D14, pin 5 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h index 14b3bab8a715..0a3ac1f185a7 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h @@ -42,13 +42,13 @@ #define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_4 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_A9) #define MICROPY_HW_I2C1_SDA (pin_A10) #define MICROPY_HW_I2C3_SCL (pin_A7) #define MICROPY_HW_I2C3_SDA (pin_B4) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_B0) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h index 9823ae9b9b74..1b5827d5aec0 100644 --- a/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h @@ -34,7 +34,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -44,7 +44,7 @@ #define MICROPY_HW_I2C4_SCL (pin_C0) // pin 38 on CN7 #define MICROPY_HW_I2C4_SDA (pin_C1) // pin 36 on CN7 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 @@ -58,7 +58,7 @@ #define MICROPY_HW_SPI3_MISO (pin_C11) // pin 2 on CN7 #define MICROPY_HW_SPI3_MOSI (pin_C12) // pin 3 on CN7 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) diff --git a/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h index 2899a97aceed..a7bb0b36bbf0 100644 --- a/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h @@ -46,7 +46,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) @@ -54,7 +54,7 @@ #define MICROPY_HW_I2C3_SCL (pin_C0) #define MICROPY_HW_I2C3_SDA (pin_C1) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_B3) #define MICROPY_HW_SPI1_MISO (pin_B4) @@ -64,7 +64,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN bus +// CAN buses #define MICROPY_HW_CAN1_TX (pin_A12) #define MICROPY_HW_CAN1_RX (pin_A11) diff --git a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h index d5cd7bb1ec66..999f97a70872 100644 --- a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h +++ b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h @@ -36,13 +36,13 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -52,7 +52,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index 57cc75efc6f9..48b3ee3eb909 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -122,7 +122,7 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_UART6_RTS (pyb_pin_BT_RTS) #define MICROPY_HW_UART6_CTS (pyb_pin_BT_CTS) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pyb_pin_X9) #define MICROPY_HW_I2C1_SDA (pyb_pin_X10) @@ -130,7 +130,7 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_I2C2_SCL (pyb_pin_Y9) #define MICROPY_HW_I2C2_SDA (pyb_pin_Y10) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pyb_pin_X5) #define MICROPY_HW_SPI1_SCK (pyb_pin_X6) @@ -146,7 +146,7 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_SPI3_MISO (pyb_pin_W50) #define MICROPY_HW_SPI3_MOSI (pyb_pin_W46) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "X" #define MICROPY_HW_CAN1_TX (pyb_pin_X10) #define MICROPY_HW_CAN1_RX (pyb_pin_X9) diff --git a/ports/stm32/boards/PYBD_SF6/mpconfigboard.h b/ports/stm32/boards/PYBD_SF6/mpconfigboard.h index cbfbe39945da..8c11d7b2eec9 100644 --- a/ports/stm32/boards/PYBD_SF6/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF6/mpconfigboard.h @@ -49,7 +49,7 @@ #define MICROPY_HW_UART7_TX (pyb_pin_W16) #define MICROPY_HW_UART7_RX (pyb_pin_W22B) -// Extra CAN busses +// Extra CAN buses #define MICROPY_HW_CAN2_NAME "Y" #define MICROPY_HW_CAN2_TX (pyb_pin_Y6) #define MICROPY_HW_CAN2_RX (pyb_pin_Y5) diff --git a/ports/stm32/boards/PYBLITEV10/mpconfigboard.h b/ports/stm32/boards/PYBLITEV10/mpconfigboard.h index 77509a600371..1643e250cb5c 100644 --- a/ports/stm32/boards/PYBLITEV10/mpconfigboard.h +++ b/ports/stm32/boards/PYBLITEV10/mpconfigboard.h @@ -35,7 +35,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -43,7 +43,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_B8) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.h b/ports/stm32/boards/PYBV10/mpconfigboard.h index dda98776cd34..52382f44d5c1 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.h +++ b/ports/stm32/boards/PYBV10/mpconfigboard.h @@ -44,7 +44,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -52,7 +52,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -64,7 +64,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "YA" #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.h b/ports/stm32/boards/PYBV11/mpconfigboard.h index 7d10c13e8fc0..8e8469404820 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.h +++ b/ports/stm32/boards/PYBV11/mpconfigboard.h @@ -44,7 +44,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -52,7 +52,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -64,7 +64,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "YA" #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 diff --git a/ports/stm32/boards/PYBV3/mpconfigboard.h b/ports/stm32/boards/PYBV3/mpconfigboard.h index 7f1531770f30..9c956efd6d09 100644 --- a/ports/stm32/boards/PYBV3/mpconfigboard.h +++ b/ports/stm32/boards/PYBV3/mpconfigboard.h @@ -44,7 +44,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -56,7 +56,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 #define MICROPY_HW_CAN2_TX (pin_B13) // Y6 diff --git a/ports/stm32/boards/PYBV4/mpconfigboard.h b/ports/stm32/boards/PYBV4/mpconfigboard.h index c1c60751138a..2bd569ecdfa9 100644 --- a/ports/stm32/boards/PYBV4/mpconfigboard.h +++ b/ports/stm32/boards/PYBV4/mpconfigboard.h @@ -41,7 +41,7 @@ #define MICROPY_HW_UART6_PORT (GPIOC) #define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -49,7 +49,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -61,7 +61,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "YA" #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 diff --git a/ports/stm32/boards/STM32F411DISC/mpconfigboard.h b/ports/stm32/boards/STM32F411DISC/mpconfigboard.h index 13172333b7b7..97da20461257 100644 --- a/ports/stm32/boards/STM32F411DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F411DISC/mpconfigboard.h @@ -26,7 +26,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B9) //#define MICROPY_HW_I2C2_SCL (pin_B10) @@ -34,7 +34,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_A9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/STM32F429DISC/mpconfigboard.h b/ports/stm32/boards/STM32F429DISC/mpconfigboard.h index 9b65f617437a..95cab08c8fa1 100644 --- a/ports/stm32/boards/STM32F429DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F429DISC/mpconfigboard.h @@ -22,11 +22,11 @@ #define MICROPY_HW_UART2_TX (pin_D8) #define MICROPY_HW_UART2_RX (pin_D9) -// I2C busses +// I2C buses #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses //#define MICROPY_HW_SPI1_NSS (pin_A4) //#define MICROPY_HW_SPI1_SCK (pin_A5) //#define MICROPY_HW_SPI1_MISO (pin_A6) @@ -52,7 +52,7 @@ //#define MICROPY_HW_SPI6_MISO (pin_G12) //#define MICROPY_HW_SPI6_MOSI (pin_G14) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F439/mpconfigboard.h b/ports/stm32/boards/STM32F439/mpconfigboard.h index a4e10934458f..702ef265bb32 100644 --- a/ports/stm32/boards/STM32F439/mpconfigboard.h +++ b/ports/stm32/boards/STM32F439/mpconfigboard.h @@ -40,11 +40,11 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_A8) #define MICROPY_HW_I2C1_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -74,7 +74,7 @@ //#define MICROPY_HW_SPI6_MISO (pin_G12) //#define MICROPY_HW_SPI6_MOSI (pin_G14) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h index 3e4c8261ccae..dbe52e6b10e0 100644 --- a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h @@ -43,13 +43,13 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -59,7 +59,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h index 5004a8ecac9d..87cefb50176f 100644 --- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h @@ -59,19 +59,19 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C3_SCL (pin_H7) #define MICROPY_HW_I2C3_SDA (pin_H8) -// SPI +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_A11) #define MICROPY_HW_SPI2_SCK (pin_A12) #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F7DISC/mpconfigboard.h b/ports/stm32/boards/STM32F7DISC/mpconfigboard.h index b07f0a7b8ffc..cf7061902ee7 100644 --- a/ports/stm32/boards/STM32F7DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F7DISC/mpconfigboard.h @@ -38,20 +38,20 @@ void STM32F7DISC_board_early_init(void); #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C3_SCL (pin_H7) #define MICROPY_HW_I2C3_SDA (pin_H8) -// SPI +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_I0) #define MICROPY_HW_SPI2_SCK (pin_I1) #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32L476DISC/mpconfigboard.h b/ports/stm32/boards/STM32L476DISC/mpconfigboard.h index ad62f761e55f..58fb8ef1440d 100644 --- a/ports/stm32/boards/STM32L476DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32L476DISC/mpconfigboard.h @@ -50,19 +50,19 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_D0) #define MICROPY_HW_SPI2_SCK (pin_D1) #define MICROPY_HW_SPI2_MISO (pin_D3) #define MICROPY_HW_SPI2_MOSI (pin_D4) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) diff --git a/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h b/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h index 5d9fa25bc3b8..d4d78454af7e 100644 --- a/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h @@ -26,13 +26,13 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_G14) #define MICROPY_HW_I2C1_SDA (pin_G13) #define MICROPY_HW_I2C2_SCL (pin_H4) #define MICROPY_HW_I2C2_SDA (pin_B14) -// SPI busses +// SPI buses // -> To the arduino connector #define MICROPY_HW_SPI1_NSS (pin_A15) #define MICROPY_HW_SPI1_SCK (pin_A5) diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index eceb5b6e7a8b..1b8db2e3e633 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -294,7 +294,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const /// the bus, if any). If extra arguments are given, the bus is initialised. /// See `init` for parameters of initialisation. /// -/// The physical pins of the UART busses are: +/// The physical pins of the UART buses are: /// /// - `UART(4)` is on `XA`: `(TX, RX) = (X1, X2) = (PA0, PA1)` /// - `UART(1)` is on `XB`: `(TX, RX) = (X9, X10) = (PB6, PB7)` diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index ee8b498a1359..f0bd38333d6c 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -660,7 +660,7 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, size_t n_args, co /// the bus, if any). If extra arguments are given, the bus is initialised. /// See `init` for parameters of initialisation. /// -/// The physical pins of the I2C busses are: +/// The physical pins of the I2C buses are: /// /// - `I2C(1)` is on the X position: `(SCL, SDA) = (X9, X10) = (PB6, PB7)` /// - `I2C(2)` is on the Y position: `(SCL, SDA) = (Y9, Y10) = (PB10, PB11)` diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c index cc9dd1163623..99a1cd77b4db 100644 --- a/ports/stm32/pyb_spi.c +++ b/ports/stm32/pyb_spi.c @@ -125,7 +125,7 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, size_t n_args, co // the bus, if any). If extra arguments are given, the bus is initialised. // See `init` for parameters of initialisation. // -// The physical pins of the SPI busses are: +// The physical pins of the SPI buses are: // - `SPI(1)` is on the X position: `(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)` // - `SPI(2)` is on the Y position: `(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)` // diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index f8ab791898d3..d3b3a784e86f 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -31,7 +31,7 @@ #include "py/mphal.h" #include "spi.h" -// Possible DMA configurations for SPI busses: +// Possible DMA configurations for SPI buses: // SPI1_TX: DMA2_Stream3.CHANNEL_3 or DMA2_Stream5.CHANNEL_3 // SPI1_RX: DMA2_Stream0.CHANNEL_3 or DMA2_Stream2.CHANNEL_3 // SPI2_TX: DMA1_Stream4.CHANNEL_0 diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c index 471b40ee0169..6373047b004f 100644 --- a/ports/teensy/uart.c +++ b/ports/teensy/uart.c @@ -302,7 +302,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, uint n_args, const mp /// the bus, if any). If extra arguments are given, the bus is initialised. /// See `init` for parameters of initialisation. /// -/// The physical pins of the UART busses are: +/// The physical pins of the UART buses are: /// /// - `UART(4)` is on `XA`: `(TX, RX) = (X1, X2) = (PA0, PA1)` /// - `UART(1)` is on `XB`: `(TX, RX) = (X9, X10) = (PB6, PB7)` From 04927dfaca06d68a35ff1a5700a5e4eb283b5f2d Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 14 Nov 2020 18:54:26 +1100 Subject: [PATCH 0005/4290] tools/mpy_ld.py: Support R_X86_64_GOTPCREL reloc for x86-64 arch. This can be treated by the linker the same as R_X86_64_REX_GOTPCRELX, according to https://reviews.llvm.org/D18301. Signed-off-by: Damien George --- tools/mpy_ld.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index 774966a7f68a..852249943887 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -73,6 +73,7 @@ R_ARM_BASE_PREL = 25 # aka R_ARM_GOTPC R_ARM_GOT_BREL = 26 # aka R_ARM_GOT32 R_ARM_THM_JUMP24 = 30 +R_X86_64_GOTPCREL = 9 R_X86_64_REX_GOTPCRELX = 42 R_386_GOT32X = 43 @@ -132,7 +133,7 @@ def __init__(self, name, mpy_feature, qstr_entry_size, word_size, arch_got, asm_ | MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, 2, 8, - (R_X86_64_REX_GOTPCRELX,), + (R_X86_64_GOTPCREL, R_X86_64_REX_GOTPCRELX), asm_jump_x86, ), "armv7m": ArchData( @@ -536,7 +537,10 @@ def do_relocation_text(env, text_addr, r): # Relcation pointing to GOT reloc = addr = env.got_entries[s.name].offset - elif env.arch.name == "EM_X86_64" and r_info_type == R_X86_64_REX_GOTPCRELX: + elif env.arch.name == "EM_X86_64" and r_info_type in ( + R_X86_64_GOTPCREL, + R_X86_64_REX_GOTPCRELX, + ): # Relcation pointing to GOT got_entry = env.got_entries[s.name] addr = env.got_section.addr + got_entry.offset From f49d47c167ce97b48ff3e9cbbc016b09664390f5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Nov 2020 23:37:05 +1100 Subject: [PATCH 0006/4290] py/asmx64: Support use of top 8 regs in src_r64 argument. Signed-off-by: Damien George --- py/asmx64.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/py/asmx64.c b/py/asmx64.c index fd64eaf98b1c..62df5c6d4ad7 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -285,31 +285,28 @@ void asm_x64_mov_r64_to_mem64(asm_x64_t *as, int src_r64, int dest_r64, int dest } void asm_x64_mov_mem8_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { - assert(src_r64 < 8); - if (dest_r64 < 8) { + if (src_r64 < 8 && dest_r64 < 8) { asm_x64_write_byte_2(as, 0x0f, OPCODE_MOVZX_RM8_TO_R64); } else { - asm_x64_write_byte_3(as, REX_PREFIX | REX_R, 0x0f, OPCODE_MOVZX_RM8_TO_R64); + asm_x64_write_byte_3(as, REX_PREFIX | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), 0x0f, OPCODE_MOVZX_RM8_TO_R64); } asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } void asm_x64_mov_mem16_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { - assert(src_r64 < 8); - if (dest_r64 < 8) { + if (src_r64 < 8 && dest_r64 < 8) { asm_x64_write_byte_2(as, 0x0f, OPCODE_MOVZX_RM16_TO_R64); } else { - asm_x64_write_byte_3(as, REX_PREFIX | REX_R, 0x0f, OPCODE_MOVZX_RM16_TO_R64); + asm_x64_write_byte_3(as, REX_PREFIX | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), 0x0f, OPCODE_MOVZX_RM16_TO_R64); } asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } void asm_x64_mov_mem32_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { - assert(src_r64 < 8); - if (dest_r64 < 8) { + if (src_r64 < 8 && dest_r64 < 8) { asm_x64_write_byte_1(as, OPCODE_MOV_RM64_TO_R64); } else { - asm_x64_write_byte_2(as, REX_PREFIX | REX_R, OPCODE_MOV_RM64_TO_R64); + asm_x64_write_byte_2(as, REX_PREFIX | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), OPCODE_MOV_RM64_TO_R64); } asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } From 5176a2d7325d941d8f2f41b31eab87b6e7a83f06 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Nov 2020 23:37:58 +1100 Subject: [PATCH 0007/4290] py/emitnative: Fix x86-64 emitter to generate correct 8/16-bit stores. Fixes issue #6643. Signed-off-by: Damien George --- py/emitnative.c | 4 ++-- tests/micropython/viper_misc2.py | 21 +++++++++++++++++++++ tests/micropython/viper_misc2.py.exp | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/micropython/viper_misc2.py create mode 100644 tests/micropython/viper_misc2.py.exp diff --git a/py/emitnative.c b/py/emitnative.c index 052a505911d2..425ba2d33e52 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1769,7 +1769,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { int reg_index = REG_ARG_2; int reg_value = REG_ARG_3; emit_pre_pop_reg_flexible(emit, &vtype_base, ®_base, reg_index, reg_value); - #if N_X86 + #if N_X64 || N_X86 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) emit_pre_pop_reg(emit, &vtype_value, reg_value); #else @@ -1856,7 +1856,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, MP_ERROR_TEXT("can't store with '%q' index"), vtype_to_qstr(vtype_index)); } - #if N_X86 + #if N_X64 || N_X86 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) emit_pre_pop_reg(emit, &vtype_value, reg_value); #else diff --git a/tests/micropython/viper_misc2.py b/tests/micropython/viper_misc2.py new file mode 100644 index 000000000000..8f0be487d626 --- /dev/null +++ b/tests/micropython/viper_misc2.py @@ -0,0 +1,21 @@ +# Miscellaneous viper tests + +# Test correct use of registers in load and store +@micropython.viper +def expand(dest: ptr8, source: ptr8, length: int): + n = 0 + for x in range(0, length, 2): + c = source[x] + d = source[x + 1] + dest[n] = (c & 0xE0) | ((c & 0x1C) >> 1) + n += 1 + dest[n] = ((c & 3) << 6) | ((d & 0xE0) >> 4) + n += 1 + dest[n] = ((d & 0x1C) << 3) | ((d & 3) << 2) + n += 1 + + +source = b"\xaa\xaa\xff\xff" +dest = bytearray(len(source) // 2 * 3) +expand(dest, source, len(source)) +print(dest) diff --git a/tests/micropython/viper_misc2.py.exp b/tests/micropython/viper_misc2.py.exp new file mode 100644 index 000000000000..eff2f5e41d24 --- /dev/null +++ b/tests/micropython/viper_misc2.py.exp @@ -0,0 +1 @@ +bytearray(b'\xa4\x8aH\xee\xce\xec') From a96afae90f6e5d693173382561d06e583b0b5fa5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 May 2021 14:10:37 +1000 Subject: [PATCH 0008/4290] stm32/sdio: Fix case of SDIO DMA turning off mid transfer. The DMA driver will turn off DMA if it hasn't been used for an amount of time (to save power). The SDIO driver for cyw43 WLAN was not informing the DMA driver that it was using DMA and there was a chance that the DMA would turn off in the middle of an SDIO DMA transfer. The symptoms of this would be printing of SDIO error messages and a failure to communicate with the cyw43 WLAN module. This commit fixes this issue by changing the SDIO driver to use the dma_nohal_XXX API to initialise and start the DMA. Signed-off-by: Damien George --- ports/stm32/dma.c | 2 +- ports/stm32/sdio.c | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 4320315ba4e5..d4b41771b081 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -40,7 +40,7 @@ #define DMA_IDLE_TICK_MAX (8) // 8*8 = 64 msec #define DMA_IDLE_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & DMA_SYSTICK_MASK) == 0) -#define ENABLE_SDIO (MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD) +#define ENABLE_SDIO (MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD || MICROPY_PY_NETWORK_CYW43) typedef enum { dma_id_not_defined=-1, diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index dfd409257759..0291e3e81d3c 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -28,6 +28,7 @@ #include "py/mperrno.h" #include "py/mphal.h" +#include "dma.h" #include "pin.h" #include "pin_static_af.h" #include "pendsv.h" @@ -382,27 +383,21 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le } #if defined(STM32F7) - DMA2->LIFCR = 0x3f << 22; - DMA2_Stream3->FCR = 0x07; // ? - DMA2_Stream3->PAR = (uint32_t)&SDMMC->FIFO; if ((uint32_t)buf & 3) { printf("sdio_transfer_cmd53: buf=%p is not aligned for DMA\n", buf); return -MP_EINVAL; } - DMA2_Stream3->M0AR = (uint32_t)buf; - DMA2_Stream3->NDTR = ((len + block_size - 1) & ~(block_size - 1)) / 4; - DMA2_Stream3->CR = 4 << 25 // channel 4 - | 1 << 23 // MBURST INCR4 - | 1 << 21 // PBURST INCR4 - | 3 << 16 // PL very high - | 2 << 13 // MSIZE word - | 2 << 11 // PSIZE word - | 1 << 10 // MINC enabled - | 0 << 9 // PINC disabled - | write << 6 // DIR mem-to-periph - | 1 << 5 // PFCTRL periph is flow controller - | 1 << 0 // EN + uint32_t dma_config = + 2 << DMA_SxCR_MSIZE_Pos // MSIZE word + | 2 << DMA_SxCR_PSIZE_Pos // PSIZE word + | write << DMA_SxCR_DIR_Pos // DIR mem-to-periph + | 1 << DMA_SxCR_PFCTRL_Pos // PFCTRL periph is flow controller ; + uint32_t dma_src = (uint32_t)buf; + uint32_t dma_dest = (uint32_t)&SDMMC->FIFO; + uint32_t dma_len = ((len + block_size - 1) & ~(block_size - 1)) / 4; + dma_nohal_init(&dma_SDIO_0, dma_config); + dma_nohal_start(&dma_SDIO_0, dma_src, dma_dest, dma_len); #else SDMMC->IDMABASE0 = (uint32_t)buf; SDMMC->IDMACTRL = SDMMC_IDMA_IDMAEN; @@ -456,6 +451,9 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le #else printf("sdio_transfer_cmd53: timeout wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->DCTRL, (uint)SDMMC->IDMACTRL); #endif + if (sdmmc_dma) { + dma_nohal_deinit(&dma_SDIO_0); + } return -MP_ETIMEDOUT; } } @@ -468,6 +466,9 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le #else printf("sdio_transfer_cmd53: error=%08lx wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", sdmmc_error, write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->DCTRL, (uint)SDMMC->IDMACTRL); #endif + if (sdmmc_dma) { + dma_nohal_deinit(&dma_SDIO_0); + } return -(0x1000000 | sdmmc_error); } @@ -476,6 +477,8 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le printf("sdio_transfer_cmd53: didn't transfer correct length: cur=%p top=%p\n", sdmmc_buf_cur, sdmmc_buf_top); return -MP_EIO; } + } else { + dma_nohal_deinit(&dma_SDIO_0); } return 0; From 748339b28126e69fd2dc2778b2a182901d0a4693 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 18 May 2021 22:17:45 +1000 Subject: [PATCH 0009/4290] stm32/uart: Configure pull-up only on RX and CTS, not TX and RTS. RX and CTS are the input pins and pull-ups are enabled so they don't cause a problem if left unconnected. But the output pins don't need a pull up (they were originally all configured with pull up in commit 8f7491a109a555ca897ae49efe98f4cc2b080311). If needed, the pull-ups can be disabled in Python using machine.Pin after the UART is constructed. See issue #4369. Signed-off-by: Damien George --- ports/stm32/uart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index a2b69967b6e4..9f74416170f8 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -474,10 +474,11 @@ bool uart_init(pyb_uart_obj_t *uart_obj, } uint32_t mode = MP_HAL_PIN_MODE_ALT; - uint32_t pull = MP_HAL_PIN_PULL_UP; for (uint i = 0; i < 4; i++) { if (pins[i] != NULL) { + // Configure pull-up on RX and CTS (the input pins). + uint32_t pull = (i & 1) ? MP_HAL_PIN_PULL_UP : MP_HAL_PIN_PULL_NONE; bool ret = mp_hal_pin_config_alt(pins[i], mode, pull, uart_fn, uart_unit); if (!ret) { return false; From ea81bcf1c0ddeb8be34192cbededecfa425c039b Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 May 2021 23:57:45 +1000 Subject: [PATCH 0010/4290] stm32/mboot: Leave bootloader from thread mode, not from IRQ. Leaving the bootloader from an IRQ (eg USB or I2C IRQ) will not work if MBOOT_LEAVE_BOOTLOADER_VIA_RESET is disabled, ie if mboot jumps directly to the application. This is because the CPU will still be in IRQ state when the application starts and IRQs of lower priority will be blocked. Fix this by setting a flag when the bootloader should finish, and exit the bootloader always from the main (top level) thread. This also improves the USB behaviour of mboot: it no longer abruptly disconnects when the manifest command is sent. Signed-off-by: Damien George --- ports/stm32/mboot/dfu.h | 2 ++ ports/stm32/mboot/main.c | 33 ++++++++++++++++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/ports/stm32/mboot/dfu.h b/ports/stm32/mboot/dfu.h index 73db3545d8d5..e867a3e22d0c 100644 --- a/ports/stm32/mboot/dfu.h +++ b/ports/stm32/mboot/dfu.h @@ -26,6 +26,7 @@ #ifndef MICROPY_INCLUDED_STM32_MBOOT_DFU_H #define MICROPY_INCLUDED_STM32_MBOOT_DFU_H +#include #include // DFU spec: https://www.usb.org/sites/default/files/DFU_1.1.pdf @@ -106,6 +107,7 @@ typedef struct _dfu_state_t { dfu_cmd_t cmd; dfu_status_t status; uint8_t error; + bool leave_dfu; uint16_t wBlockNum; uint16_t wLength; uint32_t addr; diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 3a0242a8d6bf..c1e1d59d235d 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -106,8 +106,6 @@ static volatile uint32_t systick_ms; // Global dfu state dfu_context_t dfu_context SECTION_NOZERO_BSS; -static void do_reset(void); - uint32_t get_le32(const uint8_t *b) { return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24; } @@ -771,7 +769,7 @@ void i2c_slave_process_rx_end(i2c_slave_t *i2c) { memcpy(buf + 12 + sizeof(MICROPY_HW_MCU_NAME), MICROPY_HW_BOARD_NAME, sizeof(MICROPY_HW_BOARD_NAME) - 1); len = 12 + sizeof(MICROPY_HW_MCU_NAME) + sizeof(MICROPY_HW_BOARD_NAME) - 1; } else if (buf[0] == I2C_CMD_RESET && len == 0) { - do_reset(); + dfu_context.leave_dfu = true; } else if (buf[0] == I2C_CMD_GETLAYOUT && len == 0) { len = strlen(FLASH_LAYOUT_STR); memcpy(buf, FLASH_LAYOUT_STR, len); @@ -864,6 +862,7 @@ static void dfu_init(void) { dfu_context.cmd = DFU_CMD_NONE; dfu_context.status = DFU_STATUS_OK; dfu_context.error = 0; + dfu_context.leave_dfu = false; dfu_context.addr = 0x08000000; } @@ -931,7 +930,8 @@ static void dfu_handle_rx(int cmd, int arg, int len, const void *buf) { static void dfu_process(void) { if (dfu_context.state == DFU_STATE_MANIFEST) { - do_reset(); + // Set a flag to leave DFU mode from the main thread (here we are in an IRQ handler). + dfu_context.leave_dfu = true; } if (dfu_context.state == DFU_STATE_BUSY) { @@ -1412,17 +1412,6 @@ static void leave_bootloader(void) { NVIC_SystemReset(); } -static void do_reset(void) { - led_state_all(0); - mp_hal_delay_ms(50); - pyb_usbdd_shutdown(); - #if defined(MBOOT_I2C_SCL) - i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn); - #endif - mp_hal_delay_ms(50); - leave_bootloader(); -} - extern PCD_HandleTypeDef pcd_fs_handle; extern PCD_HandleTypeDef pcd_hs_handle; @@ -1561,7 +1550,7 @@ void stm32_main(int initial_r0) { #if MBOOT_USB_RESET_ON_DISCONNECT bool has_connected = false; #endif - for (;;) { + while (!dfu_context.leave_dfu) { #if USE_USB_POLLING #if MBOOT_USB_AUTODETECT_PORT || MICROPY_HW_USB_MAIN_DEV == USB_PHY_FS_ID if (USB_OTG_FS->GINTSTS & USB_OTG_FS->GINTMSK) { @@ -1585,10 +1574,20 @@ void stm32_main(int initial_r0) { has_connected = true; } if (has_connected && pyb_usbdd.hUSBDDevice.dev_state == USBD_STATE_SUSPENDED) { - do_reset(); + break; } #endif } + + // Shutdown and leave the bootloader. + led_state_all(0); + mp_hal_delay_ms(50); + pyb_usbdd_shutdown(); + #if defined(MBOOT_I2C_SCL) + i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn); + #endif + mp_hal_delay_ms(50); + leave_bootloader(); } void NMI_Handler(void) { From 247d7e2e8e7ec262a141b0fc4190a94cce8103ef Mon Sep 17 00:00:00 2001 From: Tobias Thyrrestrup Date: Tue, 18 May 2021 15:38:49 +0200 Subject: [PATCH 0011/4290] tools/pydfu.py: Remove default VID/PID values. As the new default behaviour, this allows PyDFU to be used with all devices, not just the ones matching a specific set of VID/PID values. But it's still possible to specify VID/PID if needed to narrow down the selection of the USB device. Signed-off-by: Tobias Thyrrestrup --- tools/pydfu.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tools/pydfu.py b/tools/pydfu.py index 42b4fa2da6fe..ea658d300bf3 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -23,10 +23,6 @@ import usb.util import zlib -# VID/PID -__VID = 0x0483 -__PID = 0xDF11 - # USB request __TIMEOUT __TIMEOUT = 4000 @@ -112,10 +108,10 @@ def find_dfu_cfg_descr(descr): return None -def init(): +def init(**kwargs): """Initializes the found DFU device so that we can program it.""" global __dev, __cfg_descr - devices = get_dfu_devices(idVendor=__VID, idProduct=__PID) + devices = get_dfu_devices(**kwargs) if not devices: raise ValueError("No DFU device found") if len(devices) > 1: @@ -565,15 +561,13 @@ def cli_progress(addr, offset, size): def main(): """Test program for verifying this files functionality.""" global __verbose - global __VID - global __PID # Parse CMD args parser = argparse.ArgumentParser(description="DFU Python Util") parser.add_argument( "-l", "--list", help="list available DFU devices", action="store_true", default=False ) - parser.add_argument("--vid", help="USB Vendor ID", type=lambda x: int(x, 0), default=__VID) - parser.add_argument("--pid", help="USB Product ID", type=lambda x: int(x, 0), default=__PID) + parser.add_argument("--vid", help="USB Vendor ID", type=lambda x: int(x, 0), default=None) + parser.add_argument("--pid", help="USB Product ID", type=lambda x: int(x, 0), default=None) parser.add_argument( "-m", "--mass-erase", help="mass erase device", action="store_true", default=False ) @@ -588,14 +582,18 @@ def main(): __verbose = args.verbose - __VID = args.vid - __PID = args.pid + kwargs = {} + if args.vid: + kwargs["idVendor"] = args.vid + + if args.pid: + kwargs["idProduct"] = args.pid if args.list: - list_dfu_devices(idVendor=__VID, idProduct=__PID) + list_dfu_devices(**kwargs) return - init() + init(**kwargs) command_run = False if args.mass_erase: From a7a9f2fe897d2c4e3c18618c996460224df08114 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Thu, 20 May 2021 22:12:35 -0500 Subject: [PATCH 0012/4290] tools/ci.sh: Update zephyr docker image to v0.17.3. Updates the zephyr docker image and SDK to the latest versions. Signed-off-by: Maureen Helm --- tools/ci.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ci.sh b/tools/ci.sh index 33cf364ddd22..57421ae242bc 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -479,14 +479,14 @@ function ci_windows_build { # ports/zephyr function ci_zephyr_setup { - docker pull zephyrprojectrtos/ci:v0.11.13 + docker pull zephyrprojectrtos/ci:v0.17.3 docker run --name zephyr-ci -d -it \ -v "$(pwd)":/micropython \ - -e ZEPHYR_SDK_INSTALL_DIR=/opt/sdk/zephyr-sdk-0.12.2 \ + -e ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-0.12.4 \ -e ZEPHYR_TOOLCHAIN_VARIANT=zephyr \ -e ZEPHYR_BASE=/zephyrproject/zephyr \ -w /micropython/ports/zephyr \ - zephyrprojectrtos/ci:v0.11.13 + zephyrprojectrtos/ci:v0.17.3 docker ps -a } From e61ac453dcabaeca2406f1fb6ef113522f341aa2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 22 May 2021 22:09:25 +1000 Subject: [PATCH 0013/4290] py/mkrules.cmake: Add MPY_LIB_DIR and BOARD_DIR to makemanifest call. So that the FROZEN_MANIFEST option in cmake works the same as make. Signed-off-by: Damien George --- py/mkrules.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/py/mkrules.cmake b/py/mkrules.cmake index f20240c62b29..7589255b2039 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -125,9 +125,13 @@ if(MICROPY_FROZEN_MANIFEST) MICROPY_MODULE_FROZEN_MPY=\(1\) ) + if(NOT MICROPY_LIB_DIR) + set(MICROPY_LIB_DIR ${MICROPY_DIR}/../micropython-lib) + endif() + add_custom_command( OUTPUT ${MICROPY_FROZEN_CONTENT} - COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/tools/makemanifest.py -o ${MICROPY_FROZEN_CONTENT} -v "MPY_DIR=${MICROPY_DIR}" -v "PORT_DIR=${MICROPY_PORT_DIR}" -b "${CMAKE_BINARY_DIR}" -f${MICROPY_CROSS_FLAGS} ${MICROPY_FROZEN_MANIFEST} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/tools/makemanifest.py -o ${MICROPY_FROZEN_CONTENT} -v "MPY_DIR=${MICROPY_DIR}" -v "MPY_LIB_DIR=${MICROPY_LIB_DIR}" -v "PORT_DIR=${MICROPY_PORT_DIR}" -v "BOARD_DIR=${MICROPY_BOARD_DIR}" -b "${CMAKE_BINARY_DIR}" -f${MICROPY_CROSS_FLAGS} ${MICROPY_FROZEN_MANIFEST} DEPENDS MICROPY_FORCE_BUILD ${MICROPY_QSTRDEFS_GENERATED} VERBATIM From 3b950ed2959c603ff30dd6052c157e7981c4d2d6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 22 May 2021 22:10:09 +1000 Subject: [PATCH 0014/4290] tools/ci.sh: Use FROZEN_MANIFEST in an esp32 build to test feature. This tests that FROZEN_MANIFEST works with cmake (on esp32 at least). Signed-off-by: Damien George --- tools/ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ci.sh b/tools/ci.sh index 57421ae242bc..7b38ce0df04f 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -109,7 +109,7 @@ function ci_esp32_build { make ${MAKEOPTS} -C ports/esp32 submodules make ${MAKEOPTS} -C ports/esp32 make ${MAKEOPTS} -C ports/esp32 clean - make ${MAKEOPTS} -C ports/esp32 USER_C_MODULES=../../../examples/usercmodule/micropython.cmake + make ${MAKEOPTS} -C ports/esp32 USER_C_MODULES=../../../examples/usercmodule/micropython.cmake FROZEN_MANIFEST=$(pwd)/ports/esp32/boards/manifest.py if [ -d $IDF_PATH/components/esp32s2 ]; then make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_S2 fi From 0aa01b0205adc7544315fed602029e792a235b2e Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 00:04:01 +1000 Subject: [PATCH 0015/4290] lib/mbedtls: Switch to currently latest commit of LTS branch v2.16. Signed-off-by: Damien George --- lib/mbedtls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mbedtls b/lib/mbedtls index 1b6a24f759ce..1bc2c9cb8b8f 160000 --- a/lib/mbedtls +++ b/lib/mbedtls @@ -1 +1 @@ -Subproject commit 1b6a24f759cefbb4a69ae9476885d7f42a847e3d +Subproject commit 1bc2c9cb8b8fe4659bd94b8ebba5a4c02029b7fa From ff5d39529c3bf331dd8171aaa24937b2650f40fd Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Fri, 21 Aug 2020 16:03:21 +0200 Subject: [PATCH 0016/4290] mimxrt: Implement machine.Pin class. - modified pin type from pin_obj_t to machine_pin_obj_t - created machine_pin.c - implemented basic version of make-pins.py to genertate pins.c/.h files automatically; the only alternate function currently supported is GPIO - added af.csv files for all supported MCUs - replaced pins.c/pins.h files with pin.csv for all boards - implemented on/off/high/low/value/init methods - Implemented IN/OUT/OPEN_DRAIN modes - modified LDFLAGS for DEBUG build to get usefull .elf file for debugging Signed-off-by: Philipp Ebensberger --- ports/mimxrt/Makefile | 41 ++- ports/mimxrt/README.md | 5 +- ports/mimxrt/board_init.c | 2 - .../boards/MIMXRT1010_EVK/mpconfigboard.h | 2 +- .../boards/MIMXRT1010_EVK/mpconfigboard.mk | 19 ++ ports/mimxrt/boards/MIMXRT1010_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv | 57 ++++ ports/mimxrt/boards/MIMXRT1010_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1011.ld | 2 +- ports/mimxrt/boards/MIMXRT1011_af.csv | 44 +++ .../boards/MIMXRT1020_EVK/mpconfigboard.h | 3 +- .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 18 ++ ports/mimxrt/boards/MIMXRT1020_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv | 33 +++ ports/mimxrt/boards/MIMXRT1020_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1021_af.csv | 94 ++++++ .../boards/MIMXRT1050_EVK/mpconfigboard.h | 2 +- ports/mimxrt/boards/MIMXRT1050_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv | 51 ++++ ports/mimxrt/boards/MIMXRT1050_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1052_af.csv | 125 ++++++++ .../boards/MIMXRT1060_EVK/mpconfigboard.h | 2 +- .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 19 ++ ports/mimxrt/boards/MIMXRT1060_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv | 51 ++++ ports/mimxrt/boards/MIMXRT1060_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1062_af.csv | 125 ++++++++ .../boards/MIMXRT1064_EVK/mpconfigboard.h | 2 +- ports/mimxrt/boards/MIMXRT1064_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv | 51 ++++ ports/mimxrt/boards/MIMXRT1064_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1064_af.csv | 125 ++++++++ ports/mimxrt/boards/TEENSY40/mpconfigboard.h | 2 +- ports/mimxrt/boards/TEENSY40/pins.c | 33 --- ports/mimxrt/boards/TEENSY40/pins.csv | 55 ++++ ports/mimxrt/boards/TEENSY40/pins.h | 30 -- ports/mimxrt/boards/make-pins.py | 259 +++++++++++++++++ ports/mimxrt/boards/mimxrt_prefix.c | 26 ++ ports/mimxrt/led.c | 6 +- ports/mimxrt/led.h | 2 +- ports/mimxrt/machine_pin.c | 273 ++++++++++++++++++ ports/mimxrt/modmachine.c | 2 + ports/mimxrt/mphalport.h | 4 + ports/mimxrt/pin.c | 106 ++++++- ports/mimxrt/pin.h | 112 ++++--- ports/mimxrt/tusb_port.c | 2 +- 46 files changed, 1662 insertions(+), 438 deletions(-) delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1011_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1021_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1052_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1062_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1064_af.csv delete mode 100644 ports/mimxrt/boards/TEENSY40/pins.c create mode 100644 ports/mimxrt/boards/TEENSY40/pins.csv delete mode 100644 ports/mimxrt/boards/TEENSY40/pins.h create mode 100644 ports/mimxrt/boards/make-pins.py create mode 100644 ports/mimxrt/boards/mimxrt_prefix.c create mode 100644 ports/mimxrt/machine_pin.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 3a001182a036..0c893f9634a8 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -23,6 +23,16 @@ GIT_SUBMODULES = lib/tinyusb lib/nxp_driver MCU_DIR = lib/nxp_driver/sdk/devices/$(MCU_SERIES) LD_FILES = boards/$(MCU_SERIES).ld $(TOP)/$(MCU_DIR)/gcc/$(MCU_SERIES)xxxxx_flexspi_nor.ld +MAKE_PINS = boards/make-pins.py +BOARD_PINS = $(BOARD_DIR)/pins.csv +AF_FILE = boards/$(MCU_SERIES)_af.csv +PREFIX_FILE = boards/mimxrt_prefix.c +GEN_PINS_SRC = $(BUILD)/pins_gen.c +GEN_PINS_HDR = $(HEADER_BUILD)/pins.h +GEN_PINS_QSTR = $(BUILD)/pins_qstr.h +GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h +GEN_PINS_AF_PY = $(BUILD)/pins_af.py + # mcu driver cause following warnings #CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs CFLAGS += -Wno-error=unused-parameter @@ -49,12 +59,14 @@ CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -D__START=main \ -DCPU_HEADER_H='<$(MCU_SERIES).h>' -LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref +LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref --print-memory-usage LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Tune for Debugging or Optimization ifeq ($(DEBUG),1) CFLAGS += -O0 -ggdb +LDFLAGS += --gc-sections +CFLAGS += -fdata-sections -ffunction-sections else CFLAGS += -Os -DNDEBUG LDFLAGS += --gc-sections @@ -95,8 +107,8 @@ SRC_C = \ tusb_port.c \ board_init.c \ $(BOARD_DIR)/flash_config.c \ - $(BOARD_DIR)/pins.c \ machine_led.c \ + machine_pin.c \ modutime.c \ modmachine.c \ mphalport.c \ @@ -116,15 +128,17 @@ SRC_S = lib/utils/gchelper_m3.s \ # List of sources for qstr extraction SRC_QSTR += \ machine_led.c \ + machine_pin.c \ modutime.c \ modmachine.c \ pin.c \ - $(BOARD_DIR)/pins.c \ + $(GEN_PINS_SRC) \ OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) +OBJ += $(BUILD)/pins_gen.o # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" $(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces @@ -142,4 +156,25 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(BUILD)/firmware.hex: $(BUILD)/firmware.elf $(Q)$(OBJCOPY) -O ihex -R .eeprom $< $@ +# Making OBJ use an order-only depenedency on the generated pins.h file +# has the side effect of making the pins.h file before we actually compile +# any of the objects. The normal dependency generation will deal with the +# case when pins.h is modified. But when it doesn't exist, we don't know +# which source files might need it. +$(OBJ): | $(GEN_PINS_HDR) + +# With conditional pins, we may need to regenerate qstrdefs.h when config +# options change. +$(HEADER_BUILD)/qstrdefs.generated.h: $(BOARD_DIR)/mpconfigboard.h + +# Use a pattern rule here so that make will only call make-pins.py once to make +# both pins_gen.c and pins.h +$(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: $(BOARD_PINS) $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE)\ + --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC) + +$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c + $(call compile_c) + include $(TOP)/py/mkrules.mk diff --git a/ports/mimxrt/README.md b/ports/mimxrt/README.md index a2b5cf79a16a..c24939f47879 100644 --- a/ports/mimxrt/README.md +++ b/ports/mimxrt/README.md @@ -5,10 +5,13 @@ Currently supports Teensy 4.0 and the i.MX RT1010 EVK board. Features: - REPL over USB VCP + - machine.Pin Known issues: - pyboard.py doesn't work with files larger than 64 bytes + - machine.Pin class currently does not support GPIOMUX option of + i.MX RT101x variants TODO: - Enable TCM - - Peripherals (pins, LED, Timers, etc) + - Peripherals (LED, Timers, etc) diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index 9095c880482d..0336cdf6865d 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -39,8 +39,6 @@ #include "clock_config.h" -#define LED_STATE_ON (0) - volatile uint32_t systick_ms = 0; const uint8_t dcd_data[] = { 0x00 }; diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index eeddd0e0213f..5a89423b50e3 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (16 * 1024 * 1024) // i.MX RT1010 EVK has 1 board LED -#define MICROPY_HW_LED1_PIN (GPIO_11) +#define MICROPY_HW_LED1_PIN (pin_GPIO_11) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index e178545845b2..c5b5055324b1 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -2,6 +2,25 @@ MCU_SERIES = MIMXRT1011 MCU_VARIANT = MIMXRT1011DAE5A JLINK_PATH = /media/RT1010-EVK/ +JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink + + +ifdef JLINK_IP +JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) +else +JLINK_CONNECTION_SETTINGS = -USB +endif + + +deploy_jlink: $(BUILD)/firmware.hex + $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "st" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "loadfile \"$(realpath $(BUILD)/firmware.hex)\"" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "qc" >> $(JLINK_COMMANDER_SCRIPT) + $(JLINK_PATH)JLinkExe -device $(MCU_VARIANT) -if SWD $(JLINK_CONNECTION_SETTINGS) -CommanderScript $(JLINK_COMMANDER_SCRIPT) deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.c deleted file mode 100644 index e0397e09edb2..000000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "pin.h" - -static pin_af_obj_t GPIO_11_af[] = { - PIN_AF(GPIOMUX_IO11, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_11 = PIN(GPIO_11, GPIO1, 5, GPIO_11_af); diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv new file mode 100644 index 000000000000..f7fdf39643ea --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv @@ -0,0 +1,57 @@ +D0,GPIO_09 +D1,GPIO_10 +D2,GPIO_AD_05 +D3,GPIO_AD_06 +D4,GPIO_08 +D5,GPIO_01 +D6,GPIO_AD_01 +D7,GPIO_AD_02 +D8,GPIO_SD_02 +D9,GPIO_03 +D10,GPIO_AD_05 +D11,GPIO_AD_04 +D12,GPIO_AD_03 +D13,GPIO_AD_06 +D14,GPIO_01 +D15,GPIO_02 +CUR_A,GPIO_AD_01 +CUR_B,GPIO_AD_02 +CUR_C,GPIO_AD_07 +VOLT_DCB,GPIO_AD_09 +CUR_DCB,GPIO_AD_10 +A0,GPIO_AD_07 +A1,GPIO_AD_09 +A2,GPIO_AD_10 +A3,GPIO_AD_14 +A4,GPIO_AD_01 +A5,GPIO_AD_02 +PWM_AT,GPIO_02 +PWM_AB,GPIO_01 +PWM_BT,GPIO_04 +PWM_BB,GPIO_03 +PWM_CT,GPIO_06 +PWM_CB,GPIO_05 +ENC_A,GPIO_AD_05 +ENC_B,GPIO_AD_06 +LED_GREEN,GPIO_11 +GPIO_01,GPIO_01 +GPIO_02,GPIO_02 +GPIO_03,GPIO_03 +GPIO_04,GPIO_04 +GPIO_05,GPIO_05 +GPIO_06,GPIO_06 +GPIO_08,GPIO_08 +GPIO_09,GPIO_09 +GPIO_10,GPIO_10 +GPIO_11,GPIO_11 +GPIO_AD_01,GPIO_AD_01 +GPIO_AD_02,GPIO_AD_02 +GPIO_AD_03,GPIO_AD_03 +GPIO_AD_04,GPIO_AD_04 +GPIO_AD_05,GPIO_AD_05 +GPIO_AD_06,GPIO_AD_06 +GPIO_AD_07,GPIO_AD_07 +GPIO_AD_09,GPIO_AD_09 +GPIO_AD_10,GPIO_AD_10 +GPIO_AD_14,GPIO_AD_14 +GPIO_SD_02,GPIO_SD_02 diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.h deleted file mode 100644 index 99534932a19d..000000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_11; diff --git a/ports/mimxrt/boards/MIMXRT1011.ld b/ports/mimxrt/boards/MIMXRT1011.ld index 0512c48a7f2d..9db30adee8a4 100644 --- a/ports/mimxrt/boards/MIMXRT1011.ld +++ b/ports/mimxrt/boards/MIMXRT1011.ld @@ -1,5 +1,5 @@ /* 24kiB stack. */ -__stack_size__ = 0x6000; +__stack_size__ = 0x4000; _estack = __StackTop; _sstack = __StackLimit; diff --git a/ports/mimxrt/boards/MIMXRT1011_af.csv b/ports/mimxrt/boards/MIMXRT1011_af.csv new file mode 100644 index 000000000000..11dd08546332 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1011_af.csv @@ -0,0 +1,44 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_00,FLEXSPI_B_DQS,SAI3_MCLK,LPSPI2_PCS3,LPSPI1_PCS3,PIT_TRIGGER0,GPIO1_IO00,,,,,,,ALT5 +GPIO_01,SAI1_RX_BCLK,WDOG1_ANY,FLEXPWM1_PWM0_B,LPI2C1_SDA,KPP_ROW3,GPIO1_IO01,,,,,,,ALT5 +GPIO_02,SAI1_RX_SYNC,WDOG2_B,FLEXPWM1_PWM0_A,LPI2C1_SCL,KPP_COL3,GPIO1_IO02,,,,,,,ALT5 +GPIO_03,SAI1_RX_DATA0,GPT1_COMPARE3,FLEXPWM1_PWM1_B,,SPDIF_SR_CLK,GPIO1_IO03,,,,,,,ALT5 +GPIO_04,SAI1_TX_DATA0,GPT1_CAPTURE2,FLEXPWM1_PWM1_A,,SPDIF_IN,GPIO1_IO04,,,,,,,ALT5 +GPIO_05,SAI1_TX_DATA1,GPT1_COMPARE2,FLEXPWM1_PWM2_B,LPUART4_RXD,SPDIF_OUT,GPIO1_IO05,,,,,,,ALT0 +GPIO_06,SAI1_TX_BCLK,GPT1_CAPTURE1,FLEXPWM1_PWM2_A,LPUART4_TXD,SPDIF_EXT_CLK,GPIO1_IO06,,,,,,,ALT5 +GPIO_07,SAI1_TX_SYNC,GPT1_COMPARE1,FLEXPWM1_PWM3_B,LPUART3_RXD,SPDIF_LOCK,GPIO1_IO07,LPUART1_RTS_B,,,,,,ALT5 +GPIO_08,SAI1_MCLK,GPT1_CLK,FLEXPWM1_PWM3_A,LPUART3_TXD,FLEXIO1_IO00,GPIO1_IO08,LPUART1_CTS_B,,,,,,ALT5 +GPIO_09,LPUART1_RXD,WDOG1_B,FLEXSPI_A_SS1_B,LPI2C2_SDA,FLEXIO1_IO01,GPIO1_IO09,SPDIF_SR_CLK,,,,,,ALT5 +GPIO_10,LPUART1_TXD,LPI2C1_HREQ,EWM_OUT_B,LPI2C2_SCL,FLEXIO1_IO02,GPIO1_IO10,SPDIF_IN,,,,,,ALT5 +GPIO_11,LPUART3_RXD,LPI2C1_SDA,KPP_ROW0,FLEXSPI_B_SS1_B,FLEXIO1_IO03,GPIO1_IO11,SPDIF_OUT,ARM_TRACE3,,,,,ALT5 +GPIO_12,LPUART3_TXD,LPI2C1_SCL,KPP_COL0,USB_OTG1_OC,FLEXIO1_IO04,GPIO1_IO12,SPDIF_EXT_CLK,ARM_TRACE2,,,,,ALT5 +GPIO_13,LPUART2_RXD,LPSPI2_PCS2,KPP_ROW3,USB_OTG1_ID,FLEXIO1_IO05,GPIO1_IO13,SPDIF_LOCK,ARM_TRACE1,,,,,ALT5 +GPIO_AD_00,LPUART2_TXD,LPSPI1_PCS2,KPP_COL3,USB_OTG1_PWR,FLEXIO1_IO20,GPIO1_IO14,ARM_NMI,ARM_TRACE0,,,ADC1_IN0,,ALT5 +GPIO_AD_01,LPUART4_RXD,LPSPI2_PCS1,WDOG1_ANY,LPI2C2_SDA,MQS_LEFT,GPIO1_IO15,USB_OTG1_OC,ARM_TRACE_SWO,,,ADC1_IN1,,ALT5 +GPIO_AD_02,LPUART4_TXD,LPSPI1_PCS1,WDOG2_B,LPI2C2_SCL,MQS_RIGHT,GPIO1_IO16,,ARM_TRACE_CLK,,,ADC1_IN2,,ALT5 +GPIO_AD_03,LPSPI1_SDI,PIT_TRIGGER3,FLEXPWM1_PWM2_B,KPP_ROW2,GPT2_CLK,GPIO1_IO17,SNVS_VIO_5_B,JTAG_DE_B,,,ADC1_IN3,,ALT5 +GPIO_AD_04,LPSPI1_SDO,PIT_TRIGGER2,FLEXPWM1_PWM2_A,KPP_COL2,GPT2_COMPARE1,GPIO1_IO18,SNVS_VIO_5_CTL,,,,ADC1_IN4,,ALT5 +GPIO_AD_05,LPSPI1_PCS0,PIT_TRIGGER1,FLEXPWM1_PWM3_B,KPP_ROW1,GPT2_CAPTURE1,GPIO1_IO19,,,,,ADC1_IN5,,ALT5 +GPIO_AD_06,LPSPI1_SCK,PIT_TRIGGER0,FLEXPWM1_PWM3_A,KPP_COL1,GPT2_COMPARE2,GPIO1_IO20,LPI2C1_HREQ,,,,ADC1_IN6,,ALT5 +GPIO_AD_07,LPI2C2_SDA,LPUART3_RXD,ARM_CM7_RXEV,LPUART2_RTS_B,GPT2_CAPTURE2,GPIO1_IO21,OCOTP_FUSE_LATCHED,XBAR1_INOUT03,,,ADC1_IN7,,ALT5 +GPIO_AD_08,LPI2C2_SCL,LPUART3_TXD,ARM_CM7_TXEV,LPUART2_CTS_B,GPT2_COMPARE3,GPIO1_IO22,EWM_OUT_B,JTAG_TRSTB,,,ADC1_IN8,,ALT7 +GPIO_AD_09,LPSPI2_SDI,FLEXPWM1_PWM3_X,KPP_ROW2,ARM_TRACE_SWO,FLEXIO1_IO21,GPIO1_IO23,REF_CLK_32K,JTAG_TDO,,,ADC1_IN9,,ALT7 +GPIO_AD_10,LPSPI2_SDO,FLEXPWM1_PWM2_X,KPP_COL2,PIT_TRIGGER3,FLEXIO1_IO22,GPIO1_IO24,USB_OTG1_ID,JTAG_TDI,,,ADC1_IN10,,ALT7 +GPIO_AD_11,LPSPI2_PCS0,FLEXPWM1_PWM1_X,KPP_ROW1,PIT_TRIGGER2,FLEXIO1_IO23,GPIO1_IO25,WDOG1_B,JTAG_MOD,,,ADC1_IN11,,ALT7 +GPIO_AD_12,LPSPI2_SCK,FLEXPWM1_PWM0_X,KPP_COL1,PIT_TRIGGER1,FLEXIO1_IO24,GPIO1_IO26,USB_OTG1_PWR,JTAG_TCK,,,ADC1_IN12,,ALT7 +GPIO_AD_13,LPI2C1_SDA,LPUART3_RTS_B,KPP_ROW0,LPUART4_RTS_B,FLEXIO1_IO25,GPIO1_IO27,ARM_NMI,JTAG_TMS,,,ADC1_IN13,,ALT7 +GPIO_AD_14,LPI2C1_SCL,LPUART3_CTS_B,KPP_COL0,LPUART4_CTS_B,FLEXIO1_IO26,GPIO1_IO28,REF_CLK_24M,XBAR1_INOUT02,,,ADC1_IN14,,ALT5 +GPIO_SD_00,FLEXSPI_B_SS0_B,SAI3_TX_SYNC,ARM_CM7_RXEV,CCM_STOP,FLEXIO1_IO06,GPIO2_IO00,SRC_BT_CFG2,,,,,,ALT5 +GPIO_SD_01,FLEXSPI_B_DATA1,SAI3_TX_BCLK,FLEXPWM1_PWM0_B,CCM_CLKO2,FLEXIO1_IO07,GPIO2_IO01,SRC_BT_CFG1,,,,,,ALT5 +GPIO_SD_02,FLEXSPI_B_DATA2,SAI3_TX_DATA,FLEXPWM1_PWM0_A,CCM_CLKO1,FLEXIO1_IO08,GPIO2_IO02,SRC_BT_CFG0,,,,,,ALT5 +GPIO_SD_03,FLEXSPI_B_DATA0,SAI3_RX_DATA,FLEXPWM1_PWM1_B,CCM_REF_EN_B,FLEXIO1_IO09,GPIO2_IO03,SRC_BOOT_MODE1,,,,,,ALT6 +GPIO_SD_04,FLEXSPI_B_DATA3,SAI3_RX_SYNC,FLEXPWM1_PWM1_A,CCM_WAIT,FLEXIO1_IO10,GPIO2_IO04,SRC_BOOT_MODE0,,,,,,ALT6 +GPIO_SD_05,FLEXSPI_A_SS1_B,LPI2C1_SDA,LPSPI1_SDI,,FLEXIO1_IO11,GPIO2_IO05,,,,,,,ALT5 +GPIO_SD_06,FLEXSPI_A_SS0_B,LPI2C1_SCL,LPSPI1_SDO,,FLEXIO1_IO12,GPIO2_IO06,,,,,,,ALT5 +GPIO_SD_07,FLEXSPI_A_DATA1,LPI2C2_SDA,LPSPI1_PCS0,,FLEXIO1_IO13,GPIO2_IO07,,,,,,,ALT5 +GPIO_SD_08,FLEXSPI_A_DATA2,LPI2C2_SCL,LPSPI1_SCK,,FLEXIO1_IO14,GPIO2_IO08,,,,,,,ALT5 +GPIO_SD_09,FLEXSPI_A_DATA0,LPSPI2_SDI,LPUART2_RXD,,FLEXIO1_IO15,GPIO2_IO09,,,,,,,ALT5 +GPIO_SD_10,FLEXSPI_A_SCLK,LPSPI2_SDO,LPUART2_TXD,,FLEXIO1_IO16,GPIO2_IO10,,,,,,,ALT5 +GPIO_SD_11,FLEXSPI_A_DATA3,LPSPI2_SCK,LPUART1_RXD,,FLEXIO1_IO17,GPIO2_IO11,WDOG1_RST_B_DEB,,,,,,ALT5 +GPIO_SD_12,FLEXSPI_A_DQS,LPSPI2_PCS0,LPUART1_TXD,,FLEXIO1_IO18,GPIO2_IO12,WDOG2_RST_B_DEB,,,,,,ALT5 +GPIO_SD_13,FLEXSPI_B_SCLK,SAI3_RX_BCLK,ARM_CM7_TXEV,CCM_PMIC_RDY,FLEXIO1_IO19,GPIO2_IO13,SRC_BT_CFG3,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index 8598f76bf183..d8c0f00e276e 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -4,6 +4,7 @@ #define BOARD_FLASH_SIZE (8 * 1024 * 1024) // i.MX RT1020 EVK has 1 board LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_05) +// Todo: think about replacing the define with searching in the generated pins? +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_05) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index f3b1689524e2..0f5bb967af31 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -2,6 +2,24 @@ MCU_SERIES = MIMXRT1021 MCU_VARIANT = MIMXRT1021DAG5A JLINK_PATH ?= /media/RT1020-EVK/ +JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink + + +ifdef JLINK_IP +JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) +else +JLINK_CONNECTION_SETTINGS = +endif + + +deploy_jlink: $(BUILD)/firmware.hex + $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "st" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "loadfile \"$(realpath $(BUILD)/firmware.hex)\"" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "qc" >> $(JLINK_COMMANDER_SCRIPT) + $(JLINK_PATH)JLinkExe -device $(MCU_VARIANT) -if SWD $(JLINK_CONNECTION_SETTINGS) -CommanderScript $(JLINK_COMMANDER_SCRIPT) deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.c deleted file mode 100644 index 946b6efca8b2..000000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "pin.h" - -static pin_af_obj_t GPIO_AD_B0_05_af[] = { - PIN_AF(GPIO1_IO05, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_05 = PIN(GPIO_AD_B0_05, GPIO1, 5, GPIO_AD_B0_05_af); diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv new file mode 100644 index 000000000000..8420bbd82156 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv @@ -0,0 +1,33 @@ +D0,GPIO_AD_B1_09 +D1,GPIO_AD_B1_08 +D2,GPIO_AD_B0_09 +D3,GPIO_AD_B0_07 +D4,GPIO_AD_B0_05 +D5,GPIO_AD_B0_06 +D6,GPIO_AD_B0_14 +D7,GPIO_AD_B1_06 +D8,GPIO_AD_B1_07 +D9,GPIO_AD_B0_15 +D10,GPIO_AD_B0_11 +D11,GPIO_AD_B0_12 +D12,GPIO_AD_B0_13 +D13,GPIO_AD_B0_10 +D14,GPIO_SD_B1_03 +D15,GPIO_SD_B1_02 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_12 +A3,GPIO_AD_B1_13 +A4,GPIO_AD_B1_15 +A5,GPIO_AD_B1_14 +RX,GPIO_AD_B1_09 +TX,GPIO_AD_B1_08 +SDA,GPIO_AD_B1_15 +SCL,GPIO_AD_B1_14 +I2C_SCL,GPIO_SD_B1_02 +I2C_SDA,GPIO_SD_B1_03 +SCK,GPIO_AD_B0_10 +SDI,GPIO_AD_B0_13 +SDO,GPIO_AD_B0_12 +CS,GPIO_AD_B0_11 +LED_GREEN,GPIO_AD_B0_05 \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.h deleted file mode 100644 index 158929911c7a..000000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_05; diff --git a/ports/mimxrt/boards/MIMXRT1021_af.csv b/ports/mimxrt/boards/MIMXRT1021_af.csv new file mode 100644 index 000000000000..668b415f0ba7 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1021_af.csv @@ -0,0 +1,94 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,JTAG_TMS,,,,,GPIO1_IO00,USBPHY1_TSTI_TX_EN,GPT1_COMPARE1,,,,,ALT0 +GPIO_AD_B0_01,JTAG_TCK,,,,,GPIO1_IO01,USBPHY1_TSTI_TX_HIZ,GPT1_CAPTURE2,,,,,ALT0 +GPIO_AD_B0_02,JTAG_MOD,,,,,GPIO1_IO02,USBPHY1_TSTI_TX_LS_MODE,GPT1_CAPTURE1,,,,,ALT0 +GPIO_AD_B0_03,JTAG_TDI,USDHC2_CD_B,WDOG1_B,SAI1_MCLK,USDHC1_WP,GPIO1_IO03,USB_OTG1_OC,CCM_PMIC_RDY,,,,,ALT0 +GPIO_AD_B0_04,JTAG_TDO,FLEXCAN1_TX,USDHC1_WP,TMR2_TIMER0,ENET_MDIO,GPIO1_IO04,USB_OTG1_PWR,EWM_OUT_B,,,,,ALT0 +GPIO_AD_B0_05,JTAG_TRSTB,FLEXCAN1_RX,USDHC1_CD_B,TMR2_TIMER1,ENET_MDC,GPIO1_IO05,USB_OTG1_ID,ARM_NMI,,,,,ALT0 +GPIO_AD_B0_06,PIT_TRIGGER0,MQS_RIGHT,LPUART1_TXD,TMR2_TIMER2,FLEXPWM2_PWMA3,GPIO1_IO06,REF_32K_OUT,,,,,,ALT5 +GPIO_AD_B0_07,PIT_TRIGGER1,MQS_LEFT,LPUART1_RXD,TMR2_TIMER3,FLEXPWM2_PWMB3,GPIO1_IO07,REF_24M_OUT,,,,,,ALT5 +GPIO_AD_B0_08,ENET_TX_CLK,LPI2C3_SCL,LPUART1_CTS_B,KPP_COL0,ENET_REF_CLK,GPIO1_IO08,ARM_CM7_TXEV,,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_09,ENET_RX_DATA1,LPI2C3_SDA,LPUART1_RTS_B,KPP_ROW0,,GPIO1_IO09,ARM_CM7_RXEV,,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_10,ENET_RX_DATA0,LPSPI1_SCK,LPUART5_TXD,KPP_COL1,FLEXPWM2_PWMA2,GPIO1_IO10,ARM_TRACE_CLK,,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_11,ENET_RX_EN,LPSPI1_PCS0,LPUART5_RXD,KPP_ROW1,FLEXPWM2_PWMB2,GPIO1_IO11,ARM_TRACE_SWO,,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_12,ENET_RX_ER,LPSPI1_SDO,LPUART3_CTS_B,KPP_COL2,FLEXPWM2_PWMA1,GPIO1_IO12,ARM_TRACE0,SNVS_VIO_5_CTL,,,ADC1_IN0,,ALT5 +GPIO_AD_B0_13,ENET_TX_EN,LPSPI1_SDI,LPUART3_RTS_B,KPP_ROW2,FLEXPWM2_PWMB1,GPIO1_IO13,,SNVS_VIO_5_B,,,ADC2_IN0,,ALT5 +GPIO_AD_B0_14,ENET_TX_DATA0,FLEXCAN2_TX,LPUART3_TXD,KPP_COL3,FLEXPWM2_PWMA0,GPIO1_IO14,,WDOG1_ANY,,,"ADC1_IN1,ADC2_IN1","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B0_15,ENET_TX_DATA1,FLEXCAN2_RX,LPUART3_RXD,KPP_ROW3,FLEXPWM2_PWMB0,GPIO1_IO15,,,,,"ADC1_IN2,ADC2_IN2","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_00,SEMC_RDY,FLEXSPI_A_DATA3,FLEXCAN2_TX,SAI1_MCLK,FLEXIO1_D15,GPIO1_IO16,ENET_1588_EVENT2_OUT,KPP_COL4,,,,ACMP1_IN2,ALT5 +GPIO_AD_B1_01,SEMC_CSX0,FLEXSPI_A_SCLK,FLEXCAN2_RX,SAI1_TX_BCLK,FLEXIO1_D14,GPIO1_IO17,ENET_1588_EVENT2_IN,KPP_ROW4,,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B1_02,SEMC_CSX1,FLEXSPI_A_DATA0,LPSPI4_SCK,SAI1_TX_SYNC,FLEXIO1_D13,GPIO1_IO18,ENET_1588_EVENT3_OUT,KPP_COL5,,,ADC2_IN3,ACMP3_IN2,ALT5 +GPIO_AD_B1_03,SEMC_CSX2,FLEXSPI_A_DATA2,LPSPI4_PCS0,SAI1_TX_DATA0,FLEXIO1_D12,GPIO1_IO19,ENET_1588_EVENT3_IN,KPP_ROW5,,,ADC1_IN4,ACMP4_IN2,ALT5 +GPIO_AD_B1_04,SEMC_CSX3,FLEXSPI_A_DATA1,LPSPI4_SDO,SAI1_RX_SYNC,FLEXIO1_D11,GPIO1_IO20,LPSPI1_PCS1,KPP_COL6,,,ADC2_IN4,ACMP1_IN3,ALT5 +GPIO_AD_B1_05,USDHC1_WP,FLEXSPI_A_SS0_B,LPSPI4_SDI,SAI1_RX_DATA0,FLEXIO1_D10,GPIO1_IO21,LPSPI1_PCS2,KPP_ROW6,,,"ADC1_IN5,ADC2_IN5",ACMP2_IN3,ALT5 +GPIO_AD_B1_06,USDHC1_RESET_B,FLEXPWM1_PWMA0,LPUART2_CTS_B,SAI1_RX_BCLK,FLEXIO1_D09,GPIO1_IO22,LPSPI1_PCS3,KPP_COL7,,,"ADC1_IN6,ADC2_IN6",ACMP3_IN3,ALT5 +GPIO_AD_B1_07,USDHC1_VSELECT,FLEXPWM1_PWMB0,LPUART2_RTS_B,SAI1_TX_DATA1,FLEXIO1_D08,GPIO1_IO23,LPSPI3_PCS3,KPP_ROW7,,,"ADC1_IN7,ADC2_IN7",ACMP4_IN3,ALT5 +GPIO_AD_B1_08,LPI2C2_SCL,FLEXPWM1_PWMA1,LPUART2_TXD,SAI1_TX_DATA2,FLEXIO1_D07,GPIO1_IO24,LPSPI3_PCS2,XBAR_INOUT12,,,"ADC1_IN8,ADC2_IN8",ACMP1_IN5,ALT5 +GPIO_AD_B1_09,LPI2C2_SDA,FLEXPWM1_PWMB1,LPUART2_RXD,SAI1_TX_DATA3,FLEXIO1_D06,GPIO1_IO25,LPSPI3_PCS1,XBAR_INOUT13,,,"ADC1_IN9,ADC2_IN9",ACMP2_IN5,ALT5 +GPIO_AD_B1_10,USB_OTG1_PWR,FLEXPWM1_PWMA2,LPUART4_TXD,USDHC1_CD_B,FLEXIO1_D05,GPIO1_IO26,GPT2_CAPTURE1,,,,"ADC1_IN10,ADC2_IN10",ACMP3_IN5,ALT5 +GPIO_AD_B1_11,USB_OTG1_ID,FLEXPWM1_PWMB2,LPUART4_RXD,USDHC1_WP,FLEXIO1_D04,GPIO1_IO27,GPT2_COMPARE1,,,,"ADC1_IN11,ADC2_IN11",ACMP4_IN5,ALT5 +GPIO_AD_B1_12,USB_OTG1_OC,ACMP1_OUT,LPSPI3_SCK,USDHC2_CD_B,FLEXIO1_D03,GPIO1_IO28,FLEXPWM1_PWMA3,,,,"ADC1_IN12,ADC2_IN12","ACMP1_IN6,ACMP1_OUT",ALT5 +GPIO_AD_B1_13,LPI2C1_HREQ,ACMP2_OUT,LPSPI3_PCS0,USDHC2_WP,FLEXIO1_D02,GPIO1_IO29,FLEXPWM1_PWMB3,,,,"ADC1_IN13,ADC2_IN13","ACMP2_IN6,ACMP2_OUT",ALT5 +GPIO_AD_B1_14,LPI2C1_SCL,ACMP3_OUT,LPSPI3_SDO,ENET_1588_EVENT0_OUT,FLEXIO1_D01,GPIO1_IO30,,,,,"ADC1_IN14,ADC2_IN14","ACMP3_IN6,ACMP3_OUT",ALT5 +GPIO_AD_B1_15,LPI2C1_SDA,ACMP4_OUT,LPSPI3_SDI,ENET_1588_EVENT0_IN,FLEXIO1_D00,GPIO1_IO31,,,,,"ADC1_IN15,ADC2_IN15","ACMP4_IN6,ACMP4_OUT",ALT5 +GPIO_EMC_00,SEMC_DA00,TMR2_TIMER0,LPUART4_CTS_B,SPDIF_SR_CLK,LPSPI2_SCK,GPIO2_IO00,FLEXCAN1_TX,PIT_TRIGGER2,,,,,ALT5 +GPIO_EMC_01,SEMC_DA01,TMR2_TIMER1,LPUART4_RTS_B,SPDIF_OUT,LPSPI2_PCS0,GPIO2_IO01,FLEXCAN1_RX,PIT_TRIGGER3,,,,,ALT5 +GPIO_EMC_02,SEMC_DA02,TMR2_TIMER2,LPUART4_TXD,SPDIF_LOCK,LPSPI2_SDO,GPIO2_IO02,LPI2C1_SCL,,,,,,ALT5 +GPIO_EMC_03,SEMC_DA03,TMR2_TIMER3,LPUART4_RXD,SPDIF_EXT_CLK,LPSPI2_SDI,GPIO2_IO03,LPI2C1_SDA,,,,,,ALT5 +GPIO_EMC_04,SEMC_DA04,XBAR_INOUT04,SPDIF_OUT,SAI2_TX_BCLK,FLEXIO1_D16,GPIO2_IO04,USBPHY1_TSTO_PLL_CLK20DIV,,,,,,ALT5 +GPIO_EMC_05,SEMC_DA05,XBAR_INOUT05,SPDIF_IN,SAI2_TX_SYNC,FLEXIO1_D17,GPIO2_IO05,USBPHY1_TSTI_TX_HS_MODE,,,,,,ALT5 +GPIO_EMC_06,SEMC_DA06,XBAR_INOUT06,LPUART3_TXD,SAI2_TX_DATA,FLEXIO1_D18,GPIO2_IO06,USBPHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_07,SEMC_DA07,XBAR_INOUT07,LPUART3_RXD,SAI2_RX_SYNC,FLEXIO1_D19,GPIO2_IO07,USBPHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,XBAR_INOUT08,FLEXCAN2_TX,SAI2_RX_DATA,FLEXIO1_D20,GPIO2_IO08,USBPHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_09,SEMC_WE,XBAR_INOUT09,FLEXCAN2_RX,SAI2_RX_BCLK,FLEXIO1_D21,GPIO2_IO09,USBPHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_10,SEMC_CAS,XBAR_INOUT10,LPI2C4_SDA,SAI1_TX_SYNC,LPSPI2_SCK,GPIO2_IO10,FLEXPWM2_PWMX0,,,,,,ALT5 +GPIO_EMC_11,SEMC_RAS,XBAR_INOUT11,LPI2C4_SCL,SAI1_TX_BCLK,LPSPI2_PCS0,GPIO2_IO11,FLEXPWM2_PWMX1,,,,,,ALT5 +GPIO_EMC_12,SEMC_CS0,XBAR_INOUT12,LPUART6_TXD,SAI1_TX_DATA0,LPSPI2_SDO,GPIO2_IO12,FLEXPWM2_PWMX2,,,,,,ALT5 +GPIO_EMC_13,SEMC_BA0,XBAR_INOUT13,LPUART6_RXD,SAI1_RX_DATA0,LPSPI2_SDI,GPIO2_IO13,FLEXPWM2_PWMX3,CCM_PMIC_RDY,,,,,ALT5 +GPIO_EMC_14,SEMC_BA1,XBAR_INOUT14,LPUART6_CTS_B,SAI1_RX_BCLK,LPSPI2_PCS1,GPIO2_IO14,FLEXCAN1_TX,,,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR10,XBAR_INOUT15,LPUART6_RTS_B,SAI1_RX_SYNC,WDOG1_B,GPIO2_IO15,FLEXCAN1_RX,,,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR00,,MQS_RIGHT,SAI2_MCLK,,GPIO2_IO16,SRC_BOOT_MODE0,,,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR01,,MQS_LEFT,SAI3_MCLK,,GPIO2_IO17,SRC_BOOT_MODE1,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR02,XBAR_INOUT16,LPI2C2_SDA,SAI1_RX_SYNC,FLEXIO1_D22,GPIO2_IO18,SRC_BT_CFG0,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR03,XBAR_INOUT17,LPI2C2_SCL,SAI1_RX_BCLK,FLEXIO1_D23,GPIO2_IO19,SRC_BT_CFG1,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR04,FLEXPWM1_PWMA3,LPUART2_CTS_B,SAI1_MCLK,FLEXIO1_D24,GPIO2_IO20,SRC_BT_CFG2,,,,,,ALT5 +GPIO_EMC_21,SEMC_ADDR05,FLEXPWM1_PWMB3,LPUART2_RTS_B,SAI1_RX_DATA0,FLEXIO1_D25,GPIO2_IO21,SRC_BT_CFG3,,,,,,ALT5 +GPIO_EMC_22,SEMC_ADDR06,FLEXPWM1_PWMA2,LPUART2_TXD,SAI1_TX_DATA3,FLEXIO1_D26,GPIO2_IO22,SRC_BT_CFG4,,,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR07,FLEXPWM1_PWMB2,LPUART2_RXD,SAI1_TX_DATA2,FLEXIO1_D27,GPIO2_IO23,SRC_BT_CFG5,,,,,,ALT5 +GPIO_EMC_24,SEMC_ADDR08,FLEXPWM1_PWMA1,LPUART8_CTS_B,SAI1_TX_DATA1,FLEXIO1_D28,GPIO2_IO24,SRC_BT_CFG6,,,,,,ALT5 +GPIO_EMC_25,SEMC_ADDR09,FLEXPWM1_PWMB1,LPUART8_RTS_B,SAI1_TX_DATA0,FLEXIO1_D29,GPIO2_IO25,SRC_BT_CFG7,,,,,,ALT5 +GPIO_EMC_26,SEMC_ADDR11,FLEXPWM1_PWMA0,LPUART8_TXD,SAI1_TX_BCLK,FLEXIO1_D30,GPIO2_IO26,SRC_BT_CFG8,,,,,,ALT5 +GPIO_EMC_27,SEMC_ADDR12,FLEXPWM1_PWMB0,LPUART8_RXD,SAI1_TX_SYNC,FLEXIO1_D31,GPIO2_IO27,SRC_BT_CFG9,,,,,,ALT5 +GPIO_EMC_28,SEMC_DQS,FLEXPWM2_PWMA3,XBAR_INOUT18,SAI3_MCLK,EWM_OUT_B,GPIO2_IO28,GPT2_CAPTURE2,FLEXPWM1_PWMX0,,,,,ALT5 +GPIO_EMC_29,SEMC_CKE,FLEXPWM2_PWMB3,XBAR_INOUT19,SAI3_RX_BCLK,WDOG2_RST_B_DEB,GPIO2_IO29,GPT2_COMPARE2,FLEXPWM1_PWMX1,,,,,ALT5 +GPIO_EMC_30,SEMC_CLK,FLEXPWM2_PWMA2,LPUART4_CTS_B,SAI3_RX_SYNC,WDOG1_RST_B_DEB,GPIO2_IO30,GPT2_COMPARE3,FLEXPWM1_PWMX2,,,,,ALT5 +GPIO_EMC_31,SEMC_DM1,FLEXPWM2_PWMB2,LPUART4_RTS_B,SAI3_RX_DATA,WDOG2_B,GPIO2_IO31,GPT2_CLK,FLEXPWM1_PWMX3,,,,,ALT5 +GPIO_EMC_32,SEMC_DA08,TMR1_TIMER0,LPUART4_TXD,SAI3_TX_DATA,LPSPI4_SCK,GPIO3_IO00,USBPHY1_TSTO_RX_FS_RXD,REF_24M_OUT,,,,,ALT5 +GPIO_EMC_33,SEMC_DA09,TMR1_TIMER1,LPUART4_RXD,SAI3_TX_BCLK,LPSPI4_PCS0,GPIO3_IO01,USBPHY1_TSTI_TX_DP,SRC_TESTER_ACK,,,,,ALT5 +GPIO_EMC_34,SEMC_DA10,TMR1_TIMER2,LPUART7_TXD,SAI3_TX_SYNC,LPSPI4_SDO,GPIO3_IO02,ENET_CRS,,,,,,ALT5 +GPIO_EMC_35,SEMC_DA11,TMR1_TIMER3,LPUART7_RXD,USDHC2_WP,LPSPI4_SDI,GPIO3_IO03,ENET_COL,,,,,,ALT5 +GPIO_EMC_36,SEMC_DA12,FLEXPWM2_PWMA1,LPUART5_CTS_B,CCM_PMIC_RDY,LPSPI4_PCS1,GPIO3_IO04,ENET_RX_CLK,USDHC1_WP,,,,,ALT5 +GPIO_EMC_37,SEMC_DA13,FLEXPWM2_PWMB1,LPUART5_RTS_B,MQS_RIGHT,LPSPI4_PCS2,GPIO3_IO05,ENET_RX_DATA3,USDHC1_VSELECT,,,,,ALT5 +GPIO_EMC_38,SEMC_DA14,FLEXPWM2_PWMA0,LPUART5_TXD,MQS_LEFT,LPSPI4_PCS3,GPIO3_IO06,ENET_RX_DATA2,USDHC1_CD_B,,,,,ALT5 +GPIO_EMC_39,SEMC_DA15,FLEXPWM2_PWMB0,LPUART5_RXD,USB_OTG1_OC,WDOG1_B,GPIO3_IO07,ENET_TX_ER,GPT1_CLK,,,,,ALT5 +GPIO_EMC_40,SEMC_CSX0,XBAR_INOUT18,SPDIF_OUT,USB_OTG1_ID,ENET_MDIO,GPIO3_IO08,ENET_TX_DATA3,GPT1_COMPARE3,,,,,ALT5 +GPIO_EMC_41,SEMC_RDY,XBAR_INOUT19,SPDIF_IN,USB_OTG1_PWR,ENET_MDC,GPIO3_IO09,ENET_TX_DATA2,GPT1_COMPARE2,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_DATA2,TMR1_TIMER0,SAI1_MCLK,SAI2_MCLK,LPI2C3_SCL,GPIO3_IO13,FLEXSPI_A_SS1_B,XBAR_INOUT14,,,,,ALT5 +GPIO_SD_B0_01,USDHC1_DATA3,TMR1_TIMER1,REF_24M_OUT,SAI2_RX_SYNC,LPI2C3_SDA,GPIO3_IO14,FLEXSPI_B_SS1_B,XBAR_INOUT15,,,,,ALT5 +GPIO_SD_B0_02,USDHC1_CMD,TMR1_TIMER2,LPUART7_CTS_B,SAI2_RX_BCLK,LPSPI1_SCK,GPIO3_IO15,ENET_MDIO,XBAR_INOUT16,,,,,ALT5 +GPIO_SD_B0_03,USDHC1_CLK,TMR1_TIMER3,LPUART7_RTS_B,SAI2_RX_DATA,LPSPI1_PCS0,GPIO3_IO16,ENET_MDC,,,,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA0,FLEXCAN2_TX,LPUART7_TXD,SAI2_TX_DATA,LPSPI1_SDO,GPIO3_IO17,FLEXSPI_B_SS0_B,,,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA1,FLEXCAN2_RX,LPUART7_RXD,SAI2_TX_BCLK,LPSPI1_SDI,GPIO3_IO18,FLEXSPI_B_DQS,,,,,,ALT5 +GPIO_SD_B0_06,USDHC1_CD_B,USDHC1_RESET_B,REF_32K_OUT,SAI2_TX_SYNC,WDOG1_B,GPIO3_IO19,XBAR_INOUT17,,,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA2,FLEXSPI_B_DATA3,LPUART6_TXD,XBAR_INOUT10,FLEXCAN1_TX,GPIO3_IO20,,,,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA3,FLEXSPI_B_SCLK,LPUART6_RXD,FLEXSPI_A_SS1_B,FLEXCAN1_RX,GPIO3_IO21,,,,,,,ALT5 +GPIO_SD_B1_02,USDHC2_CMD,FLEXSPI_B_DATA0,LPUART8_TXD,LPI2C4_SCL,ENET_1588_EVENT1_OUT,GPIO3_IO22,CCM_CLKO1,,,,,,ALT5 +GPIO_SD_B1_03,USDHC2_CLK,FLEXSPI_B_DATA2,LPUART8_RXD,LPI2C4_SDA,ENET_1588_EVENT1_IN,GPIO3_IO23,CCM_CLKO2,,,,,,ALT5 +GPIO_SD_B1_04,USDHC2_DATA0,FLEXSPI_B_DATA1,ENET_TX_CLK,ENET_REF_CLK,EWM_OUT_B,GPIO3_IO24,CCM_WAIT,,,,,,ALT5 +GPIO_SD_B1_05,USDHC2_DATA1,FLEXSPI_A_DQS,ENET_RX_DATA1,SAI3_MCLK,FLEXSPI_B_SS0_B,GPIO3_IO25,CCM_PMIC_RDY,,,,,,ALT5 +GPIO_SD_B1_06,USDHC2_CD_B,FLEXSPI_A_DATA3,ENET_RX_DATA0,SAI3_TX_BCLK,LPSPI2_PCS0,GPIO3_IO26,CCM_STOP,,,,,,ALT5 +GPIO_SD_B1_07,USDHC2_RESET_B,FLEXSPI_A_SCLK,ENET_RX_EN,SAI3_TX_SYNC,LPSPI2_SCK,GPIO3_IO27,,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,ENET_RX_ER,SAI3_TX_DATA,LPSPI2_SDO,GPIO3_IO28,,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA2,ENET_TX_EN,SAI3_RX_BCLK,LPSPI2_SDI,GPIO3_IO29,CCM_REF_EN_B,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA1,ENET_TX_DATA0,SAI3_RX_SYNC,LPSPI2_PCS2,GPIO3_IO30,SRC_SYSTEM_RESET,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_SS0_B,ENET_TX_DATA1,SAI3_RX_DATA,LPSPI2_PCS3,GPIO3_IO31,SRC_EARLY_RESET,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index 5a733bbd97bb..2337496d2a3b 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (64 * 1024 * 1024) // MIMXRT1050_EVK has 1 user LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_09) +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.c deleted file mode 100644 index d5da9c6f9927..000000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "pin.h" - -static pin_af_obj_t GPIO_AD_B0_09_af[] = { - PIN_AF(GPIO1_IO09, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_09 = PIN(GPIO_AD_B0_09, GPIO1, 9, GPIO_AD_B0_09_af); diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv new file mode 100644 index 000000000000..afd63d4f97fe --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv @@ -0,0 +1,51 @@ +D0,GPIO_AD_B1_07 +D1,GPIO_AD_B1_06 +D2,GPIO_AD_B0_11 +D3,GPIO_AD_B1_08 +D4,GPIO_AD_B0_09 +D5,GPIO_AD_B0_10 +D6,GPIO_AD_B1_02 +D7,GPIO_AD_B1_03 +D8,GPIO_AD_B0_03 +D9,GPIO_AD_B0_02 +D10,GPIO_SD_B0_01 +D11,GPIO_SD_B0_02 +D12,GPIO_SD_B0_03 +D13,GPIO_SD_B0_00 +D14,GPIO_AD_B1_01 +D15,GPIO_AD_B1_00 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_04 +A3,GPIO_AD_B1_05 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +RX,GPIO_AD_B1_07 +TX,GPIO_AD_B1_06 +SCL,GPIO_AD_B1_00 +SDA,GPIO_AD_B1_01 +SCK,GPIO_SD_B0_00 +SDI,GPIO_SD_B0_03 +SDO,GPIO_SD_B0_02 +CS,GPIO_SD_B0_01 +LED_GREEN,GPIO_AD_B0_09 +GPIO_AD_B1_07,GPIO_AD_B1_07 +GPIO_AD_B1_06,GPIO_AD_B1_06 +GPIO_AD_B0_11,GPIO_AD_B0_11 +GPIO_AD_B1_08,GPIO_AD_B1_08 +GPIO_AD_B0_09,GPIO_AD_B0_09 +GPIO_AD_B0_10,GPIO_AD_B0_10 +GPIO_AD_B1_02,GPIO_AD_B1_02 +GPIO_AD_B1_03,GPIO_AD_B1_03 +GPIO_AD_B0_03,GPIO_AD_B0_03 +GPIO_AD_B0_02,GPIO_AD_B0_02 +GPIO_SD_B0_01,GPIO_SD_B0_01 +GPIO_SD_B0_02,GPIO_SD_B0_02 +GPIO_SD_B0_03,GPIO_SD_B0_03 +GPIO_SD_B0_00,GPIO_SD_B0_00 +GPIO_AD_B1_01,GPIO_AD_B1_01 +GPIO_AD_B1_00,GPIO_AD_B1_00 +GPIO_AD_B1_10,GPIO_AD_B1_10 +GPIO_AD_B1_11,GPIO_AD_B1_11 +GPIO_AD_B1_04,GPIO_AD_B1_04 +GPIO_AD_B1_05,GPIO_AD_B1_05 diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.h deleted file mode 100644 index baef51c6c861..000000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_09; diff --git a/ports/mimxrt/boards/MIMXRT1052_af.csv b/ports/mimxrt/boards/MIMXRT1052_af.csv new file mode 100644 index 000000000000..754bf4ab7bf0 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1052_af.csv @@ -0,0 +1,125 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,FLEXPWM2_PWM3_A,XBAR_INOUT14,REF_CLK_32K,USB_OTG2_ID,LPI2C1_SCLS,GPIO1_IO00,USDHC1_RESET_B,LPSPI3_SCK,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_01,FLEXPWM2_PWM3_B,XBAR_INOUT15,REF_CLK_24M,USB_OTG1_ID,LPI2C1_SDAS,GPIO1_IO01,EWM_OUT_B,LPSPI3_SOUT,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_02,FLEXCAN2_TX,XBAR_INOUT16,LPUART6_TXD,USB_OTG1_PWR,FLEXPWM1_PWM0_X,GPIO1_IO02,LPI2C1_HREQ,LPSPI3_SIN,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_03,FLEXCAN2_RX,XBAR_INOUT17,LPUART6_RXD,USB_OTG1_OC,FLEXPWM1_PWM1_X,GPIO1_IO03,REF_CLK_24M,LPSPI3_PCS0,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_04,SRC_BOOT_MODE0,MQS_RIGHT,ENET_TX_DATA3,SAI2_TX_SYNC,CSI_DATA09,GPIO1_IO04,PIT_TRIGGER0,LPSPI3_PCS1,,,,,ALT0 +GPIO_AD_B0_05,SRC_BOOT_MODE1,MQS_LEFT,ENET_TX_DATA2,SAI2_TX_BCLK,CSI_DATA08,GPIO1_IO05,XBAR_INOUT17,LPSPI3_PCS2,,,,,ALT0 +GPIO_AD_B0_06,"JTAG_TMS,SWD_DIO",GPT2_COMPARE1,ENET_RX_CLK,SAI2_RX_BCLK,CSI_DATA07,GPIO1_IO06,XBAR_INOUT18,LPSPI3_PCS3,,,,,ALT0 +GPIO_AD_B0_07,"JTAG_TCK,SWD_CLK",GPT2_COMPARE2,ENET_TX_ER,SAI2_RX_SYNC,CSI_DATA06,GPIO1_IO07,XBAR_INOUT19,ENET_1588_EVENT3_OUT,,,,,ALT0 +GPIO_AD_B0_08,JTAG_MOD,GPT2_COMPARE3,ENET_RX_DATA3,SAI2_RX_DATA,CSI_DATA05,GPIO1_IO08,XBAR_INOUT20,ENET_1588_EVENT3_IN,,,,,ALT0 +GPIO_AD_B0_09,JTAG_TDI,FLEXPWM2_PWM3_A,ENET_RX_DATA2,SAI2_TX_DATA,CSI_DATA04,GPIO1_IO09,XBAR_INOUT21,GPT2_CLK,,,,,ALT0 +GPIO_AD_B0_10,JTAG_TDO,FLEXPWM1_PWM3_A,ENET_CRS,SAI2_MCLK,CSI_DATA03,GPIO1_IO10,XBAR_INOUT22,ENET_1588_EVENT0_OUT,,,,,ALT0 +GPIO_AD_B0_11,JTAG_TRSTB,FLEXPWM1_PWM3_B,ENET_COL,WDOG1_B,CSI_DATA02,GPIO1_IO11,XBAR_INOUT23,ENET_1588_EVENT0_IN,,,,,ALT0 +GPIO_AD_B0_12,LPI2C4_SCL,CCM_PMIC_READY,LPUART1_TXD,WDOG2_B,FLEXPWM1_PWM2_X,GPIO1_IO12,ENET_1588_EVENT1_OUT,,,,ADC1_IN1,,ALT5 +GPIO_AD_B0_13,LPI2C4_SDA,GPT1_CLK,LPUART1_RXD,EWM_OUT_B,FLEXPWM1_PWM3_X,GPIO1_IO13,ENET_1588_EVENT1_IN,REF_CLK_24M,,,ADC1_IN2,ACMP1_IN2,ALT5 +GPIO_AD_B0_14,USB_OTG2_OC,XBAR_INOUT24,LPUART1_CTS_B,ENET_1588_EVENT0_OUT,CSI_VSYNC,GPIO1_IO14,FLEXCAN2_TX,WDOG1_ANY,,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B0_15,USB_OTG2_PWR,XBAR_INOUT25,LPUART1_RTS_B,ENET_1588_EVENT0_IN,CSI_HSYNC,GPIO1_IO15,FLEXCAN2_RX,WDOG1_RST_B_DEB,,,ADC1_IN4,ACMP3_IN2,ALT5 +GPIO_AD_B1_00,USB_OTG2_ID,TMR3_TIMER0,LPUART2_CTS_B,LPI2C1_SCL,WDOG1_B,GPIO1_IO16,USDHC1_WP,KPP_ROW7,,,"ADC1_IN5,ADC2_IN5",ACMP4_IN2,ALT5 +GPIO_AD_B1_01,USB_OTG1_PWR,TMR3_TIMER1,LPUART2_RTS_B,LPI2C1_SDA,CCM_PMIC_READY,GPIO1_IO17,USDHC1_VSELECT,KPP_COL7,,,"ADC1_IN6,ADC2_IN6","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B1_02,USB_OTG1_ID,TMR3_TIMER2,LPUART2_TXD,SPDIF_OUT,ENET_1588_EVENT2_OUT,GPIO1_IO18,USDHC1_CD_B,KPP_ROW6,,,"ADC1_IN7,ADC2_IN7",ACMP1_IN3,ALT5 +GPIO_AD_B1_03,USB_OTG1_OC,TMR3_TIMER3,LPUART2_RXD,SPDIF_IN,ENET_1588_EVENT2_IN,GPIO1_IO19,USDHC2_CD_B,KPP_COL6,,,"ADC1_IN8,ADC2_IN8",ACMP2_IN3,ALT5 +GPIO_AD_B1_04,FLEXSPI_B_DATA3,ENET_MDC,LPUART3_CTS_B,SPDIF_SR_CLK,CSI_PIXCLK,GPIO1_IO20,USDHC2_DATA0,KPP_ROW5,,,"ADC1_IN9,ADC2_IN9",ACMP3_IN3,ALT5 +GPIO_AD_B1_05,FLEXSPI_B_DATA2,ENET_MDIO,LPUART3_RTS_B,SPDIF_OUT,CSI_MCLK,GPIO1_IO21,USDHC2_DATA1,KPP_COL5,,,"ADC1_IN10,ADC2_IN10",ACMP4_IN3,ALT5 +GPIO_AD_B1_06,FLEXSPI_B_DATA1,LPI2C3_SDA,LPUART3_TXD,SPDIF_LOCK,CSI_VSYNC,GPIO1_IO22,USDHC2_DATA2,KPP_ROW4,,,"ADC1_IN11,ADC2_IN11","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_07,FLEXSPI_B_DATA0,LPI2C3_SCL,LPUART3_RXD,SPDIF_EXT_CLK,CSI_HSYNC,GPIO1_IO23,USDHC2_DATA3,KPP_COL4,,,"ADC1_IN12,ADC2_IN12",ACMP1_IN5,ALT5 +GPIO_AD_B1_08,FLEXSPI_A_SS1_B,FLEXPWM4_PWM0_A,FLEXCAN1_TX,CCM_PMIC_READY,CSI_DATA09,GPIO1_IO24,USDHC2_CMD,KPP_ROW3,,,"ADC1_IN13,ADC2_IN13",ACMP2_IN5,ALT5 +GPIO_AD_B1_09,FLEXSPI_A_DQS,FLEXPWM4_PWM1_A,FLEXCAN1_RX,SAI1_MCLK,CSI_DATA08,GPIO1_IO25,USDHC2_CLK,KPP_COL3,,,"ADC1_IN14,ADC2_IN14",ACMP3_IN5,ALT5 +GPIO_AD_B1_10,FLEXSPI_A_DATA3,WDOG1_B,LPUART8_TXD,SAI1_RX_SYNC,CSI_DATA07,GPIO1_IO26,USDHC2_WP,KPP_ROW2,,,"ADC1_IN15,ADC2_IN15",ACMP4_IN5,ALT5 +GPIO_AD_B1_11,FLEXSPI_A_DATA2,EWM_OUT_B,LPUART8_RXD,SAI1_RX_BCLK,CSI_DATA06,GPIO1_IO27,USDHC2_RESET_B,KPP_COL2,,,"ADC1_IN0,ADC2_IN0",ACMP1_IN6,ALT5 +GPIO_AD_B1_12,FLEXSPI_A_DATA1,ACMP1_OUT,LPSPI3_PCS0,SAI1_RX_DATA0,CSI_DATA05,GPIO1_IO28,USDHC2_DATA4,KPP_ROW1,,,ADC2_IN1,"ACMP1_OUT,ACMP2_IN6",ALT5 +GPIO_AD_B1_13,FLEXSPI_A_DATA0,ACMP2_OUT,LPSPI3_SIN,SAI1_TX_DATA0,CSI_DATA04,GPIO1_IO29,USDHC2_DATA5,KPP_COL1,,,ADC2_IN2,"ACMP2_OUT,ACMP3_IN6",ALT5 +GPIO_AD_B1_14,FLEXSPI_A_SCLK,ACMP3_OUT,LPSPI3_SOUT,SAI1_TX_BCLK,CSI_DATA03,GPIO1_IO30,USDHC2_DATA6,KPP_ROW0,,,ADC2_IN3,"ACMP3_OUT,ACMP4_IN6",ALT5 +GPIO_AD_B1_15,FLEXSPI_A_SS0_B,ACMP4_OUT,LPSPI3_SCK,SAI1_TX_SYNC,CSI_DATA02,GPIO1_IO31,USDHC2_DATA7,KPP_COL0,,,ADC2_IN4,ACMP4_OUT,ALT5 +GPIO_B0_00,LCD_CLK,TMR1_TIMER0,MQS_RIGHT,LPSPI4_PCS0,FLEXIO2_D00,GPIO2_IO00,SEMC_CSX1,,,,,,ALT5 +GPIO_B0_01,LCD_ENABLE,TMR1_TIMER1,MQS_LEFT,LPSPI4_SIN,FLEXIO2_D01,GPIO2_IO01,SEMC_CSX2,,,,,,ALT5 +GPIO_B0_02,LCD_HSYNC,TMR1_TIMER2,FLEXCAN1_TX,LPSPI4_SOUT,FLEXIO2_D02,GPIO2_IO02,SEMC_CSX3,,,,,,ALT5 +GPIO_B0_03,LCD_VSYNC,TMR2_TIMER0,FLEXCAN1_RX,LPSPI4_SCK,FLEXIO2_D03,GPIO2_IO03,WDOG2_RST_B_DEB,,,,,,ALT5 +GPIO_B0_04,LCD_DATA00,TMR2_TIMER1,LPI2C2_SCL,ARM_TRACE0,FLEXIO2_D04,GPIO2_IO04,SRC_BT_CFG00,,,,,,ALT5 +GPIO_B0_05,LCD_DATA01,TMR2_TIMER2,LPI2C2_SDA,ARM_TRACE1,FLEXIO2_D05,GPIO2_IO05,SRC_BT_CFG01,,,,,,ALT5 +GPIO_B0_06,LCD_DATA02,TMR3_TIMER0,FLEXPWM2_PWM0_A,ARM_TRACE2,FLEXIO2_D06,GPIO2_IO06,SRC_BT_CFG02,,,,,,ALT5 +GPIO_B0_07,LCD_DATA03,TMR3_TIMER1,FLEXPWM2_PWM0_B,ARM_TRACE3,FLEXIO2_D07,GPIO2_IO07,SRC_BT_CFG03,,,,,,ALT5 +GPIO_B0_08,LCD_DATA04,TMR3_TIMER2,FLEXPWM2_PWM1_A,LPUART3_TXD,FLEXIO2_D08,GPIO2_IO08,SRC_BT_CFG04,,,,,,ALT5 +GPIO_B0_09,LCD_DATA05,TMR4_TIMER0,FLEXPWM2_PWM1_B,LPUART3_RXD,FLEXIO2_D09,GPIO2_IO09,SRC_BT_CFG05,,,,,,ALT5 +GPIO_B0_10,LCD_DATA06,TMR4_TIMER1,FLEXPWM2_PWM2_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",FLEXIO2_D10,GPIO2_IO10,SRC_BT_CFG06,,,,,,ALT5 +GPIO_B0_11,LCD_DATA07,TMR4_TIMER2,FLEXPWM2_PWM2_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",FLEXIO2_D11,GPIO2_IO11,SRC_BT_CFG07,,,,,,ALT5 +GPIO_B0_12,LCD_DATA08,XBAR_INOUT10,ARM_TRACE_CLK,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXIO2_D12,GPIO2_IO12,SRC_BT_CFG08,,,,,,ALT5 +GPIO_B0_13,LCD_DATA09,XBAR_INOUT11,ARM_TRACE_SWO,SAI1_MCLK,FLEXIO2_D13,GPIO2_IO13,SRC_BT_CFG09,,,,,,ALT5 +GPIO_B0_14,LCD_DATA10,XBAR_INOUT12,ARM_CM7_EVENT0,SAI1_RX_SYNC,FLEXIO2_D14,GPIO2_IO14,SRC_BT_CFG10,,,,,,ALT5 +GPIO_B0_15,LCD_DATA11,XBAR_INOUT13,ARM_CM7_EVENT1,SAI1_RX_BCLK,FLEXIO2_D15,GPIO2_IO15,SRC_BT_CFG11,,,,,,ALT5 +GPIO_B1_00,LCD_DATA12,XBAR_INOUT14,LPUART4_TXD,SAI1_RX_DATA0,FLEXIO2_D16,GPIO2_IO16,FLEXPWM1_PWM3_A,,,,,,ALT5 +GPIO_B1_01,LCD_DATA13,XBAR_INOUT15,LPUART4_RXD,SAI1_TX_DATA0,FLEXIO2_D17,GPIO2_IO17,FLEXPWM1_PWM3_B,,,,,,ALT5 +GPIO_B1_02,LCD_DATA14,XBAR_INOUT16,LPSPI4_PCS2,SAI1_TX_BCLK,FLEXIO2_D18,GPIO2_IO18,FLEXPWM2_PWM3_A,,,,,,ALT5 +GPIO_B1_03,LCD_DATA15,XBAR_INOUT17,LPSPI4_PCS1,SAI1_TX_SYNC,FLEXIO2_D19,GPIO2_IO19,FLEXPWM2_PWM3_B,,,,,,ALT5 +GPIO_B1_04,LCD_DATA16,LPSPI4_PCS0,CSI_DATA15,ENET_RX_DATA0,FLEXIO2_D20,GPIO2_IO20,,,,,,,ALT5 +GPIO_B1_05,LCD_DATA17,LPSPI4_SIN,CSI_DATA14,ENET_RX_DATA1,FLEXIO2_D21,GPIO2_IO21,,,,,,,ALT5 +GPIO_B1_06,LCD_DATA18,LPSPI4_SOUT,CSI_DATA13,ENET_RX_EN,FLEXIO2_D22,GPIO2_IO22,,,,,,,ALT5 +GPIO_B1_07,LCD_DATA19,LPSPI4_SCK,CSI_DATA12,ENET_TX_DATA0,FLEXIO2_D23,GPIO2_IO23,,,,,,,ALT5 +GPIO_B1_08,LCD_DATA20,TMR1_TIMER3,CSI_DATA11,ENET_TX_DATA1,FLEXIO2_D24,GPIO2_IO24,FLEXCAN2_TX,,,,,,ALT5 +GPIO_B1_09,LCD_DATA21,TMR2_TIMER3,CSI_DATA10,ENET_TX_EN,FLEXIO2_D25,GPIO2_IO25,FLEXCAN2_RX,,,,,,ALT5 +GPIO_B1_10,LCD_DATA22,TMR3_TIMER3,CSI_DATA00,ENET_TX_CLK,FLEXIO2_D26,GPIO2_IO26,ENET_REF_CLK,,,,,,ALT5 +GPIO_B1_11,LCD_DATA23,TMR4_TIMER3,CSI_DATA01,ENET_RX_ER,FLEXIO2_D27,GPIO2_IO27,LPSPI4_PCS3,,,,,,ALT5 +GPIO_B1_12,,LPUART5_TXD,CSI_PIXCLK,ENET_1588_EVENT0_IN,FLEXIO2_D28,GPIO2_IO28,USDHC1_CD_B,,,,,,ALT5 +GPIO_B1_13,WDOG1_B,LPUART5_RXD,CSI_VSYNC,ENET_1588_EVENT0_OUT,FLEXIO2_D29,GPIO2_IO29,USDHC1_WP,,,,,,ALT5 +GPIO_B1_14,ENET_MDC,FLEXPWM4_PWM2_A,CSI_HSYNC,XBAR_INOUT02,FLEXIO2_D30,GPIO2_IO30,USDHC1_VSELECT,,,,,,ALT5 +GPIO_B1_15,ENET_MDIO,FLEXPWM4_PWM3_A,CSI_MCLK,XBAR_INOUT03,FLEXIO2_D31,GPIO2_IO31,USDHC1_RESET_B,,,,,,ALT5 +GPIO_EMC_00,SEMC_DATA00,FLEXPWM4_PWM0_A,LPSPI2_SCK,XBAR_INOUT02,FLEXIO1_D00,GPIO4_IO0,USB_PHY1_TSTI_TX_LS_MODE,,,,,,ALT5 +GPIO_EMC_01,SEMC_DATA01,FLEXPWM4_PWM0_B,LPSPI2_PCS0,XBAR_INOUT03,FLEXIO1_D01,GPIO4_IO1,USB_PHY1_TSTI_TX_HS_MODE,,,,,,ALT5 +GPIO_EMC_02,SEMC_DATA02,FLEXPWM4_PWM1_A,LPSPI2_SOUT,XBAR_INOUT04,FLEXIO1_D02,GPIO4_IO2,USB_PHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_03,SEMC_DATA03,FLEXPWM4_PWM1_B,LPSPI2_SIN,XBAR_INOUT05,FLEXIO1_D03,GPIO4_IO3,USB_PHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_04,SEMC_DATA04,FLEXPWM4_PWM2_A,SAI2_TX_DATA,XBAR_INOUT06,FLEXIO1_D04,GPIO4_IO4,USB_PHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_05,SEMC_DATA05,FLEXPWM4_PWM2_B,SAI2_TX_SYNC,XBAR_INOUT07,FLEXIO1_D05,GPIO4_IO5,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_06,SEMC_DATA06,FLEXPWM2_PWM0_A,SAI2_TX_BCLK,XBAR_INOUT08,FLEXIO1_D06,GPIO4_IO6,USB_PHY2_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_07,SEMC_DATA07,FLEXPWM2_PWM0_B,SAI2_MCLK,XBAR_INOUT09,FLEXIO1_D07,GPIO4_IO7,USB_PHY1_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,FLEXPWM2_PWM1_A,SAI2_RX_DATA,XBAR_INOUT17,FLEXIO1_D08,GPIO4_IO8,USB_PHY1_TSTI_TX_DP,,,,,,ALT5 +GPIO_EMC_09,SEMC_ADDR00,FLEXPWM2_PWM1_B,SAI2_RX_SYNC,FLEXCAN2_TX,FLEXIO1_D09,GPIO4_IO9,USB_PHY1_TSTI_TX_EN,,,,,,ALT5 +GPIO_EMC_10,SEMC_ADDR01,FLEXPWM2_PWM2_A,SAI2_RX_BCLK,FLEXCAN2_RX,FLEXIO1_D10,GPIO4_IO10,USB_PHY1_TSTI_TX_HIZ,,,,,,ALT5 +GPIO_EMC_11,SEMC_ADDR02,FLEXPWM2_PWM2_B,LPI2C4_SDA,USDHC2_RESET_B,FLEXIO1_D11,GPIO4_IO11,USB_PHY2_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_12,SEMC_ADDR03,XBAR_INOUT24,LPI2C4_SCL,USDHC1_WP,FLEXPWM1_PWM3_A,GPIO4_IO12,USB_PHY1_TSTO_PLL_CLK20DIV,,,,,,ALT5 +GPIO_EMC_13,SEMC_ADDR04,XBAR_INOUT25,LPUART3_TXD,MQS_RIGHT,FLEXPWM1_PWM3_B,GPIO4_IO13,USB_PHY2_TSTO_PLL_CLK20DIV,,,,,,ALT5 +GPIO_EMC_14,SEMC_ADDR05,XBAR_INOUT19,LPUART3_RXD,MQS_LEFT,LPSPI2_PCS1,GPIO4_IO14,USB_PHY2_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR06,XBAR_INOUT20,LPUART3_CTS_B,SPDIF_OUT,TMR3_TIMER0,GPIO4_IO15,USB_PHY2_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR07,XBAR_INOUT21,LPUART3_RTS_B,SPDIF_IN,TMR3_TIMER1,GPIO4_IO16,,,,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR08,FLEXPWM4_PWM3_A,LPUART4_CTS_B,FLEXCAN1_TX,TMR3_TIMER2,GPIO4_IO17,,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR09,FLEXPWM4_PWM3_B,LPUART4_RTS_B,FLEXCAN1_RX,TMR3_TIMER3,GPIO4_IO18,SNVS_VIO_5_CTL,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR11,FLEXPWM2_PWM3_A,LPUART4_TXD,ENET_RX_DATA1,TMR2_TIMER0,GPIO4_IO19,SNVS_VIO_5_B,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR12,FLEXPWM2_PWM3_B,LPUART4_RXD,ENET_RX_DATA0,TMR2_TIMER1,GPIO4_IO20,,,,,,,ALT5 +GPIO_EMC_21,SEMC_BA0,FLEXPWM3_PWM3_A,LPI2C3_SDA,ENET_TX_DATA1,TMR2_TIMER2,GPIO4_IO21,,,,,,,ALT5 +GPIO_EMC_22,SEMC_BA1,FLEXPWM3_PWM3_B,LPI2C3_SCL,ENET_TX_DATA0,TMR2_TIMER3,GPIO4_IO22,,,,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR10,FLEXPWM1_PWM0_A,LPUART5_TXD,ENET_RX_EN,GPT1_CAPTURE2,GPIO4_IO23,,,,,,,ALT5 +GPIO_EMC_24,SEMC_CAS,FLEXPWM1_PWM0_B,LPUART5_RXD,ENET_TX_EN,GPT1_CAPTURE1,GPIO4_IO24,,,,,,,ALT5 +GPIO_EMC_25,SEMC_RAS,FLEXPWM1_PWM1_A,LPUART6_TXD,ENET_TX_CLK,ENET_REF_CLK,GPIO4_IO25,,,,,,,ALT5 +GPIO_EMC_26,SEMC_CLK,FLEXPWM1_PWM1_B,LPUART6_RXD,ENET_RX_ER,FLEXIO1_D12,GPIO4_IO26,,,,,,,ALT5 +GPIO_EMC_27,SEMC_CKE,FLEXPWM1_PWM2_A,LPUART5_RTS_B,LPSPI1_SCK,FLEXIO1_D13,GPIO4_IO27,,,,,,,ALT5 +GPIO_EMC_28,SEMC_WE,FLEXPWM1_PWM2_B,LPUART5_CTS_B,LPSPI1_SOUT,FLEXIO1_D14,GPIO4_IO28,,,,,,,ALT5 +GPIO_EMC_29,SEMC_CS0,FLEXPWM3_PWM0_A,LPUART6_RTS_B,LPSPI1_SIN,FLEXIO1_D15,GPIO4_IO29,,,,,,,ALT5 +GPIO_EMC_30,SEMC_DATA08,FLEXPWM3_PWM0_B,LPUART6_CTS_B,LPSPI1_PCS0,CSI_DATA23,GPIO4_IO30,,,,,,,ALT5 +GPIO_EMC_31,SEMC_DATA09,FLEXPWM3_PWM1_A,LPUART7_TXD,LPSPI1_PCS1,CSI_DATA22,GPIO4_IO31,,,,,,,ALT5 +GPIO_EMC_32,SEMC_DATA10,FLEXPWM3_PWM1_B,LPUART7_RXD,CCM_PMIC_READY,CSI_DATA21,GPIO3_IO18,,,,,,,ALT5 +GPIO_EMC_33,SEMC_DATA11,FLEXPWM3_PWM2_A,USDHC1_RESET_B,SAI3_RX_DATA,CSI_DATA20,GPIO3_IO19,,,,,,,ALT5 +GPIO_EMC_34,SEMC_DATA12,FLEXPWM3_PWM2_B,USDHC1_VSELECT,SAI3_RX_SYNC,CSI_DATA19,GPIO3_IO20,,,,,,,ALT5 +GPIO_EMC_35,SEMC_DATA13,XBAR_INOUT18,GPT1_COMPARE1,SAI3_RX_BCLK,CSI_DATA18,GPIO3_IO21,USDHC1_CD_B,,,,,,ALT5 +GPIO_EMC_36,SEMC_DATA14,XBAR_INOUT22,GPT1_COMPARE2,SAI3_TX_DATA,CSI_DATA17,GPIO3_IO22,USDHC1_WP,,,,,,ALT5 +GPIO_EMC_37,SEMC_DATA15,XBAR_INOUT23,GPT1_COMPARE3,SAI3_MCLK,CSI_DATA16,GPIO3_IO23,USDHC2_WP,,,,,,ALT5 +GPIO_EMC_38,SEMC_DM1,FLEXPWM1_PWM3_A,LPUART8_TXD,SAI3_TX_BCLK,CSI_FIELD,GPIO3_IO24,USDHC2_VSELECT,,,,,,ALT5 +GPIO_EMC_39,SEMC_DQS,FLEXPWM1_PWM3_B,LPUART8_RXD,SAI3_TX_SYNC,WDOG1_B,GPIO3_IO25,USDHC2_CD_B,,,,,,ALT5 +GPIO_EMC_40,SEMC_RDY,GPT2_CAPTURE2,LPSPI1_PCS2,USB_OTG2_OC,ENET_MDC,GPIO3_IO26,USDHC2_RESET_B,,,,,,ALT5 +GPIO_EMC_41,SEMC_CSX0,GPT2_CAPTURE1,LPSPI1_PCS3,USB_OTG2_PWR,ENET_MDIO,GPIO3_IO27,USDHC1_VSELECT,,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_CMD,FLEXPWM1_PWM0_A,LPI2C3_SCL,XBAR_INOUT04,LPSPI1_SCK,GPIO3_IO12,FLEXSPI_A_SS1_B,,,,,,ALT5 +GPIO_SD_B0_01,USDHC1_CLK,FLEXPWM1_PWM0_B,LPI2C3_SDA,XBAR_INOUT05,LPSPI1_PCS0,GPIO3_IO13,FLEXSPI_B_SS1_B,,,,,,ALT5 +GPIO_SD_B0_02,USDHC1_DATA0,FLEXPWM1_PWM1_A,LPUART8_CTS_B,XBAR_INOUT06,LPSPI1_SOUT,GPIO3_IO14,,,,,,,ALT5 +GPIO_SD_B0_03,USDHC1_DATA1,FLEXPWM1_PWM1_B,LPUART8_RTS_B,XBAR_INOUT07,LPSPI1_SIN,GPIO3_IO15,,,,,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA2,FLEXPWM1_PWM2_A,LPUART8_TXD,XBAR_INOUT08,FLEXSPI_B_SS0_B,GPIO3_IO16,CCM_CLKO1,,,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA3,FLEXPWM1_PWM2_B,LPUART8_RXD,XBAR_INOUT09,FLEXSPI_B_DQS,GPIO3_IO17,CCM_CLKO2,,,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA3,FLEXSPI_B_DATA3,FLEXPWM1_PWM3_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",LPUART4_TXD,GPIO3_IO00,,,,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA2,FLEXSPI_B_DATA2,FLEXPWM1_PWM3_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",LPUART4_RXD,GPIO3_IO01,,,,,,,ALT5 +GPIO_SD_B1_02,USDHC2_DATA1,FLEXSPI_B_DATA1,FLEXPWM2_PWM3_A,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXCAN1_TX,GPIO3_IO02,CCM_WAIT,,,,,,ALT5 +GPIO_SD_B1_03,USDHC2_DATA0,FLEXSPI_B_DATA0,FLEXPWM2_PWM3_B,SAI1_MCLK,FLEXCAN1_RX,GPIO3_IO03,CCM_PMIC_READY,,,,,,ALT5 +GPIO_SD_B1_04,USDHC2_CLK,FLEXSPI_B_SCLK,LPI2C1_SCL,SAI1_RX_SYNC,FLEXSPI_A_SS1_B,GPIO3_IO04,CCM_STOP,,,,,,ALT5 +GPIO_SD_B1_05,USDHC2_CMD,FLEXSPI_A_DQS,LPI2C1_SDA,SAI1_RX_BCLK,FLEXSPI_B_SS0_B,GPIO3_IO05,,,,,,,ALT5 +GPIO_SD_B1_06,USDHC2_RESET_B,FLEXSPI_A_SS0_B,LPUART7_CTS_B,SAI1_RX_DATA0,LPSPI2_PCS0,GPIO3_IO06,,,,,,,ALT5 +GPIO_SD_B1_07,SEMC_CSX1,FLEXSPI_A_SCLK,LPUART7_RTS_B,SAI1_TX_DATA0,LPSPI2_SCK,GPIO3_IO07,CCM_REF_EN_B,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,LPUART7_TXD,SAI1_TX_BCLK,LPSPI2_SOUT,GPIO3_IO08,SEMC_CSX2,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA1,LPUART7_RXD,SAI1_TX_SYNC,LPSPI2_SIN,GPIO3_IO09,,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA2,LPUART2_RXD,LPI2C2_SDA,LPSPI2_PCS2,GPIO3_IO10,,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_DATA3,LPUART2_TXD,LPI2C2_SCL,LPSPI2_PCS3,GPIO3_IO11,,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index 8bd2a579174a..c9e6d8bf2c14 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (8 * 1024 * 1024) // MIMXRT1060_EVK has 1 user LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_09) +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index b34169801b90..32f87046b8a5 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -2,6 +2,25 @@ MCU_SERIES = MIMXRT1062 MCU_VARIANT = MIMXRT1062DVJ6A JLINK_PATH ?= /media/RT1060-EVK/ +JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink + + +ifdef JLINK_IP +JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) +else +JLINK_CONNECTION_SETTINGS = -USB +endif + + +deploy_jlink: $(BUILD)/firmware.hex + $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "st" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "loadfile \"$(realpath $(BUILD)/firmware.hex)\"" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "qc" >> $(JLINK_COMMANDER_SCRIPT) + $(JLINK_PATH)JLinkExe -device $(MCU_VARIANT) -if SWD $(JLINK_CONNECTION_SETTINGS) -CommanderScript $(JLINK_COMMANDER_SCRIPT) deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.c deleted file mode 100644 index d5da9c6f9927..000000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "pin.h" - -static pin_af_obj_t GPIO_AD_B0_09_af[] = { - PIN_AF(GPIO1_IO09, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_09 = PIN(GPIO_AD_B0_09, GPIO1, 9, GPIO_AD_B0_09_af); diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv new file mode 100644 index 000000000000..afd63d4f97fe --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv @@ -0,0 +1,51 @@ +D0,GPIO_AD_B1_07 +D1,GPIO_AD_B1_06 +D2,GPIO_AD_B0_11 +D3,GPIO_AD_B1_08 +D4,GPIO_AD_B0_09 +D5,GPIO_AD_B0_10 +D6,GPIO_AD_B1_02 +D7,GPIO_AD_B1_03 +D8,GPIO_AD_B0_03 +D9,GPIO_AD_B0_02 +D10,GPIO_SD_B0_01 +D11,GPIO_SD_B0_02 +D12,GPIO_SD_B0_03 +D13,GPIO_SD_B0_00 +D14,GPIO_AD_B1_01 +D15,GPIO_AD_B1_00 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_04 +A3,GPIO_AD_B1_05 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +RX,GPIO_AD_B1_07 +TX,GPIO_AD_B1_06 +SCL,GPIO_AD_B1_00 +SDA,GPIO_AD_B1_01 +SCK,GPIO_SD_B0_00 +SDI,GPIO_SD_B0_03 +SDO,GPIO_SD_B0_02 +CS,GPIO_SD_B0_01 +LED_GREEN,GPIO_AD_B0_09 +GPIO_AD_B1_07,GPIO_AD_B1_07 +GPIO_AD_B1_06,GPIO_AD_B1_06 +GPIO_AD_B0_11,GPIO_AD_B0_11 +GPIO_AD_B1_08,GPIO_AD_B1_08 +GPIO_AD_B0_09,GPIO_AD_B0_09 +GPIO_AD_B0_10,GPIO_AD_B0_10 +GPIO_AD_B1_02,GPIO_AD_B1_02 +GPIO_AD_B1_03,GPIO_AD_B1_03 +GPIO_AD_B0_03,GPIO_AD_B0_03 +GPIO_AD_B0_02,GPIO_AD_B0_02 +GPIO_SD_B0_01,GPIO_SD_B0_01 +GPIO_SD_B0_02,GPIO_SD_B0_02 +GPIO_SD_B0_03,GPIO_SD_B0_03 +GPIO_SD_B0_00,GPIO_SD_B0_00 +GPIO_AD_B1_01,GPIO_AD_B1_01 +GPIO_AD_B1_00,GPIO_AD_B1_00 +GPIO_AD_B1_10,GPIO_AD_B1_10 +GPIO_AD_B1_11,GPIO_AD_B1_11 +GPIO_AD_B1_04,GPIO_AD_B1_04 +GPIO_AD_B1_05,GPIO_AD_B1_05 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.h deleted file mode 100644 index baef51c6c861..000000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_09; diff --git a/ports/mimxrt/boards/MIMXRT1062_af.csv b/ports/mimxrt/boards/MIMXRT1062_af.csv new file mode 100644 index 000000000000..9b83efeddc16 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1062_af.csv @@ -0,0 +1,125 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,FLEXPWM2_PWM3_A,XBAR_INOUT14,REF_CLK_32K,USB_OTG2_ID,LPI2C1_SCLS,GPIO1_IO00,USDHC1_RESET_B,LPSPI3_SCK,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_01,FLEXPWM2_PWM3_B,XBAR_INOUT15,REF_CLK_24M,USB_OTG1_ID,LPI2C1_SDAS,GPIO1_IO01,EWM_OUT_B,LPSPI3_SOUT,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_02,FLEXCAN2_TX,XBAR_INOUT16,LPUART6_TXD,USB_OTG1_PWR,FLEXPWM1_PWM0_X,GPIO1_IO02,LPI2C1_HREQ,LPSPI3_SIN,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_03,FLEXCAN2_RX,XBAR_INOUT17,LPUART6_RXD,USB_OTG1_OC,FLEXPWM1_PWM1_X,GPIO1_IO03,REF_CLK_24M,LPSPI3_PCS0,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_04,SRC_BOOT_MODE0,MQS_RIGHT,ENET_TX_DATA3,SAI2_TX_SYNC,CSI_DATA09,GPIO1_IO04,PIT_TRIGGER0,LPSPI3_PCS1,,,,,ALT0 +GPIO_AD_B0_05,SRC_BOOT_MODE1,MQS_LEFT,ENET_TX_DATA2,SAI2_TX_BCLK,CSI_DATA08,GPIO1_IO05,XBAR_INOUT17,LPSPI3_PCS2,,,,,ALT0 +GPIO_AD_B0_06,"JTAG_TMS,SWD_DIO",GPT2_COMPARE1,ENET_RX_CLK,SAI2_RX_BCLK,CSI_DATA07,GPIO1_IO06,XBAR_INOUT18,LPSPI3_PCS3,,,,,ALT0 +GPIO_AD_B0_07,"JTAG_TCK,SWD_CLK",GPT2_COMPARE2,ENET_TX_ER,SAI2_RX_SYNC,CSI_DATA06,GPIO1_IO07,XBAR_INOUT19,ENET_1588_EVENT3_OUT,,,,,ALT0 +GPIO_AD_B0_08,JTAG_MOD,GPT2_COMPARE3,ENET_RX_DATA3,SAI2_RX_DATA,CSI_DATA05,GPIO1_IO08,XBAR_INOUT20,ENET_1588_EVENT3_IN,,,,,ALT0 +GPIO_AD_B0_09,JTAG_TDI,FLEXPWM2_PWM3_A,ENET_RX_DATA2,SAI2_TX_DATA,CSI_DATA04,GPIO1_IO09,XBAR_INOUT21,GPT2_CLK,,,,,ALT0 +GPIO_AD_B0_10,JTAG_TDO,FLEXPWM1_PWM3_A,ENET_CRS,SAI2_MCLK,CSI_DATA03,GPIO1_IO10,XBAR_INOUT22,ENET_1588_EVENT0_OUT,FLEXCAN3_TX,,,,ALT0 +GPIO_AD_B0_11,JTAG_TRSTB,FLEXPWM1_PWM3_B,ENET_COL,WDOG1_B,CSI_DATA02,GPIO1_IO11,XBAR_INOUT23,ENET_1588_EVENT0_IN,FLEXCAN3_RX,,,,ALT0 +GPIO_AD_B0_12,LPI2C4_SCL,CCM_PMIC_READY,LPUART1_TXD,WDOG2_B,FLEXPWM1_PWM2_X,GPIO1_IO12,ENET_1588_EVENT1_OUT,,,,ADC1_IN1,,ALT5 +GPIO_AD_B0_13,LPI2C4_SDA,GPT1_CLK,LPUART1_RXD,EWM_OUT_B,FLEXPWM1_PWM3_X,GPIO1_IO13,ENET_1588_EVENT1_IN,REF_CLK_24M,,,ADC1_IN2,ACMP1_IN2,ALT5 +GPIO_AD_B0_14,USB_OTG2_OC,XBAR_INOUT24,LPUART1_CTS_B,ENET_1588_EVENT0_OUT,CSI_VSYNC,GPIO1_IO14,FLEXCAN2_TX,WDOG1_ANY,FLEXCAN3_TX,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B0_15,USB_OTG2_PWR,XBAR_INOUT25,LPUART1_RTS_B,ENET_1588_EVENT0_IN,CSI_HSYNC,GPIO1_IO15,FLEXCAN2_RX,WDOG1_RESET_B_DEB,FLEXCAN3_RX,,ADC1_IN4,ACMP3_IN2,ALT5 +GPIO_AD_B1_00,USB_OTG2_ID,TMR3_TIMER0,LPUART2_CTS_B,LPI2C1_SCL,WDOG1_B,GPIO1_IO16,USDHC1_WP,KPP_ROW7,ENET2_1588_EVENT0_OUT,FLEXIO3_D00,"ADC1_IN5,ADC2_IN5",ACMP4_IN2,ALT5 +GPIO_AD_B1_01,USB_OTG1_PWR,TMR3_TIMER1,LPUART2_RTS_B,LPI2C1_SDA,CCM_PMIC_READY,GPIO1_IO17,USDHC1_VSELECT,KPP_COL7,ENET2_1588_EVENT0_IN,FLEXIO3_D01,"ADC1_IN6,ADC2_IN6","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B1_02,USB_OTG1_ID,TMR3_TIMER2,LPUART2_TXD,SPDIF_OUT,ENET_1588_EVENT2_OUT,GPIO1_IO18,USDHC1_CD_B,KPP_ROW6,GPT2_CLK,FLEXIO3_D02,"ADC1_IN7,ADC2_IN7",ACMP1_IN3,ALT5 +GPIO_AD_B1_03,USB_OTG1_OC,TMR3_TIMER3,LPUART2_RXD,SPDIF_IN,ENET_1588_EVENT2_IN,GPIO1_IO19,USDHC2_CD_B,KPP_COL6,GPT2_CAPTURE1,FLEXIO3_D03,"ADC1_IN8,ADC2_IN8",ACMP2_IN3,ALT5 +GPIO_AD_B1_04,FLEXSPI_B_DATA3,ENET_MDC,LPUART3_CTS_B,SPDIF_SR_CLK,CSI_PIXCLK,GPIO1_IO20,USDHC2_DATA0,KPP_ROW5,GPT2_CAPTURE2,FLEXIO3_D04,"ADC1_IN9,ADC2_IN9",ACMP3_IN3,ALT5 +GPIO_AD_B1_05,FLEXSPI_B_DATA2,ENET_MDIO,LPUART3_RTS_B,SPDIF_OUT,CSI_MCLK,GPIO1_IO21,USDHC2_DATA1,KPP_COL5,GPT2_COMPARE1,FLEXIO3_D05,"ADC1_IN10,ADC2_IN10",ACMP4_IN3,ALT5 +GPIO_AD_B1_06,FLEXSPI_B_DATA1,LPI2C3_SDA,LPUART3_TXD,SPDIF_LOCK,CSI_VSYNC,GPIO1_IO22,USDHC2_DATA2,KPP_ROW4,GPT2_COMPARE2,FLEXIO3_D06,"ADC1_IN11,ADC2_IN11","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_07,FLEXSPI_B_DATA0,LPI2C3_SCL,LPUART3_RXD,SPDIF_EXT_CLK,CSI_HSYNC,GPIO1_IO23,USDHC2_DATA3,KPP_COL4,GPT2_COMPARE3,FLEXIO3_D07,"ADC1_IN12,ADC2_IN12",ACMP1_IN5,ALT5 +GPIO_AD_B1_08,FLEXSPI_A_SS1_B,FLEXPWM4_PWM0_A,FLEXCAN1_TX,CCM_PMIC_READY,CSI_DATA09,GPIO1_IO24,USDHC2_CMD,KPP_ROW3,,FLEXIO3_D08,"ADC1_IN13,ADC2_IN13",ACMP2_IN5,ALT5 +GPIO_AD_B1_09,FLEXSPI_A_DQS,FLEXPWM4_PWM1_A,FLEXCAN1_RX,SAI1_MCLK,CSI_DATA08,GPIO1_IO25,USDHC2_CLK,KPP_COL3,,FLEXIO3_D09,"ADC1_IN14,ADC2_IN14",ACMP3_IN5,ALT5 +GPIO_AD_B1_10,FLEXSPI_A_DATA3,WDOG1_B,LPUART8_TXD,SAI1_RX_SYNC,CSI_DATA07,GPIO1_IO26,USDHC2_WP,KPP_ROW2,ENET2_1588_EVENT1_OUT,FLEXIO3_D10,"ADC1_IN15,ADC2_IN15",ACMP4_IN5,ALT5 +GPIO_AD_B1_11,FLEXSPI_A_DATA2,EWM_OUT_B,LPUART8_RXD,SAI1_RX_BCLK,CSI_DATA06,GPIO1_IO27,USDHC2_RESET_B,KPP_COL2,ENET2_1588_EVENT1_IN,FLEXIO3_D11,ADC2_IN0,ACMP1_IN6,ALT5 +GPIO_AD_B1_12,FLEXSPI_A_DATA1,ACMP_OUT00,LPSPI3_PCS0,SAI1_RX_DATA0,CSI_DATA05,GPIO1_IO28,USDHC2_DATA4,KPP_ROW1,ENET2_1588_EVENT2_OUT,FLEXIO3_D12,ADC2_IN1,"ACMP1_OUT,ACMP2_IN6",ALT5 +GPIO_AD_B1_13,FLEXSPI_A_DATA0,ACMP_OUT01,LPSPI3_SIN,SAI1_TX_DATA0,CSI_DATA04,GPIO1_IO29,USDHC2_DATA5,KPP_COL1,ENET2_1588_EVENT2_IN,FLEXIO3_D13,ADC2_IN2,"ACMP2_OUT,ACMP3_IN6",ALT5 +GPIO_AD_B1_14,FLEXSPI_A_SCLK,ACMP_OUT02,LPSPI3_SOUT,SAI1_TX_BCLK,CSI_DATA03,GPIO1_IO30,USDHC2_DATA6,KPP_ROW0,ENET2_1588_EVENT3_OUT,FLEXIO3_D14,ADC2_IN3,"ACMP3_OUT,ACMP4_IN6",ALT5 +GPIO_AD_B1_15,FLEXSPI_A_SS0_B,ACMP_OUT03,LPSPI3_SCK,SAI1_TX_SYNC,CSI_DATA02,GPIO1_IO31,USDHC2_DATA7,KPP_COL0,ENET2_1588_EVENT3_IN,FLEXIO3_D15,ADC2_IN4,ACMP4_OUT,ALT5 +GPIO_B0_00,LCD_CLK,TMR1_TIMER0,MQS_RIGHT,LPSPI4_PCS0,FLEXIO2_D00,GPIO2_IO00,SEMC_CSX1,,ENET2_MDC,,,,ALT5 +GPIO_B0_01,LCD_ENABLE,TMR1_TIMER1,MQS_LEFT,LPSPI4_SIN,FLEXIO2_D01,GPIO2_IO01,SEMC_CSX2,,ENET2_MDIO,,,,ALT5 +GPIO_B0_02,LCD_HSYNC,TMR1_TIMER2,FLEXCAN1_TX,LPSPI4_SOUT,FLEXIO2_D02,GPIO2_IO02,SEMC_CSX3,,ENET2_1588_EVENT0_OUT,,,,ALT5 +GPIO_B0_03,LCD_VSYNC,TMR2_TIMER0,FLEXCAN1_RX,LPSPI4_SCK,FLEXIO2_D03,GPIO2_IO03,WDOG2_RESET_B_DEB,,ENET2_1588_EVENT0_IN,,,,ALT5 +GPIO_B0_04,LCD_DATA00,TMR2_TIMER1,LPI2C2_SCL,ARM_TRACE0,FLEXIO2_D04,GPIO2_IO04,SRC_BT_CFG00,,ENET2_TDATA3,,,,ALT5 +GPIO_B0_05,LCD_DATA01,TMR2_TIMER2,LPI2C2_SDA,ARM_TRACE1,FLEXIO2_D05,GPIO2_IO05,SRC_BT_CFG01,,ENET2_TDATA2,,,,ALT5 +GPIO_B0_06,LCD_DATA02,TMR3_TIMER0,FLEXPWM2_PWM0_A,ARM_TRACE2,FLEXIO2_D06,GPIO2_IO06,SRC_BT_CFG02,,ENET2_RX_CLK,,,,ALT5 +GPIO_B0_07,LCD_DATA03,TMR3_TIMER1,FLEXPWM2_PWM0_B,ARM_TRACE3,FLEXIO2_D07,GPIO2_IO07,SRC_BT_CFG03,,ENET2_TX_ER,,,,ALT5 +GPIO_B0_08,LCD_DATA04,TMR3_TIMER2,FLEXPWM2_PWM1_A,LPUART3_TXD,FLEXIO2_D08,GPIO2_IO08,SRC_BT_CFG04,,ENET2_RDATA3,,,,ALT5 +GPIO_B0_09,LCD_DATA05,TMR4_TIMER0,FLEXPWM2_PWM1_B,LPUART3_RXD,FLEXIO2_D09,GPIO2_IO09,SRC_BT_CFG05,,ENET2_RDATA2,,,,ALT5 +GPIO_B0_10,LCD_DATA06,TMR4_TIMER1,FLEXPWM2_PWM2_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",FLEXIO2_D10,GPIO2_IO10,SRC_BT_CFG06,,ENET2_CRS,,,,ALT5 +GPIO_B0_11,LCD_DATA07,TMR4_TIMER2,FLEXPWM2_PWM2_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",FLEXIO2_D11,GPIO2_IO11,SRC_BT_CFG07,,ENET2_COL,,,,ALT5 +GPIO_B0_12,LCD_DATA08,XBAR_INOUT10,ARM_TRACE_CLK,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXIO2_D12,GPIO2_IO12,SRC_BT_CFG08,,ENET2_TDATA0,,,,ALT5 +GPIO_B0_13,LCD_DATA09,XBAR_INOUT11,ARM_TRACE_SWO,SAI1_MCLK,FLEXIO2_D13,GPIO2_IO13,SRC_BT_CFG09,,ENET2_TDATA1,,,,ALT5 +GPIO_B0_14,LCD_DATA10,XBAR_INOUT12,ARM_TXEV,SAI1_RX_SYNC,FLEXIO2_D14,GPIO2_IO14,SRC_BT_CFG10,,ENET2_TX_EN,,,,ALT5 +GPIO_B0_15,LCD_DATA11,XBAR_INOUT13,ARM_EVENT1,SAI1_RX_DATA0,FLEXIO2_D15,GPIO2_IO15,SRC_BT_CFG11,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_B1_00,LCD_DATA12,XBAR_INOUT14,LPUART4_TXD,SAI1_RX_DATA0,FLEXIO2_D16,GPIO2_IO16,FLEXPWM1_PWM3_A,,ENET2_RX_ER,FLEXIO3_D16,,,ALT5 +GPIO_B1_01,LCD_DATA13,XBAR_INOUT15,LPUART4_RXD,SAI1_TX_DATA0,FLEXIO2_D17,GPIO2_IO17,FLEXPWM1_PWM3_B,,ENET2_RDATA0,FLEXIO3_D17,,,ALT5 +GPIO_B1_02,LCD_DATA14,XBAR_INOUT16,LPSPI4_PCS2,SAI1_TX_BCLK,FLEXIO2_D18,GPIO2_IO18,FLEXPWM2_PWM3_A,,ENET2_RDATA1,FLEXIO3_D18,,,ALT5 +GPIO_B1_03,LCD_DATA15,XBAR_INOUT17,LPSPI4_PCS1,SAI1_TX_SYNC,FLEXIO2_D19,GPIO2_IO19,FLEXPWM2_PWM3_B,,ENET2_RX_EN,FLEXIO3_D19,,,ALT5 +GPIO_B1_04,LCD_DATA16,LPSPI4_PCS0,CSI_DATA15,ENET_RX_DATA0,FLEXIO2_D20,GPIO2_IO20,,,GPT1_CLK,FLEXIO3_D20,,,ALT5 +GPIO_B1_05,LCD_DATA17,LPSPI4_SIN,CSI_DATA14,ENET_RX_DATA1,FLEXIO2_D21,GPIO2_IO21,,,GPT1_CAPTURE1,FLEXIO3_D21,,,ALT5 +GPIO_B1_06,LCD_DATA18,LPSPI4_SOUT,CSI_DATA13,ENET_RX_EN,FLEXIO2_D22,GPIO2_IO22,,,GPT1_CAPTURE2,FLEXIO3_D22,,,ALT5 +GPIO_B1_07,LCD_DATA19,LPSPI4_SCK,CSI_DATA12,ENET_TX_DATA0,FLEXIO2_D23,GPIO2_IO23,,,GPT1_COMPARE1,FLEXIO3_D23,,,ALT5 +GPIO_B1_08,LCD_DATA20,TMR1_TIMER3,CSI_DATA11,ENET_TX_DATA1,FLEXIO2_D24,GPIO2_IO24,FLEXCAN2_TX,,GPT1_COMPARE2,FLEXIO3_D24,,,ALT5 +GPIO_B1_09,LCD_DATA21,TMR2_TIMER3,CSI_DATA10,ENET_TX_EN,FLEXIO2_D25,GPIO2_IO25,FLEXCAN2_RX,,GPT1_COMPARE3,FLEXIO3_D25,,,ALT5 +GPIO_B1_10,LCD_DATA22,TMR3_TIMER3,CSI_DATA00,ENET_TX_CLK,FLEXIO2_D26,GPIO2_IO26,ENET_REF_CLK,,,FLEXIO3_D26,,,ALT5 +GPIO_B1_11,LCD_DATA23,TMR4_TIMER3,CSI_DATA01,ENET_RX_ER,FLEXIO2_D27,GPIO2_IO27,LPSPI4_PCS3,,,FLEXIO3_D27,,,ALT5 +GPIO_B1_12,,LPUART5_TXD,CSI_PIXCLK,ENET_1588_EVENT0_IN,FLEXIO2_D28,GPIO2_IO28,USDHC1_CD_B,,,FLEXIO3_D28,,,ALT5 +GPIO_B1_13,WDOG1_B,LPUART5_RXD,CSI_VSYNC,ENET_1588_EVENT0_OUT,FLEXIO2_D29,GPIO2_IO29,USDHC1_WP,,SEMC_DQS4,FLEXIO3_D29,,,ALT5 +GPIO_B1_14,ENET_MDC,FLEXPWM4_PWM2_A,CSI_HSYNC,XBAR_INOUT02,FLEXIO2_D30,GPIO2_IO30,USDHC1_VSELECT,,ENET2_TDATA0,FLEXIO3_D30,,,ALT5 +GPIO_B1_15,ENET_MDIO,FLEXPWM4_PWM3_A,CSI_MCLK,XBAR_INOUT03,FLEXIO2_D31,GPIO2_IO31,USDHC1_RESET_B,,ENET2_TDATA1,FLEXIO3_D31,,,ALT5 +GPIO_EMC_00,SEMC_DATA00,FLEXPWM4_PWM0_A,LPSPI2_SCK,XBAR_INOUT02,FLEXIO1_D00,GPIO4_IO0,USB_PHY1_TSTI_TX_LS_MODE,,,,,,ALT5 +GPIO_EMC_01,SEMC_DATA01,FLEXPWM4_PWM0_B,LPSPI2_PCS0,XBAR_INOUT03,FLEXIO1_D01,GPIO4_IO1,USB_PHY1_TSTI_TX_HS_MODE,JTAG_DE_B,,,,,ALT5 +GPIO_EMC_02,SEMC_DATA02,FLEXPWM4_PWM1_A,LPSPI2_SOUT,XBAR_INOUT04,FLEXIO1_D02,GPIO4_IO2,USB_PHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_03,SEMC_DATA03,FLEXPWM4_PWM1_B,LPSPI2_SIN,XBAR_INOUT05,FLEXIO1_D03,GPIO4_IO3,USB_PHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_04,SEMC_DATA04,FLEXPWM4_PWM2_A,SAI2_TX_DATA,XBAR_INOUT06,FLEXIO1_D04,GPIO4_IO4,USB_PHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_05,SEMC_DATA05,FLEXPWM4_PWM2_B,SAI2_TX_SYNC,XBAR_INOUT07,FLEXIO1_D05,GPIO4_IO5,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_06,SEMC_DATA06,FLEXPWM2_PWM0_A,SAI2_TX_BCLK,XBAR_INOUT08,FLEXIO1_D06,GPIO4_IO6,USB_PHY2_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_07,SEMC_DATA07,FLEXPWM2_PWM0_B,SAI2_MCLK,XBAR_INOUT09,FLEXIO1_D07,GPIO4_IO7,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,FLEXPWM2_PWM1_A,SAI2_RX_DATA,XBAR_INOUT17,FLEXIO1_D08,GPIO4_IO8,USB_PHY1_TSTI_TX_DP,,,,,,ALT5 +GPIO_EMC_09,SEMC_ADDR00,FLEXPWM2_PWM1_B,SAI2_RX_SYNC,FLEXCAN2_TX,FLEXIO1_D09,GPIO4_IO9,USB_PHY1_TSTI_TX_EN,,FLEXSPI2_B_SS1_B,,,,ALT5 +GPIO_EMC_10,SEMC_ADDR01,FLEXPWM2_PWM2_A,SAI2_RX_BCLK,FLEXCAN2_RX,FLEXIO1_D10,GPIO4_IO10,USB_PHY1_TSTI_TX_HIZ,,FLEXSPI2_B_SS0_B,,,,ALT5 +GPIO_EMC_11,SEMC_ADDR02,FLEXPWM2_PWM2_B,LPI2C4_SDA,USDHC2_RESET_B,FLEXIO1_D11,GPIO4_IO11,USB_PHY2_TSTO_RX_FS_RXD,,FLEXSPI2_B_DQS,,,,ALT5 +GPIO_EMC_12,SEMC_ADDR03,XBAR_INOUT24,LPI2C4_SCL,USDHC1_WP,FLEXPWM1_PWM3_A,GPIO4_IO12,USB_PHY1_TSTO_PLL_CLK20DIV,,FLEXSPI2_B_SCLK,,,,ALT5 +GPIO_EMC_13,SEMC_ADDR04,XBAR_INOUT25,LPUART3_TXD,MQS_RIGHT,FLEXPWM1_PWM3_B,GPIO4_IO13,USB_PHY2_TSTO_RX_FS_20DIV,,FLEXSPI2_B_DATA0,,,,ALT5 +GPIO_EMC_14,SEMC_ADDR05,XBAR_INOUT19,LPUART3_RXD,MQS_LEFT,LPSPI2_PCS1,GPIO4_IO14,USB_PHY2_TSTO_RX_FS_ELCH,,FLEXSPI2_B_DATA1,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR06,XBAR_INOUT20,LPUART3_CTS_B,SPDIF_OUT,TMR3_TIMER0,GPIO4_IO15,USB_PHY2_TSTO_RX_FS_ON_DET,,FLEXSPI2_B_DATA2,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR07,XBAR_INOUT21,LPUART3_RTS_B,SPDIF_IN,TMR3_TIMER1,GPIO4_IO16,,,FLEXSPI2_B_DATA3,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR08,FLEXPWM4_PWM3_A,LPUART4_CTS_B,FLEXCAN1_TX,TMR3_TIMER2,GPIO4_IO17,,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR09,FLEXPWM4_PWM3_B,LPUART4_RTS_B,FLEXCAN1_RX,TMR3_TIMER3,GPIO4_IO18,SNVS_VIO_5_CTL,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR11,FLEXPWM2_PWM3_A,LPUART4_TXD,ENET_RX_DATA1,TMR2_TIMER0,GPIO4_IO19,SNVS_VIO_5_B,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR12,FLEXPWM2_PWM3_B,LPUART4_RXD,ENET_RX_DATA0,TMR2_TIMER1,GPIO4_IO20,,,,,,,ALT5 +GPIO_EMC_21,SEMC_BA0,FLEXPWM3_PWM3_A,LPI2C3_SDA,ENET_TX_DATA1,TMR2_TIMER2,GPIO4_IO21,,,,,,,ALT5 +GPIO_EMC_22,SEMC_BA1,FLEXPWM3_PWM3_B,LPI2C3_SCL,ENET_TX_DATA0,TMR2_TIMER3,GPIO4_IO22,,,FLEXSPI2_A_SS1_B,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR10,FLEXPWM1_PWM0_A,LPUART5_TXD,ENET_RX_EN,GPT1_CAPTURE2,GPIO4_IO23,,,FLEXSPI2_A_DQS,,,,ALT5 +GPIO_EMC_24,SEMC_CAS,FLEXPWM1_PWM0_B,LPUART5_RXD,ENET_TX_EN,GPT1_CAPTURE1,GPIO4_IO24,,,FLEXSPI2_A_SS0_B,,,,ALT5 +GPIO_EMC_25,SEMC_RAS,FLEXPWM1_PWM1_A,LPUART6_TXD,ENET_TX_CLK,ENET_REF_CLK,GPIO4_IO25,,,FLEXSPI2_A_SCLK,,,,ALT5 +GPIO_EMC_26,SEMC_CLK,FLEXPWM1_PWM1_B,LPUART6_RXD,ENET_RX_ER,FLEXIO1_D12,GPIO4_IO26,,,FLEXSPI2_A_DATA0,,,,ALT5 +GPIO_EMC_27,SEMC_CKE,FLEXPWM1_PWM2_A,LPUART5_RTS_B,LPSPI1_SCK,FLEXIO1_D13,GPIO4_IO27,,,FLEXSPI2_A_DATA1,,,,ALT5 +GPIO_EMC_28,SEMC_WE,FLEXPWM1_PWM2_B,LPUART5_CTS_B,LPSPI1_SOUT,FLEXIO1_D14,GPIO4_IO28,,,FLEXSPI2_A_DATA2,,,,ALT5 +GPIO_EMC_29,SEMC_CS0,FLEXPWM3_PWM0_A,LPUART6_RTS_B,LPSPI1_SIN,FLEXIO1_D15,GPIO4_IO29,,,FLEXSPI2_A_DATA3,,,,ALT5 +GPIO_EMC_30,SEMC_DATA08,FLEXPWM3_PWM0_B,LPUART6_CTS_B,LPSPI1_PCS0,CSI_DATA23,GPIO4_IO30,,,ENET2_TDATA0,,,,ALT5 +GPIO_EMC_31,SEMC_DATA09,FLEXPWM3_PWM1_A,LPUART7_TXD,LPSPI1_PCS1,CSI_DATA22,GPIO4_IO31,,,ENET2_TDATA1,,,,ALT5 +GPIO_EMC_32,SEMC_DATA10,FLEXPWM3_PWM1_B,LPUART7_RXD,CCM_PMIC_READY,CSI_DATA21,GPIO3_IO18,,,ENET2_TX_EN,,,,ALT5 +GPIO_EMC_33,SEMC_DATA11,FLEXPWM3_PWM2_A,USDHC1_RESET_B,SAI3_RX_DATA,CSI_DATA20,GPIO3_IO19,,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_EMC_34,SEMC_DATA12,FLEXPWM3_PWM2_B,USDHC1_VSELECT,SAI3_RX_SYNC,CSI_DATA19,GPIO3_IO20,,,ENET2_RX_ER,,,,ALT5 +GPIO_EMC_35,SEMC_DATA13,XBAR_INOUT18,GPT1_COMPARE1,SAI3_RX_BCLK,CSI_DATA18,GPIO3_IO21,USDHC1_CD_B,,ENET2_RDATA0,,,,ALT5 +GPIO_EMC_36,SEMC_DATA14,XBAR_INOUT22,GPT1_COMPARE2,SAI3_TX_DATA,CSI_DATA17,GPIO3_IO22,USDHC1_WP,,ENET2_RDATA1,FLEXCAN3_TX,,,ALT5 +GPIO_EMC_37,SEMC_DATA15,XBAR_INOUT23,GPT1_COMPARE3,SAI3_MCLK,CSI_DATA16,GPIO3_IO23,USDHC2_WP,,ENET2_RX_EN,FLEXCAN3_RX,,,ALT5 +GPIO_EMC_38,SEMC_DM1,FLEXPWM1_PWM3_A,LPUART8_TXD,SAI3_TX_BCLK,CSI_FIELD,GPIO3_IO24,USDHC2_VSELECT,,ENET2_MDC,,,,ALT5 +GPIO_EMC_39,SEMC_DQS,FLEXPWM1_PWM3_B,LPUART8_RXD,SAI3_TX_SYNC,WDOG1_B,GPIO3_IO25,USDHC2_CD_B,,ENET2_MDIO,,,,ALT5 +GPIO_EMC_40,SEMC_RDY,GPT2_CAPTURE2,LPSPI1_PCS2,USB_OTG2_OC,ENET_MDC,GPIO3_IO26,USDHC2_RESET_B,,,,,,ALT5 +GPIO_EMC_41,SEMC_CSX0,GPT2_CAPTURE1,LPSPI1_PCS3,USB_OTG2_PWR,ENET_MDIO,GPIO3_IO27,USDHC1_VSELECT,,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_CMD,FLEXPWM1_PWM0_A,LPI2C3_SCL,XBAR_INOUT04,LPSPI1_SCK,GPIO3_IO12,FLEXSPI_A_SS1_B,,ENET2_TX_EN,,,,ALT5 +GPIO_SD_B0_01,USDHC1_CLK,FLEXPWM1_PWM0_B,LPI2C3_SDA,XBAR_INOUT05,LPSPI1_PCS0,GPIO3_IO13,FLEXSPI_B_SS1_B,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_SD_B0_02,USDHC1_DATA0,FLEXPWM1_PWM1_A,LPUART8_CTS_B,XBAR_INOUT06,LPSPI1_SOUT,GPIO3_IO14,,,ENET2_RX_ER,,,,ALT5 +GPIO_SD_B0_03,USDHC1_DATA1,FLEXPWM1_PWM1_B,LPUART8_RTS_B,XBAR_INOUT07,LPSPI1_SIN,GPIO3_IO15,,,ENET2_RDATA0,,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA2,FLEXPWM1_PWM2_A,LPUART8_TXD,XBAR_INOUT08,FLEXSPI_B_SS0_B,GPIO3_IO16,CCM_CLKO1,,ENET2_RDATA1,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA3,FLEXPWM1_PWM2_B,LPUART8_RXD,XBAR_INOUT09,FLEXSPI_B_DQS,GPIO3_IO17,CCM_CLKO2,,ENET2_RX_EN,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA3,FLEXSPI_B_DATA3,FLEXPWM1_PWM3_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",LPUART4_TXD,GPIO3_IO00,,,SAI3_RX_DATA,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA2,FLEXSPI_B_DATA2,FLEXPWM1_PWM3_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",LPUART4_RXD,GPIO3_IO01,,,SAI3_TX_DATA,,,,ALT5 +GPIO_SD_B1_02,USDHC2_DATA1,FLEXSPI_B_DATA1,FLEXPWM2_PWM3_A,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXCAN1_TX,GPIO3_IO02,CCM_WAIT,,SAI3_TX_SYNC,,,,ALT5 +GPIO_SD_B1_03,USDHC2_DATA0,FLEXSPI_B_DATA0,FLEXPWM2_PWM3_B,SAI1_MCLK,FLEXCAN1_RX,GPIO3_IO03,CCM_PMIC_READY,,SAI3_TX_BCLK,,,,ALT5 +GPIO_SD_B1_04,USDHC2_CLK,FLEXSPI_B_SCLK,LPI2C1_SCL,SAI1_RX_SYNC,FLEXSPI_A_SS1_B,GPIO3_IO04,CCM_STOP,,SAI3_MCLK,,,,ALT5 +GPIO_SD_B1_05,USDHC2_CMD,FLEXSPI_A_DQS,LPI2C1_SDA,SAI1_RX_BCLK,FLEXSPI_B_SS0_B,GPIO3_IO05,,,SAI3_RX_SYNC,,,,ALT5 +GPIO_SD_B1_06,USDHC2_RESET_B,FLEXSPI_A_SS0_B,LPUART7_CTS_B,SAI1_RX_DATA0,LPSPI2_PCS0,GPIO3_IO06,,,SAI3_RX_BCLK,,,,ALT5 +GPIO_SD_B1_07,SEMC_CSX1,FLEXSPI_A_SCLK,LPUART7_RTS_B,SAI1_TX_DATA0,LPSPI2_SCK,GPIO3_IO07,,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,LPUART7_TXD,SAI1_TX_BCLK,LPSPI2_SOUT,GPIO3_IO08,SEMC_CSX2,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA1,LPUART7_RXD,SAI1_TX_SYNC,LPSPI2_SIN,GPIO3_IO09,,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA2,LPUART2_RXD,LPI2C2_SDA,LPSPI2_PCS2,GPIO3_IO10,,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_DATA3,LPUART2_TXD,LPI2C2_SCL,LPSPI2_PCS3,GPIO3_IO11,,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index e05c8824d26c..3eddb4102142 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -3,6 +3,6 @@ // MIMXRT1064_EVK has 1 user LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_09) +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.c deleted file mode 100644 index d5da9c6f9927..000000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "pin.h" - -static pin_af_obj_t GPIO_AD_B0_09_af[] = { - PIN_AF(GPIO1_IO09, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_09 = PIN(GPIO_AD_B0_09, GPIO1, 9, GPIO_AD_B0_09_af); diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv new file mode 100644 index 000000000000..afd63d4f97fe --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv @@ -0,0 +1,51 @@ +D0,GPIO_AD_B1_07 +D1,GPIO_AD_B1_06 +D2,GPIO_AD_B0_11 +D3,GPIO_AD_B1_08 +D4,GPIO_AD_B0_09 +D5,GPIO_AD_B0_10 +D6,GPIO_AD_B1_02 +D7,GPIO_AD_B1_03 +D8,GPIO_AD_B0_03 +D9,GPIO_AD_B0_02 +D10,GPIO_SD_B0_01 +D11,GPIO_SD_B0_02 +D12,GPIO_SD_B0_03 +D13,GPIO_SD_B0_00 +D14,GPIO_AD_B1_01 +D15,GPIO_AD_B1_00 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_04 +A3,GPIO_AD_B1_05 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +RX,GPIO_AD_B1_07 +TX,GPIO_AD_B1_06 +SCL,GPIO_AD_B1_00 +SDA,GPIO_AD_B1_01 +SCK,GPIO_SD_B0_00 +SDI,GPIO_SD_B0_03 +SDO,GPIO_SD_B0_02 +CS,GPIO_SD_B0_01 +LED_GREEN,GPIO_AD_B0_09 +GPIO_AD_B1_07,GPIO_AD_B1_07 +GPIO_AD_B1_06,GPIO_AD_B1_06 +GPIO_AD_B0_11,GPIO_AD_B0_11 +GPIO_AD_B1_08,GPIO_AD_B1_08 +GPIO_AD_B0_09,GPIO_AD_B0_09 +GPIO_AD_B0_10,GPIO_AD_B0_10 +GPIO_AD_B1_02,GPIO_AD_B1_02 +GPIO_AD_B1_03,GPIO_AD_B1_03 +GPIO_AD_B0_03,GPIO_AD_B0_03 +GPIO_AD_B0_02,GPIO_AD_B0_02 +GPIO_SD_B0_01,GPIO_SD_B0_01 +GPIO_SD_B0_02,GPIO_SD_B0_02 +GPIO_SD_B0_03,GPIO_SD_B0_03 +GPIO_SD_B0_00,GPIO_SD_B0_00 +GPIO_AD_B1_01,GPIO_AD_B1_01 +GPIO_AD_B1_00,GPIO_AD_B1_00 +GPIO_AD_B1_10,GPIO_AD_B1_10 +GPIO_AD_B1_11,GPIO_AD_B1_11 +GPIO_AD_B1_04,GPIO_AD_B1_04 +GPIO_AD_B1_05,GPIO_AD_B1_05 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.h deleted file mode 100644 index baef51c6c861..000000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_09; diff --git a/ports/mimxrt/boards/MIMXRT1064_af.csv b/ports/mimxrt/boards/MIMXRT1064_af.csv new file mode 100644 index 000000000000..074a3f69ab3b --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_af.csv @@ -0,0 +1,125 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,FLEXPWM2_PWM3_A,XBAR_INOUT14,REF_CLK_32K,USB_OTG2_ID,LPI2C1_SCLS,GPIO1_IO00,USDHC1_RESET_B,LPSPI3_SCK,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_01,FLEXPWM2_PWM3_B,XBAR_INOUT15,REF_CLK_24M,USB_OTG1_ID,LPI2C1_SDAS,GPIO1_IO01,EWM_OUT_B,LPSPI3_SOUT,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_02,FLEXCAN2_TX,XBAR_INOUT16,LPUART6_TXD,USB_OTG1_PWR,FLEXPWM1_PWM0_X,GPIO1_IO02,LPI2C1_HREQ,LPSPI3_SIN,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_03,FLEXCAN2_RX,XBAR_INOUT17,LPUART6_RXD,USB_OTG1_OC,FLEXPWM1_PWM1_X,GPIO1_IO03,REF_CLK_24M,LPSPI3_PCS0,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_04,SRC_BOOT_MODE0,MQS_RIGHT,ENET_TX_DATA3,SAI2_TX_SYNC,CSI_DATA09,GPIO1_IO04,PIT_TRIGGER0,LPSPI3_PCS1,,,,,ALT0 +GPIO_AD_B0_05,SRC_BOOT_MODE1,MQS_LEFT,ENET_TX_DATA2,SAI2_TX_BCLK,CSI_DATA08,GPIO1_IO05,XBAR_INOUT17,LPSPI3_PCS2,,,,,ALT0 +GPIO_AD_B0_06,"JTAG_TMS,SWD_DIO",GPT2_COMPARE1,ENET_RX_CLK,SAI2_RX_BCLK,CSI_DATA07,GPIO1_IO06,XBAR_INOUT18,LPSPI3_PCS3,,,,,ALT0 +GPIO_AD_B0_07,"JTAG_TCK,SWD_CLK",GPT2_COMPARE2,ENET_TX_ER,SAI2_RX_SYNC,CSI_DATA06,GPIO1_IO07,XBAR_INOUT19,ENET_1588_EVENT3_OUT,,,,,ALT0 +GPIO_AD_B0_08,JTAG_MOD,GPT2_COMPARE3,ENET_RX_DATA3,SAI2_RX_DATA,CSI_DATA05,GPIO1_IO08,XBAR_INOUT20,ENET_1588_EVENT3_IN,,,,,ALT0 +GPIO_AD_B0_09,JTAG_TDI,FLEXPWM2_PWM3_A,ENET_RX_DATA2,SAI2_TX_DATA,CSI_DATA04,GPIO1_IO09,XBAR_INOUT21,GPT2_CLK,,SEMC_DQS4,,,ALT0 +GPIO_AD_B0_10,JTAG_TDO,FLEXPWM1_PWM3_A,ENET_CRS,SAI2_MCLK,CSI_DATA03,GPIO1_IO10,XBAR_INOUT22,ENET_1588_EVENT0_OUT,FLEXCAN3_TX,ARM_TRACE_SWO,,,ALT0 +GPIO_AD_B0_11,JTAG_TRSTB,FLEXPWM1_PWM3_B,ENET_COL,WDOG1_B,CSI_DATA02,GPIO1_IO11,XBAR_INOUT23,ENET_1588_EVENT0_IN,FLEXCAN3_RX,SEMC_CLK6,,,ALT0 +GPIO_AD_B0_12,LPI2C4_SCL,CCM_PMIC_READY,LPUART1_TXD,WDOG2_B,FLEXPWM1_PWM2_X,GPIO1_IO12,ENET_1588_EVENT1_OUT,NMI_GLUE_NMI,,,ADC1_IN1,,ALT5 +GPIO_AD_B0_13,LPI2C4_SDA,GPT1_CLK,LPUART1_RXD,EWM_OUT_B,FLEXPWM1_PWM3_X,GPIO1_IO13,ENET_1588_EVENT1_IN,REF_CLK_24M,,,ADC1_IN2,ACMP1_IN2,ALT5 +GPIO_AD_B0_14,USB_OTG2_OC,XBAR_INOUT24,LPUART1_CTS_B,ENET_1588_EVENT0_OUT,CSI_VSYNC,GPIO1_IO14,FLEXCAN2_TX,WDOG1_ANY,FLEXCAN3_TX,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B0_15,USB_OTG2_PWR,XBAR_INOUT25,LPUART1_RTS_B,ENET_1588_EVENT0_IN,CSI_HSYNC,GPIO1_IO15,FLEXCAN2_RX,WDOG1_RESET_B_DEB,FLEXCAN3_RX,,ADC1_IN4,ACMP3_IN2,ALT5 +GPIO_AD_B1_00,USB_OTG2_ID,TMR3_TIMER0,LPUART2_CTS_B,LPI2C1_SCL,WDOG1_B,GPIO1_IO16,USDHC1_WP,KPP_ROW7,ENET2_1588_EVENT0_OUT,FLEXIO3_D00,"ADC1_IN5,ADC2_IN5",ACMP4_IN2,ALT5 +GPIO_AD_B1_01,USB_OTG1_PWR,TMR3_TIMER1,LPUART2_RTS_B,LPI2C1_SDA,CCM_PMIC_READY,GPIO1_IO17,USDHC1_VSELECT,KPP_COL7,ENET2_1588_EVENT0_IN,FLEXIO3_D01,"ADC1_IN6,ADC2_IN6","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B1_02,USB_OTG1_ID,TMR3_TIMER2,LPUART2_TXD,SPDIF_OUT,ENET_1588_EVENT2_OUT,GPIO1_IO18,USDHC1_CD_B,KPP_ROW6,GPT2_CLK,FLEXIO3_D02,"ADC1_IN7,ADC2_IN7",ACMP1_IN3,ALT5 +GPIO_AD_B1_03,USB_OTG1_OC,TMR3_TIMER3,LPUART2_RXD,SPDIF_IN,ENET_1588_EVENT2_IN,GPIO1_IO19,USDHC2_CD_B,KPP_COL6,GPT2_CAPTURE1,FLEXIO3_D03,"ADC1_IN8,ADC2_IN8",ACMP2_IN3,ALT5 +GPIO_AD_B1_04,FLEXSPI_B_DATA3,ENET_MDC,LPUART3_CTS_B,SPDIF_SR_CLK,CSI_PIXCLK,GPIO1_IO20,USDHC2_DATA0,KPP_ROW5,GPT2_CAPTURE2,FLEXIO3_D04,"ADC1_IN9,ADC2_IN9",ACMP3_IN3,ALT5 +GPIO_AD_B1_05,FLEXSPI_B_DATA2,ENET_MDIO,LPUART3_RTS_B,SPDIF_OUT,CSI_MCLK,GPIO1_IO21,USDHC2_DATA1,KPP_COL5,GPT2_COMPARE1,FLEXIO3_D05,"ADC1_IN10,ADC2_IN10",ACMP4_IN3,ALT5 +GPIO_AD_B1_06,FLEXSPI_B_DATA1,LPI2C3_SDA,LPUART3_TXD,SPDIF_LOCK,CSI_VSYNC,GPIO1_IO22,USDHC2_DATA2,KPP_ROW4,GPT2_COMPARE2,FLEXIO3_D06,"ADC1_IN11,ADC2_IN11","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_07,FLEXSPI_B_DATA0,LPI2C3_SCL,LPUART3_RXD,SPDIF_EXT_CLK,CSI_HSYNC,GPIO1_IO23,USDHC2_DATA3,KPP_COL4,GPT2_COMPARE3,FLEXIO3_D07,"ADC1_IN12,ADC2_IN12",ACMP1_IN5,ALT5 +GPIO_AD_B1_08,FLEXSPI_A_SS1_B,FLEXPWM4_PWM0_A,FLEXCAN1_TX,CCM_PMIC_READY,CSI_DATA09,GPIO1_IO24,USDHC2_CMD,KPP_ROW3,,FLEXIO3_D08,"ADC1_IN13,ADC2_IN13",ACMP2_IN5,ALT5 +GPIO_AD_B1_09,FLEXSPI_A_DQS,FLEXPWM4_PWM1_A,FLEXCAN1_RX,SAI1_MCLK,CSI_DATA08,GPIO1_IO25,USDHC2_CLK,KPP_COL3,,FLEXIO3_D09,"ADC1_IN14,ADC2_IN14",ACMP3_IN5,ALT5 +GPIO_AD_B1_10,FLEXSPI_A_DATA3,WDOG1_B,LPUART8_TXD,SAI1_RX_SYNC,CSI_DATA07,GPIO1_IO26,USDHC2_WP,KPP_ROW2,ENET2_1588_EVENT1_OUT,FLEXIO3_D10,"ADC1_IN15,ADC2_IN15",ACMP4_IN5,ALT5 +GPIO_AD_B1_11,FLEXSPI_A_DATA2,EWM_OUT_B,LPUART8_RXD,SAI1_RX_BCLK,CSI_DATA06,GPIO1_IO27,USDHC2_RESET_B,KPP_COL2,ENET2_1588_EVENT1_IN,FLEXIO3_D11,"ADC1_IN0,ADC2_IN0",ACMP1_IN6,ALT5 +GPIO_AD_B1_12,FLEXSPI_A_DATA1,ACMP_OUT00,LPSPI3_PCS0,SAI1_RX_DATA0,CSI_DATA05,GPIO1_IO28,USDHC2_DATA4,KPP_ROW1,ENET2_1588_EVENT2_OUT,FLEXIO3_D12,ADC2_IN1,"ACMP1_OUT,ACMP2_IN6",ALT5 +GPIO_AD_B1_13,FLEXSPI_A_DATA0,ACMP_OUT01,LPSPI3_SIN,SAI1_TX_DATA0,CSI_DATA04,GPIO1_IO29,USDHC2_DATA5,KPP_COL1,ENET2_1588_EVENT2_IN,FLEXIO3_D13,ADC2_IN2,"ACMP2_OUT,ACMP3_IN6",ALT5 +GPIO_AD_B1_14,FLEXSPI_A_SCLK,ACMP_OUT02,LPSPI3_SOUT,SAI1_TX_BCLK,CSI_DATA03,GPIO1_IO30,USDHC2_DATA6,KPP_ROW0,ENET2_1588_EVENT3_OUT,FLEXIO3_D14,ADC2_IN3,"ACMP3_OUT,ACMP4_IN6",ALT5 +GPIO_AD_B1_15,FLEXSPI_A_SS0_B,AMCP_OUT03,LPSPI3_SCK,SAI1_TX_SYNC,CSI_DATA02,GPIO1_IO31,USDHC2_DATA7,KPP_COL0,ENET2_1588_EVENT3_IN,FLEXIO3_D15,ADC2_IN4,ACMP4_OUT,ALT5 +GPIO_B0_00,LCD_CLK,TMR1_TIMER0,MQS_RIGHT,LPSPI4_PCS0,FLEXIO2_D00,GPIO2_IO00,SEMC_CSX1,,ENET2_MDC,,,,ALT5 +GPIO_B0_01,LCD_ENABLE,TMR1_TIMER1,MQS_LEFT,LPSPI4_SIN,FLEXIO2_D01,GPIO2_IO01,SEMC_CSX2,,ENET2_MDIO,,,,ALT5 +GPIO_B0_02,LCD_HSYNC,TMR1_TIMER2,FLEXCAN1_TX,LPSPI4_SOUT,FLEXIO2_D02,GPIO2_IO02,SEMC_CSX3,,ENET2_1588_EVENT0_OUT,,,,ALT5 +GPIO_B0_03,LCD_VSYNC,TMR2_TIMER0,FLEXCAN1_RX,LPSPI4_SCK,FLEXIO2_D03,GPIO2_IO03,WDOG2_RESET_B_DEB,,ENET2_1588_EVENT0_IN,,,,ALT5 +GPIO_B0_04,LCD_DATA00,TMR2_TIMER1,LPI2C2_SCL,ARM_TRACE0,FLEXIO2_D04,GPIO2_IO04,SRC_BT_CFG00,,ENET2_TDATA3,,,,ALT5 +GPIO_B0_05,LCD_DATA01,TMR2_TIMER2,LPI2C2_SDA,ARM_TRACE1,FLEXIO2_D05,GPIO2_IO05,SRC_BT_CFG01,,ENET2_TDATA2,,,,ALT5 +GPIO_B0_06,LCD_DATA02,TMR3_TIMER0,FLEXPWM2_PWM0_A,ARM_TRACE2,FLEXIO2_D06,GPIO2_IO06,SRC_BT_CFG02,,ENET2_RX_CLK,,,,ALT5 +GPIO_B0_07,LCD_DATA03,TMR3_TIMER1,FLEXPWM2_PWM0_B,ARM_TRACE3,FLEXIO2_D07,GPIO2_IO07,SRC_BT_CFG03,,ENET2_TX_ER,,,,ALT5 +GPIO_B0_08,LCD_DATA04,TMR3_TIMER2,FLEXPWM2_PWM1_A,LPUART3_TXD,FLEXIO2_D08,GPIO2_IO08,SRC_BT_CFG04,,ENET2_RDATA3,,,,ALT5 +GPIO_B0_09,LCD_DATA05,TMR4_TIMER0,FLEXPWM2_PWM1_B,LPUART3_RXD,FLEXIO2_D09,GPIO2_IO09,SRC_BT_CFG05,,ENET2_RDATA2,,,,ALT5 +GPIO_B0_10,LCD_DATA06,TMR4_TIMER1,FLEXPWM2_PWM2_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",FLEXIO2_D10,GPIO2_IO10,SRC_BT_CFG06,,ENET2_CRS,,,,ALT5 +GPIO_B0_11,LCD_DATA07,TMR4_TIMER2,FLEXPWM2_PWM2_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",FLEXIO2_D11,GPIO2_IO11,SRC_BT_CFG07,,ENET2_COL,,,,ALT5 +GPIO_B0_12,LCD_DATA08,XBAR_INOUT10,ARM_TRACE_CLK,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXIO2_D12,GPIO2_IO12,SRC_BT_CFG08,,ENET2_TDATA0,,,,ALT5 +GPIO_B0_13,LCD_DATA09,XBAR_INOUT11,ARM_TRACE_SWO,SAI1_MCLK,FLEXIO2_D13,GPIO2_IO13,SRC_BT_CFG09,,ENET2_TDATA1,,,,ALT5 +GPIO_B0_14,LCD_DATA10,XBAR_INOUT12,ARM_EVENT0,SAI1_RX_SYNC,FLEXIO2_D14,GPIO2_IO14,SRC_BT_CFG10,,ENET2_TX_EN,ENET2_REF_CLK2,,,ALT5 +GPIO_B0_15,LCD_DATA11,XBAR_INOUT13,ARM_EVENT1,SAI1_RX_BCLK,FLEXIO2_D15,GPIO2_IO15,SRC_BT_CFG11,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_B1_00,LCD_DATA12,XBAR_INOUT14,LPUART4_TXD,SAI1_RX_DATA0,FLEXIO2_D16,GPIO2_IO16,FLEXPWM1_PWM3_A,,ENET2_RX_ER,FLEXIO3_D16,,,ALT5 +GPIO_B1_01,LCD_DATA13,XBAR_INOUT15,LPUART4_RXD,SAI1_TX_DATA0,FLEXIO2_D17,GPIO2_IO17,FLEXPWM1_PWM3_B,,ENET2_RDATA0,FLEXIO3_D17,,,ALT5 +GPIO_B1_02,LCD_DATA14,XBAR_INOUT16,LPSPI4_PCS2,SAI1_TX_BCLK,FLEXIO2_D18,GPIO2_IO18,FLEXPWM2_PWM3_A,,ENET2_RDATA1,FLEXIO3_D18,,,ALT5 +GPIO_B1_03,LCD_DATA15,XBAR_INOUT17,LPSPI4_PCS1,SAI1_TX_SYNC,FLEXIO2_D19,GPIO2_IO19,FLEXPWM2_PWM3_B,,ENET2_RX_EN,FLEXIO3_D19,,,ALT5 +GPIO_B1_04,LCD_DATA16,LPSPI4_PCS0,CSI_DATA15,ENET_RX_DATA0,FLEXIO2_D20,GPIO2_IO20,,,GPT1_CLK,FLEXIO3_D20,,,ALT5 +GPIO_B1_05,LCD_DATA17,LPSPI4_SIN,CSI_DATA14,ENET_RX_DATA1,FLEXIO2_D21,GPIO2_IO21,,,GPT1_CAPTURE1,FLEXIO3_D21,,,ALT5 +GPIO_B1_06,LCD_DATA18,LPSPI4_SOUT,CSI_DATA13,ENET_RX_EN,FLEXIO2_D22,GPIO2_IO22,,,GPT1_CAPTURE2,FLEXIO3_D22,,,ALT5 +GPIO_B1_07,LCD_DATA19,LPSPI4_SCK,CSI_DATA12,ENET_TX_DATA0,FLEXIO2_D23,GPIO2_IO23,,,GPT1_COMPARE1,FLEXIO3_D23,,,ALT5 +GPIO_B1_08,LCD_DATA20,TMR1_TIMER3,CSI_DATA11,ENET_TX_DATA1,FLEXIO2_D24,GPIO2_IO24,FLEXCAN2_TX,,GPT1_COMPARE2,FLEXIO3_D24,,,ALT5 +GPIO_B1_09,LCD_DATA21,TMR2_TIMER3,CSI_DATA10,ENET_TX_EN,FLEXIO2_D25,GPIO2_IO25,FLEXCAN2_RX,,GPT1_COMPARE3,FLEXIO3_D25,,,ALT5 +GPIO_B1_10,LCD_DATA22,TMR3_TIMER3,CSI_DATA00,ENET_TX_CLK,FLEXIO2_D26,GPIO2_IO26,ENET_REF_CLK,,,FLEXIO3_D26,,,ALT5 +GPIO_B1_11,LCD_DATA23,TMR4_TIMER3,CSI_DATA01,ENET_RX_ER,FLEXIO2_D27,GPIO2_IO27,LPSPI4_PCS3,,,FLEXIO3_D27,,,ALT5 +GPIO_B1_12,,LPUART5_TXD,CSI_PIXCLK,ENET_1588_EVENT0_IN,FLEXIO2_D28,GPIO2_IO28,USDHC1_CD_B,,,FLEXIO3_D28,,,ALT5 +GPIO_B1_13,WDOG1_B,LPUART5_RXD,CSI_VSYNC,ENET_1588_EVENT0_OUT,FLEXIO2_D29,GPIO2_IO29,USDHC1_WP,,,FLEXIO3_D29,,,ALT5 +GPIO_B1_14,ENET_MDC,FLEXPWM4_PWM2_A,CSI_HSYNC,XBAR_INOUT02,FLEXIO2_D30,GPIO2_IO30,USDHC1_VSELECT,,ENET2_TDATA0,FLEXIO3_D30,,,ALT5 +GPIO_B1_15,ENET_MDIO,FLEXPWM4_PWM3_A,CSI_MCLK,XBAR_INOUT03,FLEXIO2_D31,GPIO2_IO31,USDHC1_RESET_B,,ENET2_TDATA1,FLEXIO3_D31,,,ALT5 +GPIO_EMC_00,SEMC_DATA00,FLEXPWM4_PWM0_A,LPSPI2_SCK,XBAR_INOUT02,FLEXIO1_D00,GPIO4_IO0,USB_PHY1_TSTI_TX_LS_MODE,,,,,,ALT5 +GPIO_EMC_01,SEMC_DATA01,FLEXPWM4_PWM0_B,LPSPI2_PCS0,XBAR_INOUT03,FLEXIO1_D01,GPIO4_IO1,USB_PHY1_TSTI_TX_HS_MODE,JTAG_DE_B,,,,,ALT5 +GPIO_EMC_02,SEMC_DATA02,FLEXPWM4_PWM1_A,LPSPI2_SOUT,XBAR_INOUT04,FLEXIO1_D02,GPIO4_IO2,USB_PHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_03,SEMC_DATA03,FLEXPWM4_PWM1_B,LPSPI2_SIN,XBAR_INOUT05,FLEXIO1_D03,GPIO4_IO3,USB_PHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_04,SEMC_DATA04,FLEXPWM4_PWM2_A,SAI2_TX_DATA,XBAR_INOUT06,FLEXIO1_D04,GPIO4_IO4,USB_PHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_05,SEMC_DATA05,FLEXPWM4_PWM2_B,SAI2_TX_SYNC,XBAR_INOUT07,FLEXIO1_D05,GPIO4_IO5,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_06,SEMC_DATA06,FLEXPWM2_PWM0_A,SAI2_TX_BCLK,XBAR_INOUT08,FLEXIO1_D06,GPIO4_IO6,USB_PHY2_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_07,SEMC_DATA07,FLEXPWM2_PWM0_B,SAI2_MCLK,XBAR_INOUT09,FLEXIO1_D07,GPIO4_IO7,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,FLEXPWM2_PWM1_A,SAI2_RX_DATA,XBAR_INOUT17,FLEXIO1_D08,GPIO4_IO8,USB_PHY1_TSTO_RX_HS_,,,,,,ALT5 +GPIO_EMC_09,SEMC_ADDR00,FLEXPWM2_PWM1_B,SAI2_RX_SYNC,FLEXCAN2_TX,FLEXIO1_D09,GPIO4_IO9,USB_PHY1_TSTI_TX_EN,,FLEXSPI2_B_SS1_B,,,,ALT5 +GPIO_EMC_10,SEMC_ADDR01,FLEXPWM2_PWM2_A,SAI2_RX_BCLK,FLEXCAN2_RX,FLEXIO1_D10,GPIO4_IO10,USB_PHY1_TSTI_TX_HIZ,,FLEXSPI2_B_SS0_B,,,,ALT5 +GPIO_EMC_11,SEMC_ADDR02,FLEXPWM2_PWM2_B,LPI2C4_SDA,USDHC2_RESET_B,FLEXIO1_D11,GPIO4_IO11,USB_PHY2_TSTO_RX_HS_RXD,,FLEXSPI2_B_DQS,,,,ALT5 +GPIO_EMC_12,SEMC_ADDR03,XBAR_INOUT24,LPI2C4_SCL,USDHC1_WP,FLEXPWM1_PWM3_A,GPIO4_IO12,USB_PHY1_TSTO_PLL_CLK20DIV,,FLEXSPI2_B_SCLK,,,,ALT5 +GPIO_EMC_13,SEMC_ADDR04,XBAR_INOUT25,LPUART3_TXD,MQS_RIGHT,FLEXPWM1_PWM3_B,GPIO4_IO13,USB_PHY2_TSTO_PLL_CLK20DIV,,FLEXSPI2_B_DATA0,,,,ALT5 +GPIO_EMC_14,SEMC_ADDR05,XBAR_INOUT19,LPUART3_RXD,MQS_LEFT,LPSPI2_PCS1,GPIO4_IO14,USB_PHY2_TSTO_RX_SQUELCH,,FLEXSPI2_B_DATA1,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR06,XBAR_INOUT20,LPUART3_CTS_B,SPDIF_OUT,TMR3_TIMER0,GPIO4_IO15,USB_PHY2_TSTO_RX_DISCON_DET,,FLEXSPI2_B_DATA2,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR07,XBAR_INOUT21,LPUART3_RTS_B,SPDIF_IN,TMR3_TIMER1,GPIO4_IO16,,,FLEXSPI2_B_DATA3,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR08,FLEXPWM4_PWM3_A,LPUART4_CTS_B,FLEXCAN1_TX,TMR3_TIMER2,GPIO4_IO17,,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR09,FLEXPWM4_PWM3_B,LPUART4_RTS_B,FLEXCAN1_RX,TMR3_TIMER3,GPIO4_IO18,SNVS_VIO_5_CTL,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR11,FLEXPWM2_PWM3_A,LPUART4_TXD,ENET_RX_DATA1,TMR2_TIMER0,GPIO4_IO19,SNVS_VIO_5_B,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR12,FLEXPWM2_PWM3_B,LPUART4_RXD,ENET_RX_DATA0,TMR2_TIMER1,GPIO4_IO20,,,,,,,ALT5 +GPIO_EMC_21,SEMC_BA0,FLEXPWM3_PWM3_A,LPI2C3_SDA,ENET_TX_DATA1,TMR2_TIMER2,GPIO4_IO21,,,,,,,ALT5 +GPIO_EMC_22,SEMC_BA1,FLEXPWM3_PWM3_B,LPI2C3_SCL,ENET_TX_DATA0,TMR2_TIMER3,GPIO4_IO22,,,FLEXSPI2_A_SS1_B,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR10,FLEXPWM1_PWM0_A,LPUART5_TXD,ENET_RX_EN,GPT1_CAPTURE2,GPIO4_IO23,,,FLEXSPI2_A_DQS,,,,ALT5 +GPIO_EMC_24,SEMC_CAS,FLEXPWM1_PWM0_B,LPUART5_RXD,ENET_TX_EN,GPT1_CAPTURE1,GPIO4_IO24,,,FLEXSPI2_A_SS0_B,,,,ALT5 +GPIO_EMC_25,SEMC_RAS,FLEXPWM1_PWM1_A,LPUART6_TXD,ENET_TX_CLK,ENET_REF_CLK,GPIO4_IO25,,,FLEXSPI2_A_SCLK,,,,ALT5 +GPIO_EMC_26,SEMC_CLK,FLEXPWM1_PWM1_B,LPUART6_RXD,ENET_RX_ER,FLEXIO1_D12,GPIO4_IO26,,,FLEXSPI2_A_DATA0,,,,ALT5 +GPIO_EMC_27,SEMC_CKE,FLEXPWM1_PWM2_A,LPUART5_RTS_B,LPSPI1_SCK,FLEXIO1_D13,GPIO4_IO27,,,FLEXSPI2_A_DATA1,,,,ALT5 +GPIO_EMC_28,SEMC_WE,FLEXPWM1_PWM2_B,LPUART5_CTS_B,LPSPI1_SOUT,FLEXIO1_D14,GPIO4_IO28,,,FLEXSPI2_A_DATA2,,,,ALT5 +GPIO_EMC_29,SEMC_CS0,FLEXPWM3_PWM0_A,LPUART6_RTS_B,LPSPI1_SIN,FLEXIO1_D15,GPIO4_IO29,,,FLEXSPI2_A_DATA3,,,,ALT5 +GPIO_EMC_30,SEMC_DATA08,FLEXPWM3_PWM0_B,LPUART6_CTS_B,LPSPI1_PCS0,CSI_DATA23,GPIO4_IO30,,,ENET2_TDATA0,,,,ALT5 +GPIO_EMC_31,SEMC_DATA09,FLEXPWM3_PWM1_A,LPUART7_TXD,LPSPI1_PCS1,CSI_DATA22,GPIO4_IO31,,,ENET2_TDATA1,,,,ALT5 +GPIO_EMC_32,SEMC_DATA10,FLEXPWM3_PWM1_B,LPUART7_RXD,CCM_PMIC_READY,CSI_DATA21,GPIO3_IO18,,,ENET2_TX_EN,,,,ALT5 +GPIO_EMC_33,SEMC_DATA11,FLEXPWM3_PWM2_A,USDHC1_RESET_B,SAI3_RX_DATA,CSI_DATA20,GPIO3_IO19,,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_EMC_34,SEMC_DATA12,FLEXPWM3_PWM2_B,USDHC1_VSELECT,SAI3_RX_SYNC,CSI_DATA19,GPIO3_IO20,,,ENET2_RX_ER,,,,ALT5 +GPIO_EMC_35,SEMC_DATA13,XBAR_INOUT18,GPT1_COMPARE1,SAI3_RX_BCLK,CSI_DATA18,GPIO3_IO21,USDHC1_CD_B,,ENET2_RDATA0,,,,ALT5 +GPIO_EMC_36,SEMC_DATA14,XBAR_INOUT22,GPT1_COMPARE2,SAI3_TX_DATA,CSI_DATA17,GPIO3_IO22,USDHC1_WP,,ENET2_RDATA1,FLEXCAN3_TX,,,ALT5 +GPIO_EMC_37,SEMC_DATA15,XBAR_INOUT23,GPT1_COMPARE3,SAI3_MCLK,CSI_DATA16,GPIO3_IO23,USDHC2_WP,,ENET2_RX_EN,FLEXCAN3_RX,,,ALT5 +GPIO_EMC_38,SEMC_DM1,FLEXPWM1_PWM3_A,LPUART8_TXD,SAI3_TX_BCLK,CSI_FIELD,GPIO3_IO24,USDHC2_VSELECT,,ENET2_MDC,,,,ALT5 +GPIO_EMC_39,SEMC_DQS,FLEXPWM1_PWM3_B,LPUART8_RXD,SAI3_TX_SYNC,WDOG1_B,GPIO3_IO25,USDHC2_CD_B,,ENET2_MDIO,,,,ALT5 +GPIO_EMC_40,SEMC_RDY,GPT2_CAPTURE2,LPSPI1_PCS2,USB_OTG2_OC,ENET_MDC,GPIO3_IO26,USDHC2_RESET_B,,,SEMC_CLK5,,,ALT5 +GPIO_EMC_41,SEMC_CSX0,GPT2_CAPTURE1,LPSPI1_PCS3,USB_OTG2_PWR,ENET_MDIO,GPIO3_IO27,USDHC1_VSELECT,,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_CMD,FLEXPWM1_PWM0_A,LPI2C3_SCL,XBAR_INOUT04,LPSPI1_SCK,GPIO3_IO12,FLEXSPI_A_SS1_B,,ENET2_TX_EN,SEMC_DQS4,,,ALT5 +GPIO_SD_B0_01,USDHC1_CLK,FLEXPWM1_PWM0_B,LPI2C3_SDA,XBAR_INOUT05,LPSPI1_PCS0,GPIO3_IO13,FLEXSPI_B_SS1_B,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_SD_B0_02,USDHC1_DATA0,FLEXPWM1_PWM1_A,LPUART8_CTS_B,XBAR_INOUT06,LPSPI1_SOUT,GPIO3_IO14,,,ENET2_RX_ER,SEMC_CLK5,,,ALT5 +GPIO_SD_B0_03,USDHC1_DATA1,FLEXPWM1_PWM1_B,LPUART8_RTS_B,XBAR_INOUT07,LPSPI1_SIN,GPIO3_IO15,,,ENET2_RDATA0,SEMC_CLK6,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA2,FLEXPWM1_PWM2_A,LPUART8_TXD,XBAR_INOUT08,FLEXSPI_B_SS0_B,GPIO3_IO16,CCM_CLKO1,,ENET2_RDATA1,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA3,FLEXPWM1_PWM2_B,LPUART8_RXD,XBAR_INOUT09,FLEXSPI_B_DQS,GPIO3_IO17,CCM_CLKO2,,ENET2_RX_EN,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA3,FLEXSPI_B_DATA3,FLEXPWM1_PWM3_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",LPUART4_TXD,GPIO3_IO00,,,SAI3_RX_DATA,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA2,FLEXSPI_B_DATA2,FLEXPWM1_PWM3_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",LPUART4_RXD,GPIO3_IO01,,,SAI3_TX_DATA,,,,ALT5 +GPIO_SD_B1_02,USDHC2_DATA1,FLEXSPI_B_DATA1,FLEXPWM2_PWM3_A,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXCAN1_TX,GPIO3_IO02,CCM_WAIT,,SAI3_TX_SYNC,,,,ALT5 +GPIO_SD_B1_03,USDHC2_DATA0,FLEXSPI_B_DATA0,FLEXPWM2_PWM3_B,SAI1_MCLK,FLEXCAN1_RX,GPIO3_IO03,CCM_PMIC_READY,,SAI3_TX_BCLK,,,,ALT5 +GPIO_SD_B1_04,USDHC2_CLK,FLEXSPI_B_SCLK,LPI2C1_SCL,SAI1_RX_SYNC,FLEXSPI_A_SS1_B,GPIO3_IO04,CCM_STOP,,SAI3_MCLK,,,,ALT5 +GPIO_SD_B1_05,USDHC2_CMD,FLEXSPI_A_DQS,LPI2C1_SDA,SAI1_RX_BCLK,FLEXSPI_B_SS0_B,GPIO3_IO05,,,SAI3_RX_SYNC,,,,ALT5 +GPIO_SD_B1_06,USDHC2_RESET_B,FLEXSPI_A_SS0_B,LPUART7_CTS_B,SAI1_RX_DATA0,LPSPI2_PCS0,GPIO3_IO06,,,SAI3_RX_BCLK,,,,ALT5 +GPIO_SD_B1_07,SEMC_CSX1,FLEXSPI_A_SCLK,LPUART7_RTS_B,SAI1_TX_DATA0,LPSPI2_SCK,GPIO3_IO07,,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,LPUART7_TXD,SAI1_TX_BCLK,LPSPI2_SOUT,GPIO3_IO08,SEMC_CSX2,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA1,LPUART7_RXD,SAI1_TX_SYNC,LPSPI2_SIN,GPIO3_IO09,,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA2,LPUART2_RXD,LPI2C2_SDA,LPSPI2_PCS2,GPIO3_IO10,,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_DATA3,LPUART2_TXD,LPI2C2_SCL,LPSPI2_PCS3,GPIO3_IO11,,,,,,,ALT5 diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h index 7d564785797a..e3d7c6a12943 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (2 * 1024 * 1024) // Teensy 4.0 has 1 board LED -#define MICROPY_HW_LED1_PIN (GPIO_B0_03) +#define MICROPY_HW_LED1_PIN (pin_GPIO_B0_03) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) diff --git a/ports/mimxrt/boards/TEENSY40/pins.c b/ports/mimxrt/boards/TEENSY40/pins.c deleted file mode 100644 index c7bfc102d435..000000000000 --- a/ports/mimxrt/boards/TEENSY40/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "pin.h" - -static pin_af_obj_t GPIO_B0_03_af[] = { - PIN_AF(GPIO2_IO03, PIN_AF_MODE_ALT5, GPIO2, 0x10B0U), -}; - -pin_obj_t GPIO_B0_03 = PIN(GPIO_B0_03, GPIO2, 3, GPIO_B0_03_af); diff --git a/ports/mimxrt/boards/TEENSY40/pins.csv b/ports/mimxrt/boards/TEENSY40/pins.csv new file mode 100644 index 000000000000..c9d7c9856ddc --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/pins.csv @@ -0,0 +1,55 @@ +D0,GPIO_AD_B0_03 +D1,GPIO_AD_B0_02 +D2,GPIO_EMC_04 +D3,GPIO_EMC_05 +D4,GPIO_EMC_06 +D5,GPIO_EMC_08 +D6,GPIO_B0_10 +D7,GPIO_B1_01 +D8,GPIO_B1_00 +D9,GPIO_B0_11 +D10,GPIO_B0_00 +D11,GPIO_B0_02 +D12,GPIO_B0_01 +D13,GPIO_B0_03 +D14,GPIO_AD_B1_02 +D15,GPIO_AD_B1_03 +D16,GPIO_AD_B1_07 +D17,GPIO_AD_B1_06 +D18,GPIO_AD_B1_01 +D19,GPIO_AD_B1_00 +D20,GPIO_AD_B1_10 +D21,GPIO_AD_B1_11 +D22,GPIO_AD_B1_08 +D23,GPIO_AD_B1_09 +D24,GPIO_AD_B0_12 +D25,GPIO_AD_B0_13 +D26,GPIO_AD_B1_14 +D27,GPIO_AD_B1_15 +D28,GPIO_EMC_32 +D29,GPIO_EMC_31 +D30,GPIO_EMC_37 +D31,GPIO_EMC_36 +D32,GPIO_B0_12 +D33,GPIO_EMC_07 +DAT1,GPIO_AD_B0_03 +DAT0,GPIO_AD_B0_02 +CLK,GPIO_AD_B0_01 +CMD,GPIO_ASD_B0_00 +DAT3,GPIO_SD_B0_05 +DAT2,GPIO_SD_B0_04 +A0,GPIO_AD_B1_02 +A1,GPIO_AD_B1_03 +A2,GPIO_AD_B1_07 +A3,GPIO_AD_B1_06 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +A6,GPIO_AD_B1_10 +A7,GPIO_AD_B1_11 +A8,GPIO_AD_B1_08 +A9,GPIO_AD_B1_09 +A10,GPIO_AD_B0_12 +A11,GPIO_AD_B0_13 +A12,GPIO_AD_B1_14 +A13,GPIO_AD_B1_15 +LED,GPIO_B0_03 \ No newline at end of file diff --git a/ports/mimxrt/boards/TEENSY40/pins.h b/ports/mimxrt/boards/TEENSY40/pins.h deleted file mode 100644 index c0b6dcdfa957..000000000000 --- a/ports/mimxrt/boards/TEENSY40/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_B0_03; diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py new file mode 100644 index 000000000000..5e5b81e31e01 --- /dev/null +++ b/ports/mimxrt/boards/make-pins.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python +"""Creates the pin file for the MIMXRT10xx.""" + +from __future__ import print_function + +import argparse +import sys +import csv + +SUPPORTED_AFS = {"GPIO"} +MAX_AF = 10 # AF0 .. AF9 + + +def parse_pad(pad_str): + """Parses a string and returns a (port, gpio_bit) tuple.""" + if len(pad_str) < 4: + raise ValueError("Expecting pad name to be at least 4 characters") + if pad_str[:4] != "GPIO": + raise ValueError("Expecting pad name to start with GPIO") + return pad_str + + +def af_supported(af_str): + for supported_af in SUPPORTED_AFS: + if af_str.startswith(supported_af): + return True + else: + return False + + +class Pin(object): + """Holds the information associated with a pin.""" + + def __init__(self, pad, gpio, pin, idx=0): + self.idx = idx + self.name = pad + self.pad = pad + self.gpio = gpio + self.pin = pin + self.alt_fn = [] + self.adc_channel = 0 + self.board_pin = False + + def set_is_board_pin(self): + self.board_pin = True + + def is_board_pin(self): + return self.board_pin + + def parse_adc(self, adc_str): + pass + + def parse_af(self, af_idx, af_strs_in): + pass + + def add_af(self, af): + self.alt_fn.append(af) + + def print_pin_af(self): + if self.alt_fn: + print( + "static const machine_pin_af_obj_t pin_{0}_af[{1}] = {{".format( + self.name, len(self.alt_fn) + ) + ) + for af in self.alt_fn: + af.print() + print("};") + else: + raise ValueError("Pin '{}' has no alternative functions".format(self.name)) + + def print(self): + if self.alt_fn: + self.print_pin_af() + print( + "const machine_pin_obj_t pin_{0} = PIN({0}, {1}, {2}, pin_{3});\n".format( + self.name, self.gpio, int(self.pin), self.name + "_af" + ) + ) + else: + raise ValueError("Pin '{}' has no alternative functions".format(self.name)) + + def print_header(self, hdr_file): + pass + + +class AlternateFunction(object): + """Holds the information associated with a pins alternate function.""" + + def __init__(self, idx, af_str): + self.idx = idx + self.af_str = af_str + self.instance = self.af_str.split("_")[0] + + def print(self): + """Prints the C representation of this AF.""" + print( + " PIN_AF({0}, PIN_AF_MODE_ALT{1}, {2}, {3}),".format( + self.af_str, self.idx, self.instance, "0x10B0U" + ) + ) + + +class NamedPin(object): + def __init__(self, name, pad, idx): + self.name = name + self.pad = pad + self.idx = idx + + +class Pins(object): + def __init__(self): + self.cpu_pins = [] + self.board_pins = [] + + def find_pin_by_num(self, pin_num): + for pin in self.cpu_pins: + if pin.pin_num == pin_num: + return pin + + def find_pin_by_name(self, pad): + for pin in self.cpu_pins: + if pin.pad == pad: + return pin + + def parse_board_file(self, filename): + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile) + for row in rows: + pin = self.find_pin_by_name(row[1]) + if pin and row[0]: # Only add board pins that have a name + self.board_pins.append(NamedPin(row[0], pin.pad, pin.idx)) + + def parse_af_file(self, filename, pad_col, af_start_col): + af_end_col = af_start_col + MAX_AF + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile) + header = next(rows) + for idx, row in enumerate(rows): + pad = row[pad_col] + gpio, pin = row[6].split("_") + pin_number = pin.lstrip("IO") + + pin = Pin(pad, gpio, pin_number, idx=idx) + + # Parse alternate functions + af_idx = 0 + for af_idx, af in enumerate(row[af_start_col:af_end_col]): + if af and af_supported(af): + pin.add_af(AlternateFunction(af_idx, af)) + + self.cpu_pins.append(pin) + + @staticmethod + def print_named(label, pins): + print("") + print( + "STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{".format(label) + ) + for pin in pins: + print( + " {{ MP_ROM_QSTR(MP_QSTR_{}), MP_ROM_PTR(&pin_{}) }},".format(pin.name, pin.pad) + ) + print("};") + print( + "MP_DEFINE_CONST_DICT(machine_pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);".format( + label, label + ) + ) + + def print(self): + # Print Pin Object declarations + for pin in self.cpu_pins: + pin.print() + + print("") + print("const machine_pin_obj_t* machine_pin_board_pins [] = {") + for pin in self.board_pins: + print(" &pin_{},".format(pin.pad)) + print("};") + print("const uint32_t num_board_pins = {:d};".format(len(self.board_pins))) + # Print Pin mapping dictionaries + self.print_named("cpu", self.cpu_pins) + self.print_named("board", self.board_pins) + print("") + + def print_header(self, hdr_filename): + with open(hdr_filename, "w") as hdr_file: + for pin in self.cpu_pins: + hdr_file.write("extern const machine_pin_obj_t pin_{};\n".format(pin.name)) + hdr_file.write("extern const machine_pin_obj_t* machine_pin_board_pins[];\n") + hdr_file.write("extern const uint32_t num_board_pins;\n") + hdr_file.write("extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict;\n") + hdr_file.write("extern const mp_obj_dict_t machine_pin_board_pins_locals_dict;\n") + + +def main(): + parser = argparse.ArgumentParser( + prog="make-pins.py", + usage="%(prog)s [options] [command]", + description="Generate board specific pin file", + ) + parser.add_argument( + "-a", + "--af", + dest="af_filename", + help="Specifies the alternate function file for the chip", + default="mimxrt1021_af.csv", + ) + parser.add_argument( + "-b", + "--board", + dest="board_filename", + help="Specifies the board file", + default="MIMXRT1020_EVK/pins.csv", + ) + parser.add_argument( + "-p", + "--prefix", + dest="prefix_filename", + help="Specifies beginning portion of generated pins file", + default="mimxrt_prefix.c", + ) + parser.add_argument( + "-r", + "--hdr", + dest="hdr_filename", + help="Specifies name of generated pin header file", + default="build/pins.h", + ) + + pins = Pins() + + # test code + args = parser.parse_args() + # + + if args.af_filename: + print("// --af {:s}".format(args.af_filename)) + pins.parse_af_file(args.af_filename, 0, 1) + + if args.board_filename: + print("// --board {:s}".format(args.board_filename)) + pins.parse_board_file(args.board_filename) + + if args.hdr_filename: + print("// --hdr {:s}".format(args.hdr_filename)) + + if args.prefix_filename: + print("// --prefix {:s}".format(args.prefix_filename)) + with open(args.prefix_filename, "r") as prefix_file: + print(prefix_file.read()) + + pins.print() + pins.print_header(args.hdr_filename) + + +if __name__ == "__main__": + main() diff --git a/ports/mimxrt/boards/mimxrt_prefix.c b/ports/mimxrt/boards/mimxrt_prefix.c new file mode 100644 index 000000000000..59e338976e49 --- /dev/null +++ b/ports/mimxrt/boards/mimxrt_prefix.c @@ -0,0 +1,26 @@ +#include + +#include "py/obj.h" +#include "py/mphal.h" +#include "pin.h" + +#define PIN_AF(_name, _af_mode, _instance, _pad_config) \ + { \ + .base = { &machine_pin_af_type }, \ + .name = MP_QSTR_##_name, \ + .af_mode = (uint32_t)(_af_mode), \ + .instance = (void *)(_instance), \ + .pad_config = (uint32_t)(_pad_config), \ + } \ + +#define PIN(_name, _gpio, _pin, _af_list) \ + { \ + .base = { &machine_pin_type }, \ + .name = MP_QSTR_##_name, \ + .gpio = (_gpio), \ + .pin = (uint32_t)(_pin), \ + .muxRegister = (uint32_t)&(IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_##_name]), \ + .configRegister = (uint32_t)&(IOMUXC->SW_PAD_CTL_PAD[kIOMUXC_SW_PAD_CTL_PAD_##_name]), \ + .af_list_len = (size_t)(sizeof((_af_list)) / sizeof(machine_pin_af_obj_t)), \ + .af_list = (_af_list), \ + } \ diff --git a/ports/mimxrt/led.c b/ports/mimxrt/led.c index bec97dd8f7cc..cb9f9854646e 100644 --- a/ports/mimxrt/led.c +++ b/ports/mimxrt/led.c @@ -44,7 +44,7 @@ const machine_led_obj_t machine_led_obj[NUM_LEDS] = { void led_init(void) { // Turn off LEDs and initialize for (mp_int_t led = 0; led < NUM_LEDS; led++) { - const pin_obj_t *led_pin = machine_led_obj[led].led_pin; + const machine_pin_obj_t *led_pin = machine_led_obj[led].led_pin; gpio_pin_config_t pin_config = { .outputLogic = 1U, @@ -67,7 +67,7 @@ void led_state(machine_led_t led, int state) { return; } - const pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; + const machine_pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; if (state == 0) { // turn LED off @@ -83,7 +83,7 @@ void led_toggle(machine_led_t led) { return; } - const pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; + const machine_pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; mp_hal_pin_toggle(led_pin); } diff --git a/ports/mimxrt/led.h b/ports/mimxrt/led.h index 35418321d173..a0628e90eddc 100644 --- a/ports/mimxrt/led.h +++ b/ports/mimxrt/led.h @@ -42,7 +42,7 @@ typedef enum { typedef struct _machine_led_obj_t { mp_obj_base_t base; mp_uint_t led_id; - const pin_obj_t *led_pin; + const machine_pin_obj_t *led_pin; } machine_led_obj_t; void led_init(void); diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c new file mode 100644 index 000000000000..583ee4a26519 --- /dev/null +++ b/ports/mimxrt/machine_pin.c @@ -0,0 +1,273 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Philipp Ebensberger + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include + +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" + +#include "py/runtime.h" +#include "py/mphal.h" +#include "pin.h" +#include "mphalport.h" + +// Local functions +STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); + +// Class Methods +STATIC void machine_pin_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind); +STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); +STATIC mp_obj_t machine_pin_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); + +// Instance Methods +STATIC mp_obj_t machine_pin_off(mp_obj_t self_in); +STATIC mp_obj_t machine_pin_on(mp_obj_t self_in); +STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t machine_pin_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); + +// Local data +enum { + PIN_INIT_ARG_MODE = 0, + PIN_INIT_ARG_PULL, + PIN_INIT_ARG_VALUE, + PIN_INIT_ARG_DRIVE, +}; + +// Pin mapping dictionaries +const mp_obj_type_t machine_pin_cpu_pins_obj_type = { + { &mp_type_type }, + .name = MP_QSTR_cpu, + .locals_dict = (mp_obj_t)&machine_pin_cpu_pins_locals_dict, +}; + +const mp_obj_type_t machine_pin_board_pins_obj_type = { + { &mp_type_type }, + .name = MP_QSTR_board, + .locals_dict = (mp_obj_t)&machine_pin_board_pins_locals_dict, +}; + +STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + machine_pin_obj_t *self = self_in; + + if (n_args == 0) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self)); + } else { + mp_hal_pin_write(self, mp_obj_is_true(args[0])); + return mp_const_none; + } +} + +STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + static const mp_arg_t allowed_args[] = { + [PIN_INIT_ARG_MODE] { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, + [PIN_INIT_ARG_PULL] { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + [PIN_INIT_ARG_VALUE] { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + [PIN_INIT_ARG_DRIVE] { MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PIN_DRIVE_POWER_3}}, + // TODO: Implement additional arguments + /* + { MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy + { MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}},*/ + }; + + // Parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Get io mode + uint mode = args[PIN_INIT_ARG_MODE].u_int; + if (!IS_GPIO_MODE(mode)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode); + } + + // Handle configuration for GPIO + if ((mode == PIN_MODE_IN) || (mode == PIN_MODE_OUT) || (mode == PIN_MODE_OPEN_DRAIN)) { + gpio_pin_config_t pin_config; + const machine_pin_af_obj_t *af_obj; + uint32_t pad_config = 0UL; + uint8_t pull = PIN_PULL_DISABLED; + + // Generate pin configuration + if ((args[PIN_INIT_ARG_VALUE].u_obj != MP_OBJ_NULL) && (mp_obj_is_true(args[PIN_INIT_ARG_VALUE].u_obj))) { + pin_config.outputLogic = 1U; + } else { + pin_config.outputLogic = 0U; + } + pin_config.direction = mode == PIN_MODE_IN ? kGPIO_DigitalInput : kGPIO_DigitalOutput; + pin_config.interruptMode = kGPIO_NoIntmode; + + af_obj = pin_find_af(self, PIN_AF_MODE_ALT5); // GPIO is always ALT5 + if (af_obj == NULL) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("requested AF %d not available for pin %d"), PIN_AF_MODE_ALT5, mode); + } + + // Generate pad configuration + if (args[PIN_INIT_ARG_PULL].u_obj != mp_const_none) { + pull = (uint8_t)mp_obj_get_int(args[PIN_INIT_ARG_PULL].u_obj); + } + + pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Slow Slew Rate + pad_config |= IOMUXC_SW_PAD_CTL_PAD_SPEED(0b01); // medium(100MHz) + + if (mode == PIN_MODE_OPEN_DRAIN) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled + } else { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b0); // Open Drain Disabled + } + + if (pull == PIN_PULL_DISABLED) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(0); // Pull/Keeper Disabled + } else if (pull == PIN_PULL_HOLD) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled + IOMUXC_SW_PAD_CTL_PAD_PUE(0); // Keeper selected + } else { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled + IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull selected + IOMUXC_SW_PAD_CTL_PAD_PUS(pull); + } + + if (mode == PIN_MODE_IN) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(0b000) | // output driver disabled + IOMUXC_SW_PAD_CTL_PAD_HYS(1U); // Hysteresis enabled + } else { + uint drive = args[PIN_INIT_ARG_DRIVE].u_int; + if (!IS_GPIO_DRIVE(drive)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive); + } + + pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive) | + IOMUXC_SW_PAD_CTL_PAD_HYS(0U); // Hysteresis disabled + } + + // Configure PAD as GPIO + IOMUXC_SetPinMux(self->muxRegister, af_obj->af_mode, 0, 0, self->configRegister, 1U); // Software Input On Field: Input Path is determined by functionality + IOMUXC_SetPinConfig(self->muxRegister, af_obj->af_mode, 0, 0, self->configRegister, pad_config); + GPIO_PinInit(self->gpio, self->pin, &pin_config); + } + + return mp_const_none; +} + +STATIC void machine_pin_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { + (void)kind; + const machine_pin_obj_t *self = MP_OBJ_TO_PTR(o); + mp_printf(print, "Pin(%s)", qstr_str(self->name)); +} + +// pin(id, mode, pull, ...) +STATIC mp_obj_t machine_pin_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + const machine_pin_obj_t *pin = pin_find(args[0]); + + if (n_args > 1 || n_kw > 0) { + // pin mode given, so configure this GPIO + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args); + } + + return (mp_obj_t)pin; +} + +// pin.off() +STATIC mp_obj_t machine_pin_off(mp_obj_t self_in) { + machine_pin_obj_t *self = self_in; + mp_hal_pin_low(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_off_obj, machine_pin_off); + +// pin.on() +STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) { + machine_pin_obj_t *self = self_in; + mp_hal_pin_high(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on); + +// pin.value([value]) +STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { + return machine_pin_obj_call(args[0], (n_args - 1), 0, args + 1); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value); + +// pin.init(mode, pull, [kwargs]) +STATIC mp_obj_t machine_pin_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_init); + +STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_off_obj) }, + { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) }, + { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_pin_off_obj) }, + { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_on_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) }, + // class attributes + { MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&machine_pin_board_pins_obj_type) }, + { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&machine_pin_cpu_pins_obj_type) }, + // class constants + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(PIN_MODE_IN) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(PIN_MODE_OUT) }, + { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(PIN_MODE_OPEN_DRAIN) }, + + { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(PIN_PULL_UP_100K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP_47K), MP_ROM_INT(PIN_PULL_UP_47K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP_22K), MP_ROM_INT(PIN_PULL_UP_22K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(PIN_PULL_DOWN_100K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_HOLD), MP_ROM_INT(PIN_PULL_HOLD) }, + + { MP_ROM_QSTR(MP_QSTR_DRIVER_OFF), MP_ROM_INT(PIN_DRIVE_OFF) }, + { MP_ROM_QSTR(MP_QSTR_POWER_0), MP_ROM_INT(PIN_DRIVE_POWER_0) }, // R0 (150 Ohm @3.3V / 260 Ohm @ 1.8V) + { MP_ROM_QSTR(MP_QSTR_POWER_1), MP_ROM_INT(PIN_DRIVE_POWER_1) }, // R0/2 + { MP_ROM_QSTR(MP_QSTR_POWER_2), MP_ROM_INT(PIN_DRIVE_POWER_2) }, // R0/3 + { MP_ROM_QSTR(MP_QSTR_POWER_3), MP_ROM_INT(PIN_DRIVE_POWER_3) }, // R0/4 + { MP_ROM_QSTR(MP_QSTR_POWER_4), MP_ROM_INT(PIN_DRIVE_POWER_4) }, // R0/5 + { MP_ROM_QSTR(MP_QSTR_POWER_5), MP_ROM_INT(PIN_DRIVE_POWER_5) }, // R0/6 + { MP_ROM_QSTR(MP_QSTR_POWER_6), MP_ROM_INT(PIN_DRIVE_POWER_6) }, // R0/7 + +}; +STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); + +const mp_obj_type_t machine_pin_type = { + {&mp_type_type}, + .name = MP_QSTR_Pin, + .print = machine_pin_obj_print, + .call = machine_pin_obj_call, + .make_new = machine_pin_obj_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict, +}; + +// FIXME: Create actual pin_af type!!! +const mp_obj_type_t machine_pin_af_type = { + {&mp_type_type}, + .name = MP_QSTR_PinAF, + .print = machine_pin_obj_print, + .make_new = machine_pin_obj_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict, +}; diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index a6aab7b4aba5..1bb6b6a3520f 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -28,6 +28,7 @@ #include "py/runtime.h" #include "extmod/machine_mem.h" #include "led.h" +#include "pin.h" #include CPU_HEADER_H @@ -52,6 +53,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { #if NUM_LEDS { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, #endif + { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 993e15156618..a6a28ab4a585 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -29,10 +29,14 @@ #include #include "ticks.h" +#include "pin.h" +#define mp_hal_pin_obj_t const machine_pin_obj_t * #define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U)) #define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U)) +#define mp_hal_pin_write(p, value) (GPIO_PinWrite(p->gpio, p->pin, value)) #define mp_hal_pin_toggle(p) (GPIO_PortToggle(p->gpio, (1 << p->pin))) +#define mp_hal_pin_read(p) (GPIO_PinRead(p->gpio, p->pin)) void mp_hal_set_interrupt_char(int c); diff --git a/ports/mimxrt/pin.c b/ports/mimxrt/pin.c index b30f4be41cea..7a437661e386 100644 --- a/ports/mimxrt/pin.c +++ b/ports/mimxrt/pin.c @@ -24,14 +24,104 @@ * THE SOFTWARE. */ +#include "py/runtime.h" #include "pin.h" -const mp_obj_type_t pin_type = { - .base = {&mp_type_type}, - .name = MP_QSTR_Pin, -}; -const mp_obj_type_t pin_af_type = { - {&mp_type_type}, - .name = MP_QSTR_PinAF, -}; +void pin_init(void) { + return; +} + +uint32_t pin_get_mode(const machine_pin_obj_t *pin) { + uint32_t pin_mode = PIN_MODE_ALT; + uint32_t config_register = *((volatile uint32_t *)pin->configRegister); + uint8_t af_mode = pin_get_af(pin); + + if (af_mode == PIN_AF_MODE_ALT5) { + bool open_drain_enabled = (config_register & IOMUXC_SW_PAD_CTL_PAD_ODE_MASK) >> IOMUXC_SW_PAD_CTL_PAD_ODE_SHIFT; + + if (open_drain_enabled) { + pin_mode = PIN_MODE_OPEN_DRAIN; + } else { + // Check pin direction + if ((pin->gpio->GDIR & (1U << pin->pin)) >> pin->pin) { + pin_mode = PIN_MODE_OUT; + } else { + pin_mode = PIN_MODE_IN; + } + } + } + + return pin_mode; +} + +uint32_t pin_get_af(const machine_pin_obj_t *pin) { + uint32_t mux_register = *((volatile uint32_t *)pin->muxRegister); + + // Read configured AF-Mode of pin + return (uint32_t)(mux_register & IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK) >> IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT; +} + +const machine_pin_obj_t *pin_find(mp_obj_t user_obj) { + const machine_pin_obj_t *pin_obj; + + // If a pin was provided, then use it + if (mp_obj_is_type(user_obj, &machine_pin_type)) { + pin_obj = user_obj; + return pin_obj; + } + + // If pin is SMALL_INT + if (mp_obj_is_small_int(user_obj)) { + uint8_t value = MP_OBJ_SMALL_INT_VALUE(user_obj); + if (value < num_board_pins) { + return machine_pin_board_pins[value]; + } + } + + // See if the pin name matches a board pin + pin_obj = pin_find_named_pin(&machine_pin_board_pins_locals_dict, user_obj); + if (pin_obj) { + return pin_obj; + } + + // See if the pin name matches a cpu pin + pin_obj = pin_find_named_pin(&machine_pin_cpu_pins_locals_dict, user_obj); + if (pin_obj) { + return pin_obj; + } + + mp_raise_ValueError(MP_ERROR_TEXT("Pin doesn't exist")); +} + +const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { + mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); + mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP); + if (named_elem != NULL && named_elem->value != NULL) { + return named_elem->value; + } + return NULL; +} + +const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn) { + const machine_pin_af_obj_t *af_obj = NULL; + + for (int i = 0; i < pin->af_list_len; ++i) { + af_obj = &pin->af_list[i]; + if (af_obj->af_mode == fn) { + return af_obj; + } + } + + return NULL; +} + +const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx) { + // TODO: Implement pin_find_af_by_index function + return NULL; +} + +const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name) { + // TODO: Implement pin_find_af_by_name function + return NULL; +} diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index cfb1e6b57250..268b505b3856 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -27,12 +27,32 @@ #ifndef MICROPY_INCLUDED_MIMXRT_PIN_H #define MICROPY_INCLUDED_MIMXRT_PIN_H -#include "fsl_gpio.h" +#include #include "py/obj.h" +#include "fsl_gpio.h" + +// ------------------------------------------------------------------------------------------------------------------ // + +#define IS_GPIO_MODE(MODE) (((MODE) == PIN_MODE_IN) || \ + ((MODE) == PIN_MODE_OUT) || \ + ((MODE) == PIN_MODE_OPEN_DRAIN) || \ + ((MODE) == PIN_MODE_ALT)) + +#define IS_GPIO_DRIVE(DRIVE) (((DRIVE) == PIN_DRIVE_OFF) || \ + ((DRIVE) == PIN_DRIVE_POWER_0) || \ + ((DRIVE) == PIN_DRIVE_POWER_1) || \ + ((DRIVE) == PIN_DRIVE_POWER_2) || \ + ((DRIVE) == PIN_DRIVE_POWER_3) || \ + ((DRIVE) == PIN_DRIVE_POWER_4) || \ + ((DRIVE) == PIN_DRIVE_POWER_5) || \ + ((DRIVE) == PIN_DRIVE_POWER_6)) + +// ------------------------------------------------------------------------------------------------------------------ // enum { PIN_MODE_IN = 0, PIN_MODE_OUT, + PIN_MODE_OPEN_DRAIN, PIN_MODE_ALT, }; @@ -47,13 +67,38 @@ enum { PIN_AF_MODE_ALT8, }; +enum { + PIN_PULL_DOWN_100K = 0, + PIN_PULL_UP_47K, + PIN_PULL_UP_100K, + PIN_PULL_UP_22K, + PIN_PULL_DISABLED, + PIN_PULL_HOLD, +}; + +enum { + PIN_DRIVE_OFF = 0b000, + PIN_DRIVE_POWER_0, // R0 (150 Ohm @3.3V / 260 Ohm @ 1.8V) + PIN_DRIVE_POWER_1, // R0/2 + PIN_DRIVE_POWER_2, // R0/3 + PIN_DRIVE_POWER_3, // R0/4 + PIN_DRIVE_POWER_4, // R0/5 + PIN_DRIVE_POWER_5, // R0/6 + PIN_DRIVE_POWER_6, // R0/7 +}; + + + + +// ------------------------------------------------------------------------------------------------------------------ // + typedef struct { mp_obj_base_t base; qstr name; // port name - uint32_t af_mode; // alternate function + uint8_t af_mode; // alternate function void *instance; // pointer to peripheral instance for alternate function uint32_t pad_config; // pad configuration for alternate function -} pin_af_obj_t; +} machine_pin_af_obj_t; typedef struct { mp_obj_base_t base; @@ -62,39 +107,38 @@ typedef struct { uint32_t pin; // pin number uint32_t muxRegister; uint32_t configRegister; - uint32_t mode; // current pin mode - uint32_t af_mode; // current alternate function mode size_t af_list_len; // length of available alternate functions list - const pin_af_obj_t *af_list; // pointer tolist with alternate functions -} pin_obj_t; - -extern const mp_obj_type_t pin_type; -extern const mp_obj_type_t pin_af_type; - -#define PIN_AF(_name, _af_mode, _instance, _pad_config) \ - { \ - .base = { &pin_af_type }, \ - .name = MP_QSTR_##_name, \ - .af_mode = (uint32_t)(_af_mode), \ - .instance = (void *)(_instance), \ - .pad_config = (uint32_t)(_pad_config), \ - } \ - -#define PIN(_name, _gpio, _pin, _af_list) \ - { \ - .base = { &pin_type }, \ - .name = MP_QSTR_##_name, \ - .gpio = (_gpio), \ - .pin = (uint32_t)(_pin), \ - .muxRegister = (uint32_t)&(IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_##_name]), \ - .configRegister = (uint32_t)&(IOMUXC->SW_PAD_CTL_PAD[kIOMUXC_SW_PAD_CTL_PAD_##_name]), \ - .mode = PIN_MODE_IN, \ - .af_mode = PIN_AF_MODE_ALT5, \ - .af_list_len = (size_t)(sizeof((_af_list)) / sizeof(pin_af_obj_t)), \ - .af_list = (_af_list), \ - } \ + const machine_pin_af_obj_t *af_list; // pointer tolist with alternate functions +} machine_pin_obj_t; + +// ------------------------------------------------------------------------------------------------------------------ // + +extern const mp_obj_type_t machine_pin_type; +extern const mp_obj_type_t machine_pin_af_type; + +// ------------------------------------------------------------------------------------------------------------------ // // Include board specific pins -#include "pins.h" +#include "genhdr/pins.h" // pins.h must included at this location + +extern const machine_pin_obj_t *machine_pin_board_pins[]; +extern const uint32_t num_board_pins; + +extern const mp_obj_type_t machine_pin_board_pins_obj_type; +extern const mp_obj_type_t machine_pin_cpu_pins_obj_type; + +extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict; +extern const mp_obj_dict_t machine_pin_board_pins_locals_dict; + +// ------------------------------------------------------------------------------------------------------------------ // + +void pin_init(void); +uint32_t pin_get_mode(const machine_pin_obj_t *pin); +uint32_t pin_get_af(const machine_pin_obj_t *pin); +const machine_pin_obj_t *pin_find(mp_obj_t user_obj); +const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name); +const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn); +const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx); +const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name); #endif // MICROPY_INCLUDED_MIMXRT_PIN_H diff --git a/ports/mimxrt/tusb_port.c b/ports/mimxrt/tusb_port.c index 0d73b09235b6..2b1ccabbe783 100644 --- a/ports/mimxrt/tusb_port.c +++ b/ports/mimxrt/tusb_port.c @@ -76,7 +76,7 @@ static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = { static const char *const usbd_desc_str[] = { [USBD_STR_MANUF] = "MicroPython", - [USBD_STR_PRODUCT] = "Board in FS mode", + [USBD_STR_PRODUCT] = "Board in FS mode", // Todo: fix string to indicate that product is running in High Speed mode [USBD_STR_SERIAL] = "000000000000", // TODO [USBD_STR_CDC] = "Board CDC", }; From c326d9a67ba1846bba38f284fa9b8f712dd2d48a Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Sat, 24 Apr 2021 22:15:12 +0200 Subject: [PATCH 0017/4290] mimxrt: Enable built-in help. --- ports/mimxrt/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 65b91675a5de..e6b15e1b7177 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -58,6 +58,7 @@ #define MICROPY_PY_BUILTINS_FILTER (0) #define MICROPY_PY_BUILTINS_REVERSED (1) #define MICROPY_PY_BUILTINS_MIN_MAX (0) +#define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY___FILE__ (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) From 5f68f0d08ab1effd0fae8a00bdda46dbc788d9db Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Sat, 24 Apr 2021 21:34:07 +0200 Subject: [PATCH 0018/4290] github/workflows: Add CI workflow for mimxrt port. --- .github/workflows/ports_mimxrt.yml | 23 +++++++++++++++++++++++ tools/ci.sh | 13 +++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .github/workflows/ports_mimxrt.yml diff --git a/.github/workflows/ports_mimxrt.yml b/.github/workflows/ports_mimxrt.yml new file mode 100644 index 000000000000..8fbc2209e413 --- /dev/null +++ b/.github/workflows/ports_mimxrt.yml @@ -0,0 +1,23 @@ +name: mimxrt port + +on: + push: + pull_request: + paths: + - '.github/workflows/*.yml' + - 'tools/**' + - 'py/**' + - 'extmod/**' + - 'lib/**' + - 'drivers/**' + - 'ports/mimxrt/**' + +jobs: + build: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install packages + run: source tools/ci.sh && ci_mimxrt_setup + - name: Build + run: source tools/ci.sh && ci_mimxrt_build diff --git a/tools/ci.sh b/tools/ci.sh index 7b38ce0df04f..df812141f5e5 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -138,6 +138,19 @@ function ci_esp8266_build { make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_1M } +######################################################################################## +# ports/mimxrt + +function ci_mimxrt_setup { + ci_gcc_arm_setup +} + +function ci_mimxrt_build { + make ${MAKEOPTS} -C ports/mimxrt submodules + make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1020_EVK + make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 +} + ######################################################################################## # ports/nrf From c732b80f0584156b6ff98e8baa90c011539bf88a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 25 May 2021 14:49:21 +0200 Subject: [PATCH 0019/4290] mimxrt: Extend the Pin module for SoftI2C, SoftSPI support. This change consists mostly of changing and extending the required definitions in mphalport.h. --- ports/mimxrt/machine_pin.c | 14 ++++++++++++++ ports/mimxrt/mphalport.h | 14 +++++++++++++- ports/mimxrt/pin.h | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 583ee4a26519..f63778cbe517 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -68,6 +68,20 @@ const mp_obj_type_t machine_pin_board_pins_obj_type = { .locals_dict = (mp_obj_t)&machine_pin_board_pins_locals_dict, }; +// Simplified mode setting used by the extmod modules +void machine_pin_set_mode(const machine_pin_obj_t *self, uint8_t mode) { + gpio_pin_config_t pin_config = {kGPIO_DigitalInput, 1, kGPIO_NoIntmode}; + + pin_config.direction = (mode == PIN_MODE_IN ? kGPIO_DigitalInput : kGPIO_DigitalOutput); + GPIO_PinInit(self->gpio, self->pin, &pin_config); + if (mode == PIN_MODE_OPEN_DRAIN) { + uint32_t pad_config = *(uint32_t *)self->configRegister; + pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1) | IOMUXC_SW_PAD_CTL_PAD_DSE(0b110); + IOMUXC_SetPinMux(self->muxRegister, PIN_AF_MODE_ALT5, 0, 0, self->configRegister, 1U); // Software Input On Field: Input Path is determined by functionality + IOMUXC_SetPinConfig(self->muxRegister, PIN_AF_MODE_ALT5, 0, 0, self->configRegister, pad_config); + } +} + STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); machine_pin_obj_t *self = self_in; diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index a6a28ab4a585..78b390b4eb57 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -31,12 +31,22 @@ #include "ticks.h" #include "pin.h" +#define MP_HAL_PIN_FMT "%q" + #define mp_hal_pin_obj_t const machine_pin_obj_t * +#define mp_hal_get_pin_obj(o) pin_find(o) +#define mp_hal_pin_name(p) ((p)->name) +#define mp_hal_pin_input(p) machine_pin_set_mode(p, PIN_MODE_IN); +#define mp_hal_pin_output(p) machine_pin_set_mode(p, PIN_MODE_OUT); +#define mp_hal_pin_open_drain(p) machine_pin_set_mode(p, PIN_MODE_OPEN_DRAIN); #define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U)) #define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U)) #define mp_hal_pin_write(p, value) (GPIO_PinWrite(p->gpio, p->pin, value)) #define mp_hal_pin_toggle(p) (GPIO_PortToggle(p->gpio, (1 << p->pin))) -#define mp_hal_pin_read(p) (GPIO_PinRead(p->gpio, p->pin)) +#define mp_hal_pin_read(p) (GPIO_PinReadPadStatus(p->gpio, p->pin)) + +#define mp_hal_pin_od_low(p) mp_hal_pin_low(p) +#define mp_hal_pin_od_high(p) mp_hal_pin_high(p) void mp_hal_set_interrupt_char(int c); @@ -57,6 +67,8 @@ static inline void mp_hal_delay_us(mp_uint_t us) { ticks_delay_us64(us); } +#define mp_hal_delay_us_fast(us) mp_hal_delay_us(us) + static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index 268b505b3856..6afedd1f59e1 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -140,5 +140,6 @@ const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_ const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn); const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx); const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name); +void machine_pin_set_mode(const machine_pin_obj_t *pin, uint8_t mode); #endif // MICROPY_INCLUDED_MIMXRT_PIN_H From 4ee8ec6931e6a5958d2a5710c6a8f7cd7c0f3862 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:15:58 +1000 Subject: [PATCH 0020/4290] py/asmarm: Use builtin func to flush I- and D-cache on ARM 7 archs. The inline assembler code does not work for __ARM_ARCH == 7. Signed-off-by: Damien George --- py/asmarm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py/asmarm.c b/py/asmarm.c index e91421578b27..5662d75e1952 100644 --- a/py/asmarm.c +++ b/py/asmarm.c @@ -40,7 +40,7 @@ void asm_arm_end_pass(asm_arm_t *as) { if (as->base.pass == MP_ASM_PASS_EMIT) { - #if defined(__linux__) && defined(__GNUC__) + #if (defined(__linux__) && defined(__GNUC__)) || __ARM_ARCH == 7 char *start = mp_asm_base_get_code(&as->base); char *end = start + mp_asm_base_get_code_size(&as->base); __builtin___clear_cache(start, end); @@ -48,10 +48,10 @@ void asm_arm_end_pass(asm_arm_t *as) { // flush I- and D-cache asm volatile ( "0:" - "mrc p15, 0, r15, c7, c10, 3\n" + "mrc p15, 0, r15, c7, c10, 3\n" // test and clean D-cache "bne 0b\n" "mov r0, #0\n" - "mcr p15, 0, r0, c7, c7, 0\n" + "mcr p15, 0, r0, c7, c7, 0\n" // invalidate I-cache and D-cache : : : "r0", "cc"); #endif } From 2c1a6a237d4e68c077c175d16f4d76518c00e4d2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:16:06 +1000 Subject: [PATCH 0021/4290] tools/mpy-tool.py: Support relocating ARMv6 arch. Signed-off-by: Damien George --- tools/mpy-tool.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index ea756d3ee2a5..bfc3cf27e3f4 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -532,6 +532,7 @@ def _link_qstr(self, pc, kind, qst): if config.native_arch in ( MP_NATIVE_ARCH_X86, MP_NATIVE_ARCH_X64, + MP_NATIVE_ARCH_ARMV6, MP_NATIVE_ARCH_XTENSA, MP_NATIVE_ARCH_XTENSAWIN, ): From f5cba77e50c9b3ae73d01cb373ad3226247ccd7b Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:16:11 +1000 Subject: [PATCH 0022/4290] tools/tinytest-codegen.py: Add command-line option to exclude tests. Signed-off-by: Damien George --- tools/tinytest-codegen.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 116a217b4bbc..cba0b94480ba 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -108,9 +108,12 @@ def script_to_map(test_file): description="Convert native MicroPython tests to tinytest/upytesthelper C code" ) argparser.add_argument("--stdin", action="store_true", help="read list of tests from stdin") +argparser.add_argument("--exclude", action="append", help="exclude test by name") args = argparser.parse_args() if not args.stdin: + if args.exclude: + exclude_tests += tuple(args.exclude) for group in test_dirs: tests += [test for test in glob("{}/*.py".format(group)) if test not in exclude_tests] else: From b84406f3133a36a703a1506d754fc046dd955922 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:16:08 +1000 Subject: [PATCH 0023/4290] qemu-arm: Add support for Cortex-A9 via sabrelite board. Signed-off-by: Damien George --- ports/qemu-arm/Makefile | 21 ++++++++++++---- ports/qemu-arm/Makefile.test | 7 +++++- ports/qemu-arm/imx6.ld | 47 +++++++++++++++++++++++++++++++++++ ports/qemu-arm/mpconfigport.h | 11 +++++--- ports/qemu-arm/startup.c | 27 ++++++++++++++++++++ ports/qemu-arm/uart.c | 27 ++++++++++++++++++++ 6 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 ports/qemu-arm/imx6.ld diff --git a/ports/qemu-arm/Makefile b/ports/qemu-arm/Makefile index aebc5afaeb77..22d0bf39cd96 100644 --- a/ports/qemu-arm/Makefile +++ b/ports/qemu-arm/Makefile @@ -16,7 +16,8 @@ ifeq ($(BOARD),netduino2) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_STM32 LDSCRIPT = stm32.ld -SRC_BOARD_O = lib/utils/gchelper_m3.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m3.o +MPY_CROSS_FLAGS += -march=armv7m endif ifeq ($(BOARD),microbit) @@ -24,14 +25,26 @@ CFLAGS += -mthumb -mcpu=cortex-m0 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_NRF51 LDSCRIPT = nrf51.ld QEMU_EXTRA = -global nrf51-soc.flash-size=1048576 -global nrf51-soc.sram-size=262144 -SRC_BOARD_O = lib/utils/gchelper_m0.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m0.o +MPY_CROSS_FLAGS += -march=armv7m endif ifeq ($(BOARD),mps2-an385) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_MPS2 LDSCRIPT = mps2.ld -SRC_BOARD_O = lib/utils/gchelper_m3.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m3.o +MPY_CROSS_FLAGS += -march=armv7m +endif + +ifeq ($(BOARD),sabrelite) +CFLAGS += -mcpu=cortex-a9 +CFLAGS += -DQEMU_SOC_IMX6 +LDSCRIPT = imx6.ld +QEMU_EXTRA = -m 128M +SRC_BOARD_O = lib/utils/gchelper_generic.o +# It's really armv7a but closest supported value is armv6. +MPY_CROSS_FLAGS += -march=armv6 endif CROSS_COMPILE ?= arm-none-eabi- @@ -95,7 +108,6 @@ LIB_SRC_C += $(addprefix lib/,\ libm/atanf.c \ libm/atan2f.c \ libm/roundf.c \ - utils/gchelper_native.c \ utils/sys_stdio_mphal.c \ ) @@ -125,7 +137,6 @@ ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_MODULE_FROZEN_STR CFLAGS += -DMICROPY_MODULE_FROZEN_MPY CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -MPY_CROSS_FLAGS += -march=armv7m endif all: run diff --git a/ports/qemu-arm/Makefile.test b/ports/qemu-arm/Makefile.test index 6b7f1dc7ab46..b4ad6114b804 100644 --- a/ports/qemu-arm/Makefile.test +++ b/ports/qemu-arm/Makefile.test @@ -4,6 +4,11 @@ FROZEN_MANIFEST ?= "freeze('test-frzmpy')" include Makefile +ifeq ($(BOARD),sabrelite) +# These don't work on Cortex-A9. +TESTS_EXCLUDE = inlineasm/asmdiv.py inlineasm/asmspecialregs.py +endif + CFLAGS += -DTEST .PHONY: $(BUILD)/genhdr/tests.h @@ -11,7 +16,7 @@ CFLAGS += -DTEST $(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h $(BUILD)/genhdr/tests.h: (cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp) - $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@ + $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ $(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING diff --git a/ports/qemu-arm/imx6.ld b/ports/qemu-arm/imx6.ld new file mode 100644 index 000000000000..7155956f15ad --- /dev/null +++ b/ports/qemu-arm/imx6.ld @@ -0,0 +1,47 @@ +/* Vector table is at 0x00000000, entry point is 0x10000000. */ + +MEMORY +{ + ROM : ORIGIN = 0x00000000, LENGTH = 96K + RAM : ORIGIN = 0x10000000, LENGTH = 128M +} + +_estack = ORIGIN(RAM) + LENGTH(RAM); + +SECTIONS +{ + .rom : { + . = ALIGN(4); + KEEP(*(.isr_vector)) + . = ALIGN(4); + } > ROM + + .text : { + . = ALIGN(4); + *(.text.Reset_Handler) + *(.text*) + *(.rodata*) + . = ALIGN(4); + _etext = .; + _sidata = _etext; + } > RAM + + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; + *(.data*) + . = ALIGN(4); + _edata = .; + } > RAM + + .bss : + { + . = ALIGN(4); + _sbss = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } > RAM +} diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index 498ab3ed2cfa..1f05719caad9 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -3,9 +3,16 @@ // options to control how MicroPython is built #define MICROPY_ALLOC_PATH_MAX (512) -#define MICROPY_EMIT_X64 (0) + +#if defined(__ARM_ARCH_ISA_ARM) +#define MICROPY_EMIT_ARM (1) +#define MICROPY_EMIT_INLINE_THUMB (1) +#elif defined(__ARM_ARCH_ISA_THUMB) #define MICROPY_EMIT_THUMB (1) #define MICROPY_EMIT_INLINE_THUMB (1) +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) +#endif + #define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) #define MICROPY_MEM_STATS (1) #define MICROPY_DEBUG_PRINTERS (0) @@ -43,8 +50,6 @@ // type definitions for the specific machine -#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) - #define MP_SSIZE_MAX (0x7fffffff) #define UINT_FMT "%lu" diff --git a/ports/qemu-arm/startup.c b/ports/qemu-arm/startup.c index 58bdf7af9e98..a52b068c332a 100644 --- a/ports/qemu-arm/startup.c +++ b/ports/qemu-arm/startup.c @@ -28,6 +28,27 @@ void Default_Handler(void) { } } +#if defined(__ARM_ARCH_ISA_ARM) + +// ARM architecture with standard ARM ISA. + +__attribute__((naked, section(".isr_vector"))) void isr_vector(void) { + __asm volatile ( + "b Reset_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "nop\n" + "b Default_Handler\n" + "b Default_Handler\n" + ); +} + +#elif defined(__ARM_ARCH_ISA_THUMB) + +// ARM architecture with Thumb-only ISA. + const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { (uint32_t)&_estack, (uint32_t)&Reset_Handler, @@ -47,6 +68,8 @@ const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { (uint32_t)&Default_Handler, // SysTick_Handler }; +#endif + void _start(void) { // Enable the UART uart_init(); @@ -68,7 +91,11 @@ __attribute__((naked)) void exit(int status) { "ldr r1, =0x20026\n" // ADP_Stopped_ApplicationExit, a clean exit ".notclean:\n" "movs r0, #0x18\n" // SYS_EXIT + #if defined(__ARM_ARCH_ISA_ARM) + "svc 0x00123456\n" + #elif defined(__ARM_ARCH_ISA_THUMB) "bkpt 0xab\n" + #endif ); for (;;) { } diff --git a/ports/qemu-arm/uart.c b/ports/qemu-arm/uart.c index 8710e9e9f681..828398cd175a 100644 --- a/ports/qemu-arm/uart.c +++ b/ports/qemu-arm/uart.c @@ -75,4 +75,31 @@ void uart_tx_strn(const char *buf, size_t len) { } } +#elif defined(QEMU_SOC_IMX6) + +#define UART_UCR1_UARTEN (1 << 0) +#define UART_UCR2_TXEN (1 << 2) + +typedef struct _UART_t { + volatile uint32_t URXD; // 0x00 + volatile uint32_t r0[15]; + volatile uint32_t UTXD; // 0x40 + volatile uint32_t r1[15]; + volatile uint32_t UCR1; // 0x80 + volatile uint32_t UCR2; // 0x84 +} UART_t; + +#define UART1 ((UART_t *)(0x02020000)) + +void uart_init(void) { + UART1->UCR1 = UART_UCR1_UARTEN; + UART1->UCR2 = UART_UCR2_TXEN; +} + +void uart_tx_strn(const char *buf, size_t len) { + for (size_t i = 0; i < len; ++i) { + UART1->UTXD = buf[i]; + } +} + #endif From e7c0a8bca31063c295afdaf8e49c8ab24b70a90d Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:14:56 +1000 Subject: [PATCH 0024/4290] tools/ci.sh: Build Cortex-A9 sabrelite board as part of qemu-arm CI. Signed-off-by: Damien George --- tools/ci.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/ci.sh b/tools/ci.sh index df812141f5e5..c986c9fef80b 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -194,6 +194,8 @@ function ci_qemu_arm_build { make ${MAKEOPTS} -C ports/qemu-arm CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 make ${MAKEOPTS} -C ports/qemu-arm clean make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test clean + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test BOARD=sabrelite test } ######################################################################################## From dc86e044761a132ddd7026f0f9555f958ba8046a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 20 May 2021 10:02:57 +1000 Subject: [PATCH 0025/4290] tests: Make float and framebuf tests skip or run on big-endian archs. Signed-off-by: Damien George --- tests/extmod/framebuf16.py | 7 ++++++- tests/extmod/framebuf_subclass.py | 7 ++++++- ...ytearray_construct.py => bytearray_construct_endian.py} | 0 .../{bytes_construct.py => bytes_construct_endian.py} | 2 +- tests/float/float_array.py | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) rename tests/float/{bytearray_construct.py => bytearray_construct_endian.py} (100%) rename tests/float/{bytes_construct.py => bytes_construct_endian.py} (77%) diff --git a/tests/extmod/framebuf16.py b/tests/extmod/framebuf16.py index e658f1345ad1..cd7f5ec01583 100644 --- a/tests/extmod/framebuf16.py +++ b/tests/extmod/framebuf16.py @@ -1,9 +1,14 @@ try: - import framebuf + import framebuf, usys except ImportError: print("SKIP") raise SystemExit +# This test and its .exp file is based on a little-endian architecture. +if usys.byteorder != "little": + print("SKIP") + raise SystemExit + def printbuf(): print("--8<--") diff --git a/tests/extmod/framebuf_subclass.py b/tests/extmod/framebuf_subclass.py index aad5d2a1e96b..a9e3c5efc791 100644 --- a/tests/extmod/framebuf_subclass.py +++ b/tests/extmod/framebuf_subclass.py @@ -1,11 +1,16 @@ # test subclassing framebuf.FrameBuffer try: - import framebuf + import framebuf, usys except ImportError: print("SKIP") raise SystemExit +# This test and its .exp file is based on a little-endian architecture. +if usys.byteorder != "little": + print("SKIP") + raise SystemExit + class FB(framebuf.FrameBuffer): def __init__(self, n): diff --git a/tests/float/bytearray_construct.py b/tests/float/bytearray_construct_endian.py similarity index 100% rename from tests/float/bytearray_construct.py rename to tests/float/bytearray_construct_endian.py diff --git a/tests/float/bytes_construct.py b/tests/float/bytes_construct_endian.py similarity index 77% rename from tests/float/bytes_construct.py rename to tests/float/bytes_construct_endian.py index 0806087b0ef0..208f56162f85 100644 --- a/tests/float/bytes_construct.py +++ b/tests/float/bytes_construct_endian.py @@ -1,4 +1,4 @@ -# test construction of bytearray from array with float type +# test construction of bytes from array with float type try: from uarray import array diff --git a/tests/float/float_array.py b/tests/float/float_array.py index 3c2189869b93..219b6b86aef2 100644 --- a/tests/float/float_array.py +++ b/tests/float/float_array.py @@ -22,4 +22,4 @@ def test(a): test(array("f")) test(array("d")) -print("{:.4f}".format(array("f", b"\xcc\xcc\xcc=")[0])) +print("{:.4f}".format(array("f", bytes(array("I", [0x3DCCCCCC])))[0])) From ef16834887de02cbddf414b560e5a2af9cae4b16 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 18 May 2021 13:20:02 +1000 Subject: [PATCH 0026/4290] github/workflows: Add workflow to build and run unix port on MIPS. This adds a coverage build and running of the test suite on a MIPS 32-bit big endian architecture. It uses the feature of qemu to execute foreign code as though it were native to the system (using qemu user mode). The code compiled for MIPS will run under the qemu VM, but all syscalls made by this code go to the host (Linux) system. See related #7268 and #7273. Signed-off-by: Damien George --- .github/workflows/ports_unix.yml | 14 ++++++++++++++ tools/ci.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index aa4b8abdc989..5c4a4f3047a5 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -186,3 +186,17 @@ jobs: - name: Print failures if: failure() run: tests/run-tests.py --print-failures + + qemu_mips: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install packages + run: source tools/ci.sh && ci_unix_qemu_mips_setup + - name: Build + run: source tools/ci.sh && ci_unix_qemu_mips_build + - name: Run main test suite + run: source tools/ci.sh && ci_unix_qemu_mips_run_tests + - name: Print failures + if: failure() + run: tests/run-tests.py --print-failures diff --git a/tools/ci.sh b/tools/ci.sh index c986c9fef80b..23e529e5e119 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -292,6 +292,13 @@ CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS=( CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" ) +CI_UNIX_OPTS_QEMU_MIPS=( + CROSS_COMPILE=mips-linux-gnu- + VARIANT=coverage + MICROPY_STANDALONE=1 + LDFLAGS_EXTRA="-static" +) + function ci_unix_build_helper { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix "$@" submodules @@ -478,6 +485,26 @@ function ci_unix_macos_run_tests { (cd tests && ./run-tests.py --exclude 'uasyncio_(basic|heaplock|lock|wait_task)' --exclude 'import_pkg7.py' --exclude 'urandom_basic.py') } +function ci_unix_qemu_mips_setup { + sudo apt-get update + sudo apt-get install gcc-mips-linux-gnu g++-mips-linux-gnu + sudo apt-get install qemu-user + qemu-mips --version +} + +function ci_unix_qemu_mips_build { + # qemu-mips on GitHub Actions will seg-fault if not linked statically + ci_unix_build_helper "${CI_UNIX_OPTS_QEMU_MIPS[@]}" +} + +function ci_unix_qemu_mips_run_tests { + # Issues with MIPS tests: + # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) + # - ffi tests do not work + file ./ports/unix/micropython-coverage + (cd tests && MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') +} + ######################################################################################## # ports/windows From 0abf6f830cd390e2e5dbd4a2c68f611f5c9507dc Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 26 May 2021 16:57:39 +1000 Subject: [PATCH 0027/4290] esp8266/boards/GENERIC_512K: Add custom manifest without FS modules. The 512k build does not have a filesystem so there is no reason to include the filesystem-related modules. This commit provides a custom manifest.py for this board which no longer includes: _boot.py, flashbdev.py, inisetup.py, upip.py, upip_utarfile.py. This cuts the build down by about 9k of flash. Signed-off-by: Damien George --- ports/esp8266/boards/GENERIC_512K/manifest.py | 4 ++++ ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 ports/esp8266/boards/GENERIC_512K/manifest.py diff --git a/ports/esp8266/boards/GENERIC_512K/manifest.py b/ports/esp8266/boards/GENERIC_512K/manifest.py new file mode 100644 index 000000000000..e7ab8ad535b6 --- /dev/null +++ b/ports/esp8266/boards/GENERIC_512K/manifest.py @@ -0,0 +1,4 @@ +freeze("$(PORT_DIR)/modules", ("apa102.py", "neopixel.py", "ntptime.py", "port_diag.py")) +freeze("$(MPY_DIR)/drivers/dht", "dht.py") +freeze("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/extmod/webrepl/manifest.py") diff --git a/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk b/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk index a7566f9f19ec..120351909bc0 100644 --- a/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk +++ b/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk @@ -1 +1,3 @@ LD_FILES = boards/esp8266_512k.ld + +FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py From 6a127810c03d7666f1866f5e48df3c102805dbe8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 16:48:29 +1000 Subject: [PATCH 0028/4290] extmod/moduhashlib: Put hash obj in final state after digest is called. If digest is called then the hash object is put in a "final" state and calling update() or digest() again will raise a ValueError (instead of silently producing the wrong result). See issue #4119. Signed-off-by: Damien George --- extmod/moduhashlib.c | 33 +++++++++++++++++++++++++++- tests/extmod/uhashlib_final.py | 35 ++++++++++++++++++++++++++++++ tests/extmod/uhashlib_final.py.exp | 1 + 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/extmod/uhashlib_final.py create mode 100644 tests/extmod/uhashlib_final.py.exp diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 195a24334b69..b170de9e58e1 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -60,9 +60,16 @@ typedef struct _mp_obj_hash_t { mp_obj_base_t base; - char state[0]; + bool final; // if set, update and digest raise an exception + uintptr_t state[0]; // must be aligned to a machine word } mp_obj_hash_t; +static void uhashlib_ensure_not_final(mp_obj_hash_t *self) { + if (self->final) { + mp_raise_ValueError(MP_ERROR_TEXT("hash is final")); + } +} + #if MICROPY_PY_UHASHLIB_SHA256 STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); @@ -78,6 +85,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); o->base.type = type; + o->final = false; mbedtls_sha256_init((mbedtls_sha256_context *)&o->state); mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0); if (n_args == 1) { @@ -88,6 +96,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len); @@ -96,6 +105,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, 32); mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf); @@ -110,6 +121,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); o->base.type = type; + o->final = false; sha256_init((CRYAL_SHA256_CTX *)o->state); if (n_args == 1) { uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); @@ -119,6 +131,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len); @@ -127,6 +140,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, SHA256_BLOCK_SIZE); sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf); @@ -160,6 +175,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); o->base.type = type; + o->final = false; SHA1_Init((SHA1_CTX *)o->state); if (n_args == 1) { uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); @@ -169,6 +185,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len); @@ -177,6 +194,8 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, SHA1_SIZE); SHA1_Final((byte *)vstr.buf, (SHA1_CTX *)self->state); @@ -196,6 +215,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context)); o->base.type = type; + o->final = false; mbedtls_sha1_init((mbedtls_sha1_context *)o->state); mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state); if (n_args == 1) { @@ -206,6 +226,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len); @@ -214,6 +235,8 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, 20); mbedtls_sha1_finish_ret((mbedtls_sha1_context *)self->state, (byte *)vstr.buf); @@ -247,6 +270,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX)); o->base.type = type; + o->final = false; MD5_Init((MD5_CTX *)o->state); if (n_args == 1) { uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]); @@ -256,6 +280,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len); @@ -264,6 +289,8 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, MD5_SIZE); MD5_Final((byte *)vstr.buf, (MD5_CTX *)self->state); @@ -283,6 +310,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context)); o->base.type = type; + o->final = false; mbedtls_md5_init((mbedtls_md5_context *)o->state); mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state); if (n_args == 1) { @@ -293,6 +321,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len); @@ -301,6 +330,8 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, 16); mbedtls_md5_finish_ret((mbedtls_md5_context *)self->state, (byte *)vstr.buf); diff --git a/tests/extmod/uhashlib_final.py b/tests/extmod/uhashlib_final.py new file mode 100644 index 000000000000..f562cc17807e --- /dev/null +++ b/tests/extmod/uhashlib_final.py @@ -0,0 +1,35 @@ +try: + import uhashlib +except ImportError: + print("SKIP") + raise SystemExit + + +for algo_name in ("md5", "sha1", "sha256"): + algo = getattr(uhashlib, algo_name, None) + if not algo: + continue + + # Running .digest() several times in row is not supported. + h = algo(b"123") + h.digest() + try: + h.digest() + print("fail") + except ValueError: + # Expected path, don't print anything so test output is the + # same even if the algorithm is not implemented on the port. + pass + + # Partial digests are not supported. + h = algo(b"123") + h.digest() + try: + h.update(b"456") + print("fail") + except ValueError: + # Expected path, don't print anything so test output is the + # same even if the algorithm is not implemented on the port. + pass + +print("done") diff --git a/tests/extmod/uhashlib_final.py.exp b/tests/extmod/uhashlib_final.py.exp new file mode 100644 index 000000000000..19f86f493ab1 --- /dev/null +++ b/tests/extmod/uhashlib_final.py.exp @@ -0,0 +1 @@ +done From 62f75376dd6932a694569e2b7a8701b3a6b13a77 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 26 May 2021 22:37:27 +1000 Subject: [PATCH 0029/4290] stm32/boards/NUCLEO_L432KC: Fix FS size and enable LFS1 filesystem. Signed-off-by: Damien George --- ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h | 2 +- ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk | 1 + ports/stm32/boards/stm32l432.ld | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h index 0a3ac1f185a7..0f1134491f97 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h @@ -13,13 +13,13 @@ #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UTIMEQ (0) -#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_ADC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (0) // requires a custom USB connector on PA11/PA12 #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_FLASH (1) // MSI is used and is 4MHz #define MICROPY_HW_CLK_PLLM (1) diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk index 6e220a4370db..a87b4710e74a 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk @@ -6,6 +6,7 @@ OPENOCD_CONFIG = boards/openocd_stm32l4.cfg # MicroPython settings MICROPY_VFS_FAT = 0 +MICROPY_VFS_LFS1 ?= 1 # Don't include default frozen modules because MCU is tight on flash space FROZEN_MANIFEST ?= diff --git a/ports/stm32/boards/stm32l432.ld b/ports/stm32/boards/stm32l432.ld index 4699543d6691..469e834f91c1 100644 --- a/ports/stm32/boards/stm32l432.ld +++ b/ports/stm32/boards/stm32l432.ld @@ -6,7 +6,7 @@ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 230K /* sectors 0-114 */ - FLASH_FS (r) : ORIGIN = 0x08060000, LENGTH = 26K /* sectors 115-127 */ + FLASH_FS (r) : ORIGIN = 0x08039800, LENGTH = 26K /* sectors 115-127 */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* SRAM1, 48K + SRAM2, 16K */ } From 211c3e41f12295f08a883ac326386ecb5bc8d68e Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 27 May 2021 23:57:51 +1000 Subject: [PATCH 0030/4290] stm32/boards/PYBD_SF2: Disable GCC 11 warnings for array bounds. With GCC 11 there is now a warning about array bounds of OTP-mac, due to the OTP being a literal address. Signed-off-by: Damien George --- ports/stm32/boards/PYBD_SF2/board_init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/stm32/boards/PYBD_SF2/board_init.c b/ports/stm32/boards/PYBD_SF2/board_init.c index d1a0a09e7a47..c3b54fa2f101 100644 --- a/ports/stm32/boards/PYBD_SF2/board_init.c +++ b/ports/stm32/boards/PYBD_SF2/board_init.c @@ -64,7 +64,15 @@ void board_sleep(int value) { void mp_hal_get_mac(int idx, uint8_t buf[6]) { // Check if OTP region has a valid MAC address, and use it if it does if (OTP->series == 0x00d1 && OTP->mac[0] == 'H' && OTP->mac[1] == 'J' && OTP->mac[2] == '0') { + #if __GNUC__ >= 11 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #pragma GCC diagnostic ignored "-Wstringop-overread" + #endif memcpy(buf, OTP->mac, 6); + #if __GNUC__ >= 11 + #pragma GCC diagnostic pop + #endif buf[5] += idx; return; } From db8704ecbd910e598fba4bc1817acf91d9da79e3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 28 May 2021 00:09:34 +1000 Subject: [PATCH 0031/4290] esp8266,esp32: Update manifest to point to new dirs in micropython-lib. Following a refactoring of micropython-lib. Signed-off-by: Damien George --- ports/esp32/boards/manifest_release.py | 9 +++++---- ports/esp8266/boards/GENERIC/manifest.py | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ports/esp32/boards/manifest_release.py b/ports/esp32/boards/manifest_release.py index b5c7cd111b10..8b9bcde6ffa7 100644 --- a/ports/esp32/boards/manifest_release.py +++ b/ports/esp32/boards/manifest_release.py @@ -1,6 +1,7 @@ include("manifest.py") -freeze("$(MPY_LIB_DIR)/upysh", "upysh.py") -freeze("$(MPY_LIB_DIR)/urequests", "urequests.py") -freeze("$(MPY_LIB_DIR)/umqtt.simple", "umqtt/simple.py") -freeze("$(MPY_LIB_DIR)/umqtt.robust", "umqtt/robust.py") +freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") + +freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") diff --git a/ports/esp8266/boards/GENERIC/manifest.py b/ports/esp8266/boards/GENERIC/manifest.py index 46f3b837be07..9ce3ffe3aae1 100644 --- a/ports/esp8266/boards/GENERIC/manifest.py +++ b/ports/esp8266/boards/GENERIC/manifest.py @@ -10,12 +10,12 @@ # Libraries from micropython-lib, include only if the library directory exists if os.path.isdir(convert_path("$(MPY_LIB_DIR)")): # file utilities - freeze("$(MPY_LIB_DIR)/upysh", "upysh.py") + freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") # requests - freeze("$(MPY_LIB_DIR)/urequests", "urequests.py") - freeze("$(MPY_LIB_DIR)/urllib.urequest", "urllib/urequest.py") + freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") + freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py") # umqtt - freeze("$(MPY_LIB_DIR)/umqtt.simple", "umqtt/simple.py") - freeze("$(MPY_LIB_DIR)/umqtt.robust", "umqtt/robust.py") + freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") + freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") From 4982d0920ebd247758aa6321bb36a5eede0bd775 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 May 2021 11:04:01 +1000 Subject: [PATCH 0032/4290] tools/pyboard.py: Track raw REPL state via in_raw_repl variable. Signed-off-by: Damien George --- tools/pyboard.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/pyboard.py b/tools/pyboard.py index 29a15f7eae25..220c010937d7 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -255,6 +255,7 @@ class Pyboard: def __init__( self, device, baudrate=115200, user="micro", password="python", wait=0, exclusive=True ): + self.in_raw_repl = False self.use_raw_paste = True if device.startswith("exec:"): self.serial = ProcessToSerial(device[len("exec:") :]) @@ -348,8 +349,11 @@ def enter_raw_repl(self): print(data) raise PyboardError("could not enter raw repl") + self.in_raw_repl = True + def exit_raw_repl(self): self.serial.write(b"\r\x02") # ctrl-B: enter friendly REPL + self.in_raw_repl = False def follow(self, timeout, data_consumer=None): # wait for normal output From e4ba57c5cd6f68306726891c45f36b5129b633ec Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 May 2021 11:21:19 +1000 Subject: [PATCH 0033/4290] tools/pyboard.py: Add "soft_reset" option to Pyboard.enter_raw_repl(). Signed-off-by: Damien George --- tools/pyboard.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 220c010937d7..7d06aa847d7a 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -322,7 +322,7 @@ def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None): time.sleep(0.01) return data - def enter_raw_repl(self): + def enter_raw_repl(self, soft_reset=True): self.serial.write(b"\r\x03\x03") # ctrl-C twice: interrupt any running program # flush input (without relying on serial.flushInput()) @@ -332,18 +332,23 @@ def enter_raw_repl(self): n = self.serial.inWaiting() self.serial.write(b"\r\x01") # ctrl-A: enter raw REPL - data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n>") - if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"): - print(data) - raise PyboardError("could not enter raw repl") - self.serial.write(b"\x04") # ctrl-D: soft reset - data = self.read_until(1, b"soft reboot\r\n") - if not data.endswith(b"soft reboot\r\n"): - print(data) - raise PyboardError("could not enter raw repl") - # By splitting this into 2 reads, it allows boot.py to print stuff, - # which will show up after the soft reboot and before the raw REPL. + if soft_reset: + data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n>") + if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"): + print(data) + raise PyboardError("could not enter raw repl") + + self.serial.write(b"\x04") # ctrl-D: soft reset + + # Waiting for "soft reboot" independently to "raw REPL" (done below) + # allows boot.py to print, which will show up after "soft reboot" + # and before "raw REPL". + data = self.read_until(1, b"soft reboot\r\n") + if not data.endswith(b"soft reboot\r\n"): + print(data) + raise PyboardError("could not enter raw repl") + data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n") if not data.endswith(b"raw REPL; CTRL-B to exit\r\n"): print(data) From a60ad3364132b9c4a30b20cd91fd5cd1ac965618 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 May 2021 17:12:54 +1000 Subject: [PATCH 0034/4290] tools/mpremote: Add new CLI utility to interact with remote device. This has been under development since April 2017. See #3034 and #6375. Signed-off-by: Damien George --- tools/mpremote/LICENSE | 21 + tools/mpremote/README.md | 71 +++ tools/mpremote/mpremote.py | 6 + tools/mpremote/mpremote/__init__.py | 1 + tools/mpremote/mpremote/console.py | 162 ++++++ tools/mpremote/mpremote/main.py | 477 ++++++++++++++++ tools/mpremote/mpremote/pyboardextended.py | 621 +++++++++++++++++++++ tools/mpremote/pyproject.toml | 6 + tools/mpremote/setup.cfg | 25 + 9 files changed, 1390 insertions(+) create mode 100644 tools/mpremote/LICENSE create mode 100644 tools/mpremote/README.md create mode 100755 tools/mpremote/mpremote.py create mode 100644 tools/mpremote/mpremote/__init__.py create mode 100644 tools/mpremote/mpremote/console.py create mode 100644 tools/mpremote/mpremote/main.py create mode 100644 tools/mpremote/mpremote/pyboardextended.py create mode 100644 tools/mpremote/pyproject.toml create mode 100644 tools/mpremote/setup.cfg diff --git a/tools/mpremote/LICENSE b/tools/mpremote/LICENSE new file mode 100644 index 000000000000..5ec904cca10b --- /dev/null +++ b/tools/mpremote/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2021 Damien P. George + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tools/mpremote/README.md b/tools/mpremote/README.md new file mode 100644 index 000000000000..a6aaa1755df5 --- /dev/null +++ b/tools/mpremote/README.md @@ -0,0 +1,71 @@ +# mpremote -- MicroPython remote control + +This CLI tool provides an integrated set of utilities to remotely interact with +and automate a MicroPython device over a serial connection. + +The simplest way to use this tool is: + + mpremote + +This will automatically connect to the device and provide an interactive REPL. + +The full list of supported commands are: + + mpremote connect -- connect to given device + device may be: list, auto, id:x, port:x + or any valid device name/path + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run -- run the given local script + mpremote fs -- execute filesystem commands on the device + command may be: cat, ls, cp, rm, mkdir, rmdir + use ":" as a prefix to specify a file on the device + mpremote repl -- enter REPL + options: + --capture + --inject-code + --inject-file + +Multiple commands can be specified and they will be run sequentially. Connection +and disconnection will be done automatically at the start and end of the execution +of the tool, if such commands are not explicitly given. Automatic connection will +search for the first available serial device. If no action is specified then the +REPL will be entered. + +Shortcuts can be defined using the macro system. Built-in shortcuts are: + +- a0, a1, a2, a3: connect to `/dev/ttyACM?` +- u0, u1, u2, u3: connect to `/dev/ttyUSB?` +- c0, c1, c2, c3: connect to `COM?` +- cat, ls, cp, rm, mkdir, rmdir, df: filesystem commands +- reset: reset the device +- bootloader: make the device enter its bootloader + +Any user configuration, including user-defined shortcuts, can be placed in +.config/mpremote/config.py. For example: + + # Custom macro commands + commands = { + "c33": "connect id:334D335C3138", + "bl": "bootloader", + "double x=4": "eval x*2", + } + +Examples: + + mpremote + mpremote a1 + mpremote connect /dev/ttyUSB0 repl + mpremote ls + mpremote a1 ls + mpremote exec "import micropython; micropython.mem_info()" + mpremote eval 1/2 eval 3/4 + mpremote mount . + mpremote mount . exec "import local_script" + mpremote ls + mpremote cat boot.py + mpremote cp :main.py . + mpremote cp main.py : + mpremote cp -r dir/ : diff --git a/tools/mpremote/mpremote.py b/tools/mpremote/mpremote.py new file mode 100755 index 000000000000..a91ff67b15da --- /dev/null +++ b/tools/mpremote/mpremote.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import sys +from mpremote import main + +sys.exit(main.main()) diff --git a/tools/mpremote/mpremote/__init__.py b/tools/mpremote/mpremote/__init__.py new file mode 100644 index 000000000000..1bb8bf6d7fd4 --- /dev/null +++ b/tools/mpremote/mpremote/__init__.py @@ -0,0 +1 @@ +# empty diff --git a/tools/mpremote/mpremote/console.py b/tools/mpremote/mpremote/console.py new file mode 100644 index 000000000000..646bbfa22e88 --- /dev/null +++ b/tools/mpremote/mpremote/console.py @@ -0,0 +1,162 @@ +import sys + +try: + import select, termios +except ImportError: + termios = None + select = None + import msvcrt + + +class ConsolePosix: + def __init__(self): + self.infd = sys.stdin.fileno() + self.infile = sys.stdin.buffer.raw + self.outfile = sys.stdout.buffer.raw + self.orig_attr = termios.tcgetattr(self.infd) + + def enter(self): + # attr is: [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] + attr = termios.tcgetattr(self.infd) + attr[0] &= ~( + termios.BRKINT | termios.ICRNL | termios.INPCK | termios.ISTRIP | termios.IXON + ) + attr[1] = 0 + attr[2] = attr[2] & ~(termios.CSIZE | termios.PARENB) | termios.CS8 + attr[3] = 0 + attr[6][termios.VMIN] = 1 + attr[6][termios.VTIME] = 0 + termios.tcsetattr(self.infd, termios.TCSANOW, attr) + + def exit(self): + termios.tcsetattr(self.infd, termios.TCSANOW, self.orig_attr) + + def waitchar(self): + # TODO pyb.serial might not have fd + select.select([console_in.infd, pyb.serial.fd], [], []) + + def readchar(self): + res = select.select([self.infd], [], [], 0) + if res[0]: + return self.infile.read(1) + else: + return None + + def write(self, buf): + self.outfile.write(buf) + + +class ConsoleWindows: + KEY_MAP = { + b"H": b"A", # UP + b"P": b"B", # DOWN + b"M": b"C", # RIGHT + b"K": b"D", # LEFT + b"G": b"H", # POS1 + b"O": b"F", # END + b"Q": b"6~", # PGDN + b"I": b"5~", # PGUP + b"s": b"1;5D", # CTRL-LEFT, + b"t": b"1;5C", # CTRL-RIGHT, + b"\x8d": b"1;5A", # CTRL-UP, + b"\x91": b"1;5B", # CTRL-DOWN, + b"w": b"1;5H", # CTRL-POS1 + b"u": b"1;5F", # CTRL-END + b"\x98": b"1;3A", # ALT-UP, + b"\xa0": b"1;3B", # ALT-DOWN, + b"\x9d": b"1;3C", # ALT-RIGHT, + b"\x9b": b"1;3D", # ALT-LEFT, + b"\x97": b"1;3H", # ALT-POS1, + b"\x9f": b"1;3F", # ALT-END, + b"S": b"3~", # DEL, + b"\x93": b"3;5~", # CTRL-DEL + b"R": b"2~", # INS + b"\x92": b"2;5~", # CTRL-INS + b"\x94": b"Z", # Ctrl-Tab = BACKTAB, + } + + def enter(self): + pass + + def exit(self): + pass + + def inWaiting(self): + return 1 if msvcrt.kbhit() else 0 + + def waitchar(self): + while not (self.inWaiting() or pyb.serial.inWaiting()): + time.sleep(0.01) + + def readchar(self): + if msvcrt.kbhit(): + ch = msvcrt.getch() + while ch in b"\x00\xe0": # arrow or function key prefix? + if not msvcrt.kbhit(): + return None + ch = msvcrt.getch() # second call returns the actual key code + try: + ch = b"\x1b[" + self.KEY_MAP[ch] + except KeyError: + return None + return ch + + def write(self, buf): + buf = buf.decode() if isinstance(buf, bytes) else buf + sys.stdout.write(buf) + sys.stdout.flush() + # for b in buf: + # if isinstance(b, bytes): + # msvcrt.putch(b) + # else: + # msvcrt.putwch(b) + + +if termios: + Console = ConsolePosix + VT_ENABLED = True +else: + Console = ConsoleWindows + + # Windows VT mode ( >= win10 only) + # https://bugs.python.org/msg291732 + import ctypes + from ctypes import wintypes + + kernel32 = ctypes.WinDLL("kernel32", use_last_error=True) + + ERROR_INVALID_PARAMETER = 0x0057 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + + def _check_bool(result, func, args): + if not result: + raise ctypes.WinError(ctypes.get_last_error()) + return args + + LPDWORD = ctypes.POINTER(wintypes.DWORD) + kernel32.GetConsoleMode.errcheck = _check_bool + kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, LPDWORD) + kernel32.SetConsoleMode.errcheck = _check_bool + kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD) + + def set_conout_mode(new_mode, mask=0xFFFFFFFF): + # don't assume StandardOutput is a console. + # open CONOUT$ instead + fdout = os.open("CONOUT$", os.O_RDWR) + try: + hout = msvcrt.get_osfhandle(fdout) + old_mode = wintypes.DWORD() + kernel32.GetConsoleMode(hout, ctypes.byref(old_mode)) + mode = (new_mode & mask) | (old_mode.value & ~mask) + kernel32.SetConsoleMode(hout, mode) + return old_mode.value + finally: + os.close(fdout) + + # def enable_vt_mode(): + mode = mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING + try: + set_conout_mode(mode, mask) + VT_ENABLED = True + except WindowsError as e: + VT_ENABLED = False diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py new file mode 100644 index 000000000000..1ce00305eb52 --- /dev/null +++ b/tools/mpremote/mpremote/main.py @@ -0,0 +1,477 @@ +""" +MicroPython Remote - Interaction and automation tool for MicroPython +MIT license; Copyright (c) 2019-2021 Damien P. George + +This program provides a set of utilities to interact with and automate a +MicroPython device over a serial connection. Commands supported are: + + mpremote -- auto-detect, connect and enter REPL + mpremote -- connect to given device + mpremote connect -- connect to given device + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run \r +""" + ) + cl.close() + def setup_conn(port, accept_handler): global listen_s @@ -25,34 +104,41 @@ def setup_conn(port, accept_handler): for i in (network.AP_IF, network.STA_IF): iface = network.WLAN(i) if iface.active(): - print("WebREPL daemon started on ws://%s:%d" % (iface.ifconfig()[0], port)) + print("WebREPL server started on http://%s:%d/" % (iface.ifconfig()[0], port)) return listen_s def accept_conn(listen_sock): global client_s cl, remote_addr = listen_sock.accept() - prev = uos.dupterm(None) - uos.dupterm(prev) + + if not server_handshake(cl): + send_html(cl) + return False + + prev = os.dupterm(None) + os.dupterm(prev) if prev: print("\nConcurrent WebREPL connection from", remote_addr, "rejected") cl.close() - return + return False print("\nWebREPL connection from:", remote_addr) client_s = cl - websocket_helper.server_handshake(cl) - ws = uwebsocket.websocket(cl, True) + + ws = websocket.websocket(cl, True) ws = _webrepl._webrepl(ws) cl.setblocking(False) # notify REPL on socket incoming data (ESP32/ESP8266-only) - if hasattr(uos, "dupterm_notify"): - cl.setsockopt(socket.SOL_SOCKET, 20, uos.dupterm_notify) - uos.dupterm(ws) + if hasattr(os, "dupterm_notify"): + cl.setsockopt(socket.SOL_SOCKET, 20, os.dupterm_notify) + os.dupterm(ws) + + return True def stop(): global listen_s, client_s - uos.dupterm(None) + os.dupterm(None) if client_s: client_s.close() if listen_s: @@ -60,6 +146,7 @@ def stop(): def start(port=8266, password=None, accept_handler=accept_conn): + global static_host stop() webrepl_pass = password if webrepl_pass is None: @@ -67,6 +154,8 @@ def start(port=8266, password=None, accept_handler=accept_conn): import webrepl_cfg webrepl_pass = webrepl_cfg.PASS + if hasattr(webrepl_cfg, "BASE"): + static_host = webrepl_cfg.BASE except: print("WebREPL is not configured, run 'import webrepl_setup'") @@ -75,7 +164,9 @@ def start(port=8266, password=None, accept_handler=accept_conn): if accept_handler is None: print("Starting webrepl in foreground mode") - accept_conn(s) + # Run accept_conn to serve HTML until we get a websocket connection. + while not accept_conn(s): + pass elif password is None: print("Started webrepl in normal mode") else: diff --git a/extmod/webrepl/webrepl_setup.py b/extmod/webrepl/webrepl_setup.py index ffc9c77fc0de..16e5f76e655e 100644 --- a/extmod/webrepl/webrepl_setup.py +++ b/extmod/webrepl/webrepl_setup.py @@ -1,6 +1,5 @@ import sys -# import uos as os import os import machine diff --git a/extmod/webrepl/websocket_helper.py b/extmod/webrepl/websocket_helper.py deleted file mode 100644 index 3260acc52f37..000000000000 --- a/extmod/webrepl/websocket_helper.py +++ /dev/null @@ -1,85 +0,0 @@ -try: - import usys as sys -except ImportError: - import sys - -try: - import ubinascii as binascii -except: - import binascii -try: - import uhashlib as hashlib -except: - import hashlib - -DEBUG = 0 - - -def server_handshake(sock): - clr = sock.makefile("rwb", 0) - l = clr.readline() - # sys.stdout.write(repr(l)) - - webkey = None - - while 1: - l = clr.readline() - if not l: - raise OSError("EOF in headers") - if l == b"\r\n": - break - # sys.stdout.write(l) - h, v = [x.strip() for x in l.split(b":", 1)] - if DEBUG: - print((h, v)) - if h == b"Sec-WebSocket-Key": - webkey = v - - if not webkey: - raise OSError("Not a websocket request") - - if DEBUG: - print("Sec-WebSocket-Key:", webkey, len(webkey)) - - d = hashlib.sha1(webkey) - d.update(b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11") - respkey = d.digest() - respkey = binascii.b2a_base64(respkey)[:-1] - if DEBUG: - print("respkey:", respkey) - - sock.send( - b"""\ -HTTP/1.1 101 Switching Protocols\r -Upgrade: websocket\r -Connection: Upgrade\r -Sec-WebSocket-Accept: """ - ) - sock.send(respkey) - sock.send("\r\n\r\n") - - -# Very simplified client handshake, works for MicroPython's -# websocket server implementation, but probably not for other -# servers. -def client_handshake(sock): - cl = sock.makefile("rwb", 0) - cl.write( - b"""\ -GET / HTTP/1.1\r -Host: echo.websocket.org\r -Connection: Upgrade\r -Upgrade: websocket\r -Sec-WebSocket-Key: foo\r -\r -""" - ) - l = cl.readline() - # print(l) - while 1: - l = cl.readline() - if l == b"\r\n": - break - - -# sys.stdout.write(l) From f736afb577f91cee2a53a22ea17b61755e3f44fc Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Sun, 17 Jul 2022 08:43:33 +1000 Subject: [PATCH 1528/4290] drivers,ports: Fix a few typos in comments. Fixes: - Should read `definitions` rather than `defintions`. - Should read `resolution` rather than `resoultion`. - Should read `inefficient` rather than `inefficent`. - Should read `closed` rather than `closded`. Signed-off-by: Tim Gates --- drivers/cc3000/src/evnt_handler.c | 2 +- ports/mimxrt/hal/flexspi_flash_config.h | 4 ++-- ports/stm32/adc.c | 6 +++--- ports/teensy/core/pins_teensy.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/cc3000/src/evnt_handler.c b/drivers/cc3000/src/evnt_handler.c index 80f34e469b24..d430bbfdad55 100644 --- a/drivers/cc3000/src/evnt_handler.c +++ b/drivers/cc3000/src/evnt_handler.c @@ -604,7 +604,7 @@ INT32 hci_unsol_event_handler(CHAR *event_hdr) { //data[0] represents the socket id, for which FIN was received by remote. //Upon receiving this event, the user can close the socket, or else the - //socket will be closded after inacvitity timeout (by default 60 seconds) + //socket will be closed after inacvitity timeout (by default 60 seconds) tSLInformation.sWlanCB(event_type, data, 1); } } diff --git a/ports/mimxrt/hal/flexspi_flash_config.h b/ports/mimxrt/hal/flexspi_flash_config.h index 3c21eb609a77..80526880be0b 100644 --- a/ports/mimxrt/hal/flexspi_flash_config.h +++ b/ports/mimxrt/hal/flexspi_flash_config.h @@ -18,7 +18,7 @@ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ -/* FLEXSPI memory config block related defintions */ +/* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) @@ -26,7 +26,7 @@ /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 -/* Lookup table related defintions */ +/* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index fcc7d51e4527..9b7788e59e33 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -50,7 +50,7 @@ /// val = adc.read_core_vbat() # read MCU VBAT /// val = adc.read_core_vref() # read MCU VREF -/* ADC defintions */ +/* ADC definitions */ #define ADCx (ADC1) #define PIN_ADC_MASK PIN_ADC1 #define pin_adc_table pin_adc1 @@ -171,8 +171,8 @@ #define EOC_TIMEOUT (10) /* Core temperature sensor definitions */ -#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */ -#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */ +#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resolution) */ +#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resolution) */ // scale and calibration values for VBAT and VREF #define ADC_SCALE (ADC_SCALE_V / ((1 << ADC_CAL_BITS) - 1)) diff --git a/ports/teensy/core/pins_teensy.c b/ports/teensy/core/pins_teensy.c index b28f94a9ecb0..5817121fad38 100644 --- a/ports/teensy/core/pins_teensy.c +++ b/ports/teensy/core/pins_teensy.c @@ -181,7 +181,7 @@ void portb_isr(void) void portc_isr(void) { - // TODO: these are inefficent. Use CLZ somehow.... + // TODO: these are inefficient. Use CLZ somehow.... uint32_t isfr = PORTC_ISFR; PORTC_ISFR = isfr; if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9](); From fa15aed0f718562871288aa174e91507a134db28 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Fri, 22 Jul 2022 17:28:30 +0100 Subject: [PATCH 1529/4290] docs/library/neopixel: Add note that neopixel is included in rp2 builds. --- docs/library/neopixel.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/neopixel.rst b/docs/library/neopixel.rst index 1b37f088baa7..bc3b4e68a40e 100644 --- a/docs/library/neopixel.rst +++ b/docs/library/neopixel.rst @@ -6,7 +6,7 @@ This module provides a driver for WS2818 / NeoPixel LEDs. -.. note:: This module is only included by default on the ESP8266 and ESP32 +.. note:: This module is only included by default on the ESP8266, ESP32 and RP2 ports. On STM32 / Pyboard, you can `download the module `_ and copy it to the filesystem. From 1e87b56219c69306d77a887cac3d29146180f113 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Mon, 4 Jul 2022 17:35:46 +1000 Subject: [PATCH 1530/4290] py/obj: Add support for __float__ and __complex__ functions. --- py/obj.c | 15 +++++-- py/objcomplex.c | 4 ++ py/objtype.c | 6 +++ py/runtime.c | 9 ++++ py/runtime0.h | 2 + .../types_float_implicit_conversion.py | 14 +++++++ tests/float/complex_dunder.py | 40 ++++++++++++++++++ tests/float/float_dunder.py | 42 +++++++++++++++++++ tests/run-tests.py | 1 + 9 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 tests/cpydiff/types_float_implicit_conversion.py create mode 100644 tests/float/complex_dunder.py create mode 100644 tests/float/float_dunder.py diff --git a/py/obj.c b/py/obj.c index 51f6d85defb7..5a05ea58c5dd 100644 --- a/py/obj.c +++ b/py/obj.c @@ -355,9 +355,13 @@ bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) { } else if (mp_obj_is_float(arg)) { val = mp_obj_float_get(arg); } else { - return false; + arg = mp_unary_op(MP_UNARY_OP_FLOAT_MAYBE, (mp_obj_t)arg); + if (arg != MP_OBJ_NULL && mp_obj_is_float(arg)) { + val = mp_obj_float_get(arg); + } else { + return false; + } } - *value = val; return true; } @@ -399,7 +403,12 @@ bool mp_obj_get_complex_maybe(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) } else if (mp_obj_is_type(arg, &mp_type_complex)) { mp_obj_complex_get(arg, real, imag); } else { - return false; + arg = mp_unary_op(MP_UNARY_OP_COMPLEX_MAYBE, (mp_obj_t)arg); + if (arg != MP_OBJ_NULL && mp_obj_is_type(arg, &mp_type_complex)) { + mp_obj_complex_get(arg, real, imag); + } else { + return false; + } } return true; } diff --git a/py/objcomplex.c b/py/objcomplex.c index 157617e15677..3c4cb6614098 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -88,6 +88,10 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, si // a complex, just return it return args[0]; } else { + mp_float_t real, imag; + if (mp_obj_get_complex_maybe(args[0], &real, &imag)) { + return mp_obj_new_complex(real, imag); + } // something else, try to cast it to a complex return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } diff --git a/py/objtype.c b/py/objtype.c index 37c1e3bd22d3..fe1918bd3731 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -378,6 +378,12 @@ const byte mp_unary_op_method_name[MP_UNARY_OP_NUM_RUNTIME] = { [MP_UNARY_OP_INVERT] = MP_QSTR___invert__, [MP_UNARY_OP_ABS] = MP_QSTR___abs__, #endif + #if MICROPY_PY_BUILTINS_FLOAT + [MP_UNARY_OP_FLOAT_MAYBE] = MP_QSTR___float__, + #if MICROPY_PY_BUILTINS_COMPLEX + [MP_UNARY_OP_COMPLEX_MAYBE] = MP_QSTR___complex__, + #endif + #endif #if MICROPY_PY_SYS_GETSIZEOF [MP_UNARY_OP_SIZEOF] = MP_QSTR___sizeof__, #endif diff --git a/py/runtime.c b/py/runtime.c index e6d8c68070e5..2c3b3ddde4a4 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -319,6 +319,15 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { // if arg==mp_const_none. return mp_const_true; } + #if MICROPY_PY_BUILTINS_FLOAT + if (op == MP_UNARY_OP_FLOAT_MAYBE + #if MICROPY_PY_BUILTINS_COMPLEX + || op == MP_UNARY_OP_COMPLEX_MAYBE + #endif + ) { + return MP_OBJ_NULL; + } + #endif // With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int(). // In this case provide a more focused error message to not confuse, e.g. chr(1.0) #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE diff --git a/py/runtime0.h b/py/runtime0.h index e6eeff97d686..c82a4717f451 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -76,6 +76,8 @@ typedef enum { MP_UNARY_OP_HASH, // __hash__; must return a small int MP_UNARY_OP_ABS, // __abs__ MP_UNARY_OP_INT, // __int__ + MP_UNARY_OP_FLOAT_MAYBE, // __float__ + MP_UNARY_OP_COMPLEX_MAYBE, // __complex__ MP_UNARY_OP_SIZEOF, // for sys.getsizeof() } mp_unary_op_t; diff --git a/tests/cpydiff/types_float_implicit_conversion.py b/tests/cpydiff/types_float_implicit_conversion.py new file mode 100644 index 000000000000..8d39a7cd4109 --- /dev/null +++ b/tests/cpydiff/types_float_implicit_conversion.py @@ -0,0 +1,14 @@ +""" +categories: Types,float +description: uPy allows implicit conversion of objects in maths operations while CPython does not. +cause: Unknown +workaround: Objects should be wrapped in `float(obj)` for compatibility with CPython. +""" + + +class Test: + def __float__(self): + return 0.5 + + +print(2.0 * Test()) diff --git a/tests/float/complex_dunder.py b/tests/float/complex_dunder.py new file mode 100644 index 000000000000..128dc69293e2 --- /dev/null +++ b/tests/float/complex_dunder.py @@ -0,0 +1,40 @@ +# test __complex__ function support + + +class TestComplex: + def __complex__(self): + return 1j + 10 + + +class TestStrComplex: + def __complex__(self): + return "a" + + +class TestNonComplex: + def __complex__(self): + return 6 + + +class Test: + pass + + +print(complex(TestComplex())) + +try: + print(complex(TestStrComplex())) +except TypeError: + print("TypeError") + + +try: + print(complex(TestNonComplex())) +except TypeError: + print("TypeError") + + +try: + print(complex(Test())) +except TypeError: + print("TypeError") diff --git a/tests/float/float_dunder.py b/tests/float/float_dunder.py new file mode 100644 index 000000000000..1cd03db524a7 --- /dev/null +++ b/tests/float/float_dunder.py @@ -0,0 +1,42 @@ +# test __float__ function support + + +class TestFloat: + def __float__(self): + return 10.0 + + +class TestStrFloat: + def __float__(self): + return "a" + + +class TestNonFloat: + def __float__(self): + return 6 + + +class Test: + pass + + +print("%.1f" % float(TestFloat())) +print("%.1f" % TestFloat()) + + +try: + print(float(TestStrFloat())) +except TypeError: + print("TypeError") + + +try: + print(float(TestNonFloat())) +except TypeError: + print("TypeError") + + +try: + print(float(Test())) +except TypeError: + print("TypeError") diff --git a/tests/run-tests.py b/tests/run-tests.py index 2d6dbaaf1cd8..baab7bdd4a90 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -525,6 +525,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add("float/int_big_float.py") skip_tests.add("float/true_value.py") skip_tests.add("float/types.py") + skip_tests.add("float/complex_dunder.py") if not has_coverage: skip_tests.add("cmdline/cmd_parsetree.py") From 4fe3e493b1a62381db15b724f77d565ff2666120 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 25 Jul 2022 15:23:48 +1000 Subject: [PATCH 1531/4290] py/obj: Make mp_obj_get_complex_maybe call mp_obj_get_float_maybe first. This commit simplifies mp_obj_get_complex_maybe() by first calling mp_obj_get_float_maybe() to handle the cases corresponding to floats. Only if that fails does it attempt to extra a full complex number. This reduces code size and also means that mp_obj_get_complex_maybe() now supports user-defined classes defining __float__; in particular this allows user-defined classes to be used as arguments to cmath-module function. Furthermore, complex_make_new() can now be simplified to directly call mp_obj_get_complex(), instead of mp_obj_get_complex_maybe() followed by mp_obj_get_float(). This also improves error messages from complex with an invalid argument, it now raises "can't convert to complex" rather than "can't convert to float". Signed-off-by: Damien George --- py/obj.c | 17 +---------------- py/objcomplex.c | 7 ++----- tests/float/cmath_dunder.py | 21 +++++++++++++++++++++ tests/float/complex_dunder.py | 6 ++++++ tests/float/math_dunder.py | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 tests/float/cmath_dunder.py create mode 100644 tests/float/math_dunder.py diff --git a/py/obj.c b/py/obj.c index 5a05ea58c5dd..b461fe50aa25 100644 --- a/py/obj.c +++ b/py/obj.c @@ -383,22 +383,7 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { #if MICROPY_PY_BUILTINS_COMPLEX bool mp_obj_get_complex_maybe(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { - if (arg == mp_const_false) { - *real = 0; - *imag = 0; - } else if (arg == mp_const_true) { - *real = 1; - *imag = 0; - } else if (mp_obj_is_small_int(arg)) { - *real = (mp_float_t)MP_OBJ_SMALL_INT_VALUE(arg); - *imag = 0; - #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - } else if (mp_obj_is_exact_type(arg, &mp_type_int)) { - *real = mp_obj_int_as_float_impl(arg); - *imag = 0; - #endif - } else if (mp_obj_is_float(arg)) { - *real = mp_obj_float_get(arg); + if (mp_obj_get_float_maybe(arg, real)) { *imag = 0; } else if (mp_obj_is_type(arg, &mp_type_complex)) { mp_obj_complex_get(arg, real, imag); diff --git a/py/objcomplex.c b/py/objcomplex.c index 3c4cb6614098..4aa598a0bcb7 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -89,11 +89,8 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, si return args[0]; } else { mp_float_t real, imag; - if (mp_obj_get_complex_maybe(args[0], &real, &imag)) { - return mp_obj_new_complex(real, imag); - } - // something else, try to cast it to a complex - return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); + mp_obj_get_complex(args[0], &real, &imag); + return mp_obj_new_complex(real, imag); } case 2: diff --git a/tests/float/cmath_dunder.py b/tests/float/cmath_dunder.py new file mode 100644 index 000000000000..3526341510e9 --- /dev/null +++ b/tests/float/cmath_dunder.py @@ -0,0 +1,21 @@ +# test that cmath functions support user classes with __float__ and __complex__ + +try: + import cmath +except ImportError: + print("SKIP") + raise SystemExit + + +class TestFloat: + def __float__(self): + return 1.0 + + +class TestComplex: + def __complex__(self): + return 1j + 10 + + +for clas in TestFloat, TestComplex: + print("%.5g" % cmath.phase(clas())) diff --git a/tests/float/complex_dunder.py b/tests/float/complex_dunder.py index 128dc69293e2..975d829b47f3 100644 --- a/tests/float/complex_dunder.py +++ b/tests/float/complex_dunder.py @@ -1,6 +1,11 @@ # test __complex__ function support +class TestFloat: + def __float__(self): + return 1.0 + + class TestComplex: def __complex__(self): return 1j + 10 @@ -20,6 +25,7 @@ class Test: pass +print(complex(TestFloat())) print(complex(TestComplex())) try: diff --git a/tests/float/math_dunder.py b/tests/float/math_dunder.py new file mode 100644 index 000000000000..33ea7f7c1c10 --- /dev/null +++ b/tests/float/math_dunder.py @@ -0,0 +1,15 @@ +# test that math functions support user classes with __float__ + +try: + import math +except ImportError: + print("SKIP") + raise SystemExit + + +class TestFloat: + def __float__(self): + return 1.0 + + +print("%.5g" % math.exp(TestFloat())) From 9fd8250d6962d016942ac48e0d20767124bcd732 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 21 Jul 2022 12:04:19 +0100 Subject: [PATCH 1532/4290] lib/cyw43-driver: Update driver to latest version. This version of the driver adds an event hook to call during firmware download, and the ability to query the current power mode. --- lib/cyw43-driver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cyw43-driver b/lib/cyw43-driver index 5614e2750e01..2ab6ca93f9cd 160000 --- a/lib/cyw43-driver +++ b/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit 5614e2750e019b0ffa14a50e3c92045b952e2634 +Subproject commit 2ab6ca93f9cd044bc6f35c1403b1284e4161294a From 33d6994d4c5855228ae423f2d77fb2549db9f854 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 14 Jul 2022 18:11:34 +0100 Subject: [PATCH 1533/4290] rp2/cyw43_configport: Set CYW43_EVENT_POLL_HOOK value. This should allow USB to work while we're loading WiFi firmware. Fixes issue #8904. --- ports/rp2/cyw43_configport.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/rp2/cyw43_configport.h b/ports/rp2/cyw43_configport.h index 6173964cb2be..aeb220b202b1 100644 --- a/ports/rp2/cyw43_configport.h +++ b/ports/rp2/cyw43_configport.h @@ -95,4 +95,6 @@ static inline void cyw43_delay_ms(uint32_t ms) { } } +#define CYW43_EVENT_POLL_HOOK MICROPY_EVENT_POLL_HOOK_FAST + #endif // MICROPY_INCLUDED_RP2_CYW43_CONFIGPORT_H From f64862a766bf7c22feb1de75dadc69fb9e1aed4a Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 26 Jul 2022 01:37:03 +1000 Subject: [PATCH 1534/4290] rp2/cyw43_configport: Set CYW43_WIFI_NVRAM_INCLUDE_FILE value. Required for latest cyw43-driver. Signed-off-by: Damien George --- ports/rp2/cyw43_configport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/rp2/cyw43_configport.h b/ports/rp2/cyw43_configport.h index aeb220b202b1..b6f5b3cad8a7 100644 --- a/ports/rp2/cyw43_configport.h +++ b/ports/rp2/cyw43_configport.h @@ -32,6 +32,7 @@ #include "py/mphal.h" #include "pendsv.h" +#define CYW43_WIFI_NVRAM_INCLUDE_FILE "wifi_nvram_43439.h" #define CYW43_IOCTL_TIMEOUT_US (1000000) #define CYW43_SLEEP_MAX (10) #define CYW43_NETUTILS (1) From 0c45a28d24e1a7f9ea5912c928d7b5a860a6514a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 24 Jul 2022 09:15:38 +0200 Subject: [PATCH 1535/4290] rp2/rp2_pio: Fix StateMachine.restart when PIO program is shared. The state machines were not properly restarted in the case that the same PIO program was shared among multiple StateMachine instances. This is because only the first StateMachine to use the program would set the rp2_state_machine_initial_pc variable. See https://forum.micropython.org/viewtopic.php?f=21&t=12776&p=69464#p69464 --- ports/rp2/rp2_pio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index 072644eba6ac..eb85eb22480d 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -469,8 +469,8 @@ STATIC mp_obj_t rp2_state_machine_init_helper(const rp2_state_machine_obj_t *sel if (offset < 0) { rp2_pio_add_program(&rp2_pio_obj[PIO_NUM(self->pio)], args[ARG_prog].u_obj); offset = mp_obj_get_int(prog[PROG_OFFSET_PIO0 + PIO_NUM(self->pio)]); - rp2_state_machine_initial_pc[self->id] = offset; } + rp2_state_machine_initial_pc[self->id] = offset; // Compute the clock divider. uint16_t clkdiv_int; From c0fa903d6b2ed5131ae60f8faff2c6ad5276b3a2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 26 Jul 2022 12:24:50 +1000 Subject: [PATCH 1536/4290] py/compile: Support large integers in inline-asm data directive. Fixes issue #8956. Signed-off-by: Damien George --- py/compile.c | 5 +++-- tests/inlineasm/asmdata.py | 16 ++++++++++++++++ tests/inlineasm/asmdata.py.exp | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/inlineasm/asmdata.py create mode 100644 tests/inlineasm/asmdata.py.exp diff --git a/py/compile.c b/py/compile.c index ff3e5ffc6db3..8aaf88532749 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3286,12 +3286,13 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind if (pass > MP_PASS_SCOPE) { mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]); for (uint j = 1; j < n_args; j++) { - if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) { + mp_obj_t int_obj; + if (!mp_parse_node_get_int_maybe(pn_arg[j], &int_obj)) { compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("'data' requires integer arguments")); return; } mp_asm_base_data((mp_asm_base_t *)comp->emit_inline_asm, - bytesize, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[j])); + bytesize, mp_obj_int_get_truncated(int_obj)); } } } else { diff --git a/tests/inlineasm/asmdata.py b/tests/inlineasm/asmdata.py new file mode 100644 index 000000000000..bbd20c9186a4 --- /dev/null +++ b/tests/inlineasm/asmdata.py @@ -0,0 +1,16 @@ +# test the "data" directive + + +@micropython.asm_thumb +def ret_num(r0) -> uint: + lsl(r0, r0, 2) + mov(r1, pc) + add(r0, r0, r1) + ldr(r0, [r0, 4]) + b(HERE) + data(4, 0x12345678, 0x20000000, 0x40000000, 0x7FFFFFFF + 1, (1 << 32) - 2) + label(HERE) + + +for i in range(5): + print(hex(ret_num(i))) diff --git a/tests/inlineasm/asmdata.py.exp b/tests/inlineasm/asmdata.py.exp new file mode 100644 index 000000000000..502c04f99314 --- /dev/null +++ b/tests/inlineasm/asmdata.py.exp @@ -0,0 +1,5 @@ +0x12345678 +0x20000000 +0x40000000 +0x80000000 +0xfffffffe From e65d1e69e88268145ff0e7e73240f028885915be Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 22 Jul 2022 13:53:13 +1000 Subject: [PATCH 1537/4290] py/modio: Remove FileIO and TextIOWrapper from io module. On ports with more than one filesystem, the type will be wrong, for example if using LFS but FAT enabled, then the type will be FAT. So it's not possible to use these classes to identify a file object type. Furthermore, constructing an io.FileIO currently crashes on FAT, and make_new isn't supported on LFS. And the io.TextIOWrapper class does not match CPython at all. Signed-off-by: Jim Mussared --- extmod/vfs.c | 2 +- extmod/vfs_fat_file.c | 127 +++++++++++++++----------------------- extmod/vfs_posix.c | 2 +- extmod/vfs_posix_file.c | 19 +----- py/modio.c | 9 --- tests/extmod/vfs_posix.py | 4 +- 6 files changed, 58 insertions(+), 105 deletions(-) diff --git a/extmod/vfs.c b/extmod/vfs.c index 2799622b389b..be1a82d40447 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -312,7 +312,7 @@ mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) #if MICROPY_VFS_POSIX // If the file is an integer then delegate straight to the POSIX handler if (mp_obj_is_small_int(args[ARG_file].u_obj)) { - return mp_vfs_posix_file_open(&mp_type_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); + return mp_vfs_posix_file_open(&mp_type_vfs_posix_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); } #endif diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 537101d00f40..ebf36fc3978c 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -151,72 +151,6 @@ STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, } } -// Note: encoding is ignored for now; it's also not a valid kwarg for CPython's FileIO, -// but by adding it here we can use one single mp_arg_t array for open() and FileIO's constructor -STATIC const mp_arg_t file_open_args[] = { - { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_mode, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_r)} }, - { MP_QSTR_encoding, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} }, -}; -#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args) - -STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) { - int mode = 0; - const char *mode_s = mp_obj_str_get_str(args[1].u_obj); - // TODO make sure only one of r, w, x, a, and b, t are specified - while (*mode_s) { - switch (*mode_s++) { - case 'r': - mode |= FA_READ; - break; - case 'w': - mode |= FA_WRITE | FA_CREATE_ALWAYS; - break; - case 'x': - mode |= FA_WRITE | FA_CREATE_NEW; - break; - case 'a': - mode |= FA_WRITE | FA_OPEN_ALWAYS; - break; - case '+': - mode |= FA_READ | FA_WRITE; - break; - #if MICROPY_PY_IO_FILEIO - case 'b': - type = &mp_type_vfs_fat_fileio; - break; - #endif - case 't': - type = &mp_type_vfs_fat_textio; - break; - } - } - - pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); - o->base.type = type; - - const char *fname = mp_obj_str_get_str(args[0].u_obj); - assert(vfs != NULL); - FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode); - if (res != FR_OK) { - m_del_obj(pyb_file_obj_t, o); - mp_raise_OSError(fresult_to_errno_table[res]); - } - - // for 'a' mode, we must begin at the end of the file - if ((mode & FA_OPEN_ALWAYS) != 0) { - f_lseek(&o->fp, f_size(&o->fp)); - } - - return MP_OBJ_FROM_PTR(o); -} - -STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); - return file_open(NULL, type, arg_vals); -} - // TODO gc hook to close the file if not already closed STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = { @@ -247,7 +181,6 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = { { &mp_type_type }, .name = MP_QSTR_FileIO, .print = file_obj_print, - .make_new = file_obj_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &vfs_fat_fileio_stream_p, @@ -266,7 +199,6 @@ const mp_obj_type_t mp_type_vfs_fat_textio = { { &mp_type_type }, .name = MP_QSTR_TextIOWrapper, .print = file_obj_print, - .make_new = file_obj_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &vfs_fat_textio_stream_p, @@ -274,15 +206,58 @@ const mp_obj_type_t mp_type_vfs_fat_textio = { }; // Factory function for I/O stream classes -STATIC mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode) { - // TODO: analyze buffering args and instantiate appropriate type +STATIC mp_obj_t fat_vfs_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in) { fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - arg_vals[0].u_obj = path; - arg_vals[1].u_obj = mode; - arg_vals[2].u_obj = mp_const_none; - return file_open(self, &mp_type_vfs_fat_textio, arg_vals); + + const mp_obj_type_t *type = &mp_type_vfs_fat_textio; + int mode = 0; + const char *mode_s = mp_obj_str_get_str(mode_in); + // TODO make sure only one of r, w, x, a, and b, t are specified + while (*mode_s) { + switch (*mode_s++) { + case 'r': + mode |= FA_READ; + break; + case 'w': + mode |= FA_WRITE | FA_CREATE_ALWAYS; + break; + case 'x': + mode |= FA_WRITE | FA_CREATE_NEW; + break; + case 'a': + mode |= FA_WRITE | FA_OPEN_ALWAYS; + break; + case '+': + mode |= FA_READ | FA_WRITE; + break; + #if MICROPY_PY_IO_FILEIO + case 'b': + type = &mp_type_vfs_fat_fileio; + break; + #endif + case 't': + type = &mp_type_vfs_fat_textio; + break; + } + } + + pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); + o->base.type = type; + + const char *fname = mp_obj_str_get_str(path_in); + FRESULT res = f_open(&self->fatfs, &o->fp, fname, mode); + if (res != FR_OK) { + m_del_obj(pyb_file_obj_t, o); + mp_raise_OSError(fresult_to_errno_table[res]); + } + + // for 'a' mode, we must begin at the end of the file + if ((mode & FA_OPEN_ALWAYS) != 0) { + f_lseek(&o->fp, f_size(&o->fp)); + } + + return MP_OBJ_FROM_PTR(o); } -MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fatfs_builtin_open_self); +MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fat_vfs_open); #endif // MICROPY_VFS && MICROPY_VFS_FAT diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 1ada596d137c..9b00365817a1 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -138,7 +138,7 @@ STATIC mp_obj_t vfs_posix_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode if (!mp_obj_is_small_int(path_in)) { path_in = vfs_posix_get_path_obj(self, path_in); } - return mp_vfs_posix_file_open(&mp_type_textio, path_in, mode_in); + return mp_vfs_posix_file_open(&mp_type_vfs_posix_textio, path_in, mode_in); } STATIC MP_DEFINE_CONST_FUN_OBJ_3(vfs_posix_open_obj, vfs_posix_open); diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 837c5489b0e1..795ad7bbd9ea 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -111,17 +111,6 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_r)} }, - }; - - mp_arg_val_t arg_vals[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals); - return mp_vfs_posix_file_open(type, arg_vals[0].u_obj, arg_vals[1].u_obj); -} - STATIC mp_obj_t vfs_posix_file_fileno(mp_obj_t self_in) { mp_obj_vfs_posix_file_t *self = MP_OBJ_TO_PTR(self_in); check_fd_is_open(self); @@ -268,7 +257,6 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = { { &mp_type_type }, .name = MP_QSTR_FileIO, .print = vfs_posix_file_print, - .make_new = vfs_posix_file_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &vfs_posix_fileio_stream_p, @@ -287,15 +275,14 @@ const mp_obj_type_t mp_type_vfs_posix_textio = { { &mp_type_type }, .name = MP_QSTR_TextIOWrapper, .print = vfs_posix_file_print, - .make_new = vfs_posix_file_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &vfs_posix_textio_stream_p, .locals_dict = (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict, }; -const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_textio}, STDIN_FILENO}; -const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_textio}, STDOUT_FILENO}; -const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_textio}, STDERR_FILENO}; +const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, STDIN_FILENO}; +const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO}; +const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_vfs_posix_textio}, STDERR_FILENO}; #endif // MICROPY_VFS_POSIX || MICROPY_VFS_POSIX_FILE diff --git a/py/modio.c b/py/modio.c index 50af0b6a4795..d44c1948ab27 100644 --- a/py/modio.c +++ b/py/modio.c @@ -37,9 +37,6 @@ #if MICROPY_PY_IO -extern const mp_obj_type_t mp_type_fileio; -extern const mp_obj_type_t mp_type_textio; - #if MICROPY_PY_IO_IOBASE STATIC const mp_obj_type_t mp_type_iobase; @@ -211,12 +208,6 @@ STATIC const mp_rom_map_elem_t mp_module_io_globals_table[] = { #if MICROPY_PY_IO_IOBASE { MP_ROM_QSTR(MP_QSTR_IOBase), MP_ROM_PTR(&mp_type_iobase) }, #endif - #if MICROPY_PY_IO_FILEIO - { MP_ROM_QSTR(MP_QSTR_FileIO), MP_ROM_PTR(&mp_type_fileio) }, - #if MICROPY_CPYTHON_COMPAT - { MP_ROM_QSTR(MP_QSTR_TextIOWrapper), MP_ROM_PTR(&mp_type_textio) }, - #endif - #endif { MP_ROM_QSTR(MP_QSTR_StringIO), MP_ROM_PTR(&mp_type_stringio) }, #if MICROPY_PY_IO_BYTESIO { MP_ROM_QSTR(MP_QSTR_BytesIO), MP_ROM_PTR(&mp_type_bytesio) }, diff --git a/tests/extmod/vfs_posix.py b/tests/extmod/vfs_posix.py index 2a14fc20767b..d193236696ea 100644 --- a/tests/extmod/vfs_posix.py +++ b/tests/extmod/vfs_posix.py @@ -42,8 +42,8 @@ # close on a closed file should succeed f.close() -# construct a file object using the type constructor, with a raw fileno -f = type(f)(2) +# construct a file object with a raw fileno +f = open(2) print(f) # file read From 092784da1948c6bfb224f8f6c593aff255ab2db0 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 22 Jul 2022 13:53:40 +1000 Subject: [PATCH 1538/4290] ports: Remove unused mp_type_{fileio/textio} macros in mpconfigport.h. Signed-off-by: Jim Mussared --- ports/cc3200/mpconfigport.h | 4 ---- ports/esp32/mpconfigport.h | 2 -- ports/esp8266/mpconfigport.h | 11 ----------- ports/mimxrt/mpconfigport.h | 4 ---- ports/nrf/mpconfigport.h | 17 ----------------- ports/renesas-ra/mpconfigport.h | 12 ------------ ports/rp2/mpconfigport.h | 9 --------- ports/samd/mpconfigport.h | 4 ---- ports/stm32/mpconfigport.h | 12 ------------ ports/unix/mpconfigport.h | 3 --- ports/unix/variants/minimal/mpconfigvariant.h | 3 --- ports/windows/mpconfigport.h | 3 --- 12 files changed, 84 deletions(-) diff --git a/ports/cc3200/mpconfigport.h b/ports/cc3200/mpconfigport.h index 8059daeec7c6..e81a2fc29bb3 100644 --- a/ports/cc3200/mpconfigport.h +++ b/ports/cc3200/mpconfigport.h @@ -131,10 +131,6 @@ X(EINVAL) \ X(ETIMEDOUT) \ -// TODO these should be generic, not bound to fatfs -#define mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio - // extra constants #define MICROPY_PORT_CONSTANTS \ { MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, \ diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index dfa577d2bc69..957aa2e93bce 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -135,8 +135,6 @@ #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 mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 779767311cdf..9ff6a34ffd62 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -134,17 +134,6 @@ void *esp_native_code_commit(void *, size_t, void *); // printer for debugging output, goes to UART only extern const struct _mp_print_t mp_debug_print; -#if MICROPY_VFS_FAT -#define mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio -#elif MICROPY_VFS_LFS1 -#define mp_type_fileio mp_type_vfs_lfs1_fileio -#define mp_type_textio mp_type_vfs_lfs1_textio -#elif MICROPY_VFS_LFS2 -#define mp_type_fileio mp_type_vfs_lfs2_fileio -#define mp_type_textio mp_type_vfs_lfs2_textio -#endif - #define MP_STATE_PORT MP_STATE_VM // We need an implementation of the log2 function which is not a macro diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 676e563c7be4..00714ca8d056 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -184,10 +184,6 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_PENDSV_REENTER atomic_state = raise_irq_pri(IRQ_PRI_PENDSV); #define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state); -// Use VfsLfs2's types for fileio/textio -#define mp_type_fileio mp_type_vfs_lfs2_fileio -#define mp_type_textio mp_type_vfs_lfs2_textio - // Hooks to add builtins __attribute__((always_inline)) static inline void enable_irq(uint32_t state) { diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 8a2478d27d0f..a25ca1ec27ef 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -133,23 +133,6 @@ #define MICROPY_FATFS_MAX_SS (4096) #endif -#if MICROPY_VFS -// TODO these should be generic, not bound to a particular FS implementation -#if MICROPY_VFS_FAT -#define mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio -#elif MICROPY_VFS_LFS1 -#define mp_type_fileio mp_type_vfs_lfs1_fileio -#define mp_type_textio mp_type_vfs_lfs1_textio -#elif MICROPY_VFS_LFS2 -#define mp_type_fileio mp_type_vfs_lfs2_fileio -#define mp_type_textio mp_type_vfs_lfs2_textio -#endif -#else // !MICROPY_VFS_FAT -#define mp_type_fileio fatfs_type_fileio -#define mp_type_textio fatfs_type_textio -#endif - // Use port specific uos module rather than extmod variant. #define MICROPY_PY_UOS (0) diff --git a/ports/renesas-ra/mpconfigport.h b/ports/renesas-ra/mpconfigport.h index 8ecc17fcb4ac..65b194274a53 100644 --- a/ports/renesas-ra/mpconfigport.h +++ b/ports/renesas-ra/mpconfigport.h @@ -137,18 +137,6 @@ #define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_MULTI_PARTITION (1) -// TODO these should be generic, not bound to a particular FS implementation -#if MICROPY_VFS_FAT -#define mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio -#elif MICROPY_VFS_LFS1 -#define mp_type_fileio mp_type_vfs_lfs1_fileio -#define mp_type_textio mp_type_vfs_lfs1_textio -#elif MICROPY_VFS_LFS2 -#define mp_type_fileio mp_type_vfs_lfs2_fileio -#define mp_type_textio mp_type_vfs_lfs2_textio -#endif - #if MICROPY_PY_MACHINE #define MACHINE_BUILTIN_MODULE_CONSTANTS \ { MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, \ diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index d07c1015e7f5..a3725789f084 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -122,15 +122,6 @@ #define MICROPY_FATFS_MAX_SS (FLASH_SECTOR_SIZE) #endif -#if MICROPY_VFS_FAT && MICROPY_HW_USB_MSC -#define mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio -#elif MICROPY_VFS_LFS2 -// Use VfsLfs2's types for fileio/textio -#define mp_type_fileio mp_type_vfs_lfs2_fileio -#define mp_type_textio mp_type_vfs_lfs2_textio -#endif - #ifndef MICROPY_BOARD_ENTER_BOOTLOADER #define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) #endif diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 96d34bf4da04..24b9cbfe1943 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -95,10 +95,6 @@ #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_UASYNCIO (1) -// Use VfsLfs's types for fileio/textio -#define mp_type_fileio mp_type_vfs_lfs1_fileio -#define mp_type_textio mp_type_vfs_lfs1_textio - #define MP_STATE_PORT MP_STATE_VM // Miscellaneous settings diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index e44fa2260cac..e06e32c0d217 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -151,18 +151,6 @@ #define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_MULTI_PARTITION (1) -// TODO these should be generic, not bound to a particular FS implementation -#if MICROPY_VFS_FAT -#define mp_type_fileio mp_type_vfs_fat_fileio -#define mp_type_textio mp_type_vfs_fat_textio -#elif MICROPY_VFS_LFS1 -#define mp_type_fileio mp_type_vfs_lfs1_fileio -#define mp_type_textio mp_type_vfs_lfs1_textio -#elif MICROPY_VFS_LFS2 -#define mp_type_fileio mp_type_vfs_lfs2_fileio -#define mp_type_textio mp_type_vfs_lfs2_textio -#endif - #if MICROPY_PY_PYB extern const struct _mp_obj_module_t pyb_module; #define PYB_BUILTIN_MODULE_CONSTANTS \ diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 4252a406ce8f..ed4c71097ff1 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -224,9 +224,6 @@ extern const struct _mp_print_t mp_stderr_print; #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256) #define MICROPY_ASYNC_KBD_INTR (1) -#define mp_type_fileio mp_type_vfs_posix_fileio -#define mp_type_textio mp_type_vfs_posix_textio - // type definitions for the specific machine // For size_t and ssize_t diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 1e378e94d7d2..d6e5fc47262e 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -107,9 +107,6 @@ #define MICROPY_PY_UHASHLIB (0) #define MICROPY_PY_UBINASCII (0) -#define mp_type_fileio mp_type_vfs_posix_fileio -#define mp_type_textio mp_type_vfs_posix_textio - ////////////////////////////////////////// // Do not change anything beyond this line ////////////////////////////////////////// diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 71814e21476a..5f8ad983adc4 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -176,9 +176,6 @@ extern const struct _mp_print_t mp_stderr_print; #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256) #define MICROPY_KBD_EXCEPTION (1) -#define mp_type_fileio mp_type_vfs_posix_fileio -#define mp_type_textio mp_type_vfs_posix_textio - #define MICROPY_PORT_INIT_FUNC init() #define MICROPY_PORT_DEINIT_FUNC deinit() From b22abcdbbedb0f7583b19031fd65e19b3883671d Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 21 Jul 2022 09:54:02 +1000 Subject: [PATCH 1539/4290] extmod/uasyncio: Handle gather with no awaitables. This previously resulted in gather() yielding but with no way to be resumed. Signed-off-by: Jim Mussared --- extmod/uasyncio/funcs.py | 3 +++ tests/extmod/uasyncio_gather.py | 5 +++++ tests/extmod/uasyncio_gather.py.exp | 2 ++ 3 files changed, 10 insertions(+) diff --git a/extmod/uasyncio/funcs.py b/extmod/uasyncio/funcs.py index a1d38fbcbf97..96883e4fe106 100644 --- a/extmod/uasyncio/funcs.py +++ b/extmod/uasyncio/funcs.py @@ -62,6 +62,9 @@ def remove(t): async def gather(*aws, return_exceptions=False): + if not aws: + return [] + def done(t, er): # Sub-task "t" has finished, with exception "er". nonlocal state diff --git a/tests/extmod/uasyncio_gather.py b/tests/extmod/uasyncio_gather.py index c081221c9fc6..af6ea555ab13 100644 --- a/tests/extmod/uasyncio_gather.py +++ b/tests/extmod/uasyncio_gather.py @@ -53,6 +53,11 @@ async def main(): print("====") + # Gather with no awaitables + print(await asyncio.gather()) + + print("====") + # Test return_exceptions, where one task is cancelled and the other finishes normally tasks = [asyncio.create_task(task(1)), asyncio.create_task(task(2))] tasks[0].cancel() diff --git a/tests/extmod/uasyncio_gather.py.exp b/tests/extmod/uasyncio_gather.py.exp index a5ea47ab500d..371d1ae60dfd 100644 --- a/tests/extmod/uasyncio_gather.py.exp +++ b/tests/extmod/uasyncio_gather.py.exp @@ -9,6 +9,8 @@ Task C: Compute factorial(4)... Task C: factorial(4) = 24 [2, 6, 24] ==== +[] +==== start 2 end 2 [CancelledError(), 2] From f9cbe6bc47dd4f5b8e85178caecd6f0de22b4c34 Mon Sep 17 00:00:00 2001 From: Dan Ellis Date: Tue, 12 Jul 2022 09:48:38 -0400 Subject: [PATCH 1540/4290] py/formatfloat: Format all whole-number floats exactly. Formerly, py/formatfloat would print whole numbers inaccurately with nonzero digits beyond the decimal place. This resulted from its strategy of successive scaling of the argument by 0.1 which cannot be exactly represented in floating point. The change in this commit avoids scaling until the value is smaller than 1, so all whole numbers print with zero fractional part. Fixes issue #4212. Signed-off-by: Dan Ellis dan.ellis@gmail.com --- py/formatfloat.c | 154 +++++++++++++------- tests/float/float_format_ftoe.py | 4 + tests/float/float_format_ftoe.py.exp | 1 + tests/float/float_format_ints.py | 31 ++++ tests/float/float_format_ints_doubleprec.py | 15 ++ tests/run-tests.py | 1 + tools/tinytest-codegen.py | 1 + 7 files changed, 153 insertions(+), 54 deletions(-) create mode 100644 tests/float/float_format_ftoe.py create mode 100644 tests/float/float_format_ftoe.py.exp create mode 100644 tests/float/float_format_ints.py create mode 100644 tests/float/float_format_ints_doubleprec.py diff --git a/py/formatfloat.c b/py/formatfloat.c index 9d28b2317dc6..357b73ace3ab 100644 --- a/py/formatfloat.c +++ b/py/formatfloat.c @@ -25,6 +25,7 @@ */ #include "py/mpconfig.h" +#include "py/misc.h" #if MICROPY_FLOAT_IMPL != MICROPY_FLOAT_IMPL_NONE #include @@ -96,7 +97,16 @@ static inline int fp_isless1(float x) { #define fp_iszero(x) (x == 0) #define fp_isless1(x) (x < 1.0) -#endif +#endif // MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT/DOUBLE + +static inline int fp_ge_eps(FPTYPE x, FPTYPE y) { + mp_float_union_t fb_y = {y}; + // Back off 2 eps. + // This is valid for almost all values, but in practice + // it's only used when y = 1eX for X>=0. + fb_y.i -= 2; + return x >= fb_y.f; +} static const FPTYPE g_pos_pow[] = { #if FPDECEXP > 32 @@ -173,6 +183,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch int num_digits = 0; const FPTYPE *pos_pow = g_pos_pow; const FPTYPE *neg_pow = g_neg_pow; + int signed_e = 0; if (fp_iszero(f)) { e = 0; @@ -192,31 +203,24 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } } } else if (fp_isless1(f)) { - // We need to figure out what an integer digit will be used - // in case 'f' is used (or we revert other format to it below). - // As we just tested number to be <1, this is obviously 0, - // but we can round it up to 1 below. - char first_dig = '0'; - if (f >= FPROUND_TO_ONE) { - first_dig = '1'; - } - + FPTYPE f_mod = f; // Build negative exponent for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { - if (*neg_pow > f) { + if (*neg_pow > f_mod) { e += e1; - f *= *pos_pow; + f_mod *= *pos_pow; } } + char e_sign_char = '-'; - if (fp_isless1(f) && f >= FPROUND_TO_ONE) { - f = FPCONST(1.0); + if (fp_isless1(f_mod) && f_mod >= FPROUND_TO_ONE) { + f_mod = FPCONST(1.0); if (e == 0) { e_sign_char = '+'; } - } else if (fp_isless1(f)) { + } else if (fp_isless1(f_mod)) { e++; - f *= FPCONST(10.0); + f_mod *= FPCONST(10.0); } // If the user specified 'g' format, and e is <= 4, then we'll switch @@ -224,8 +228,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'f' || (fmt == 'g' && e <= 4)) { fmt = 'f'; - dec = -1; - *s++ = first_dig; + dec = 0; if (org_fmt == 'g') { prec += (e - 1); @@ -237,13 +240,8 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } num_digits = prec; - if (num_digits) { - *s++ = '.'; - while (--e && num_digits) { - *s++ = '0'; - num_digits--; - } - } + signed_e = 0; + ++num_digits; } else { // For e & g formats, we'll be printing the exponent, so set the // sign. @@ -256,22 +254,29 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch prec++; } } + signed_e = -e; } } else { - // Build positive exponent - for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { - if (*pos_pow <= f) { + // Build positive exponent. + // We don't modify f at this point to avoid innaccuracies from + // scaling it. Instead, we find the product of powers of 10 + // that is not greater than it, and use that to start the + // mantissa. + FPTYPE u_base = FPCONST(1.0); + for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++) { + FPTYPE next_u = u_base * *pos_pow; + // fp_ge_eps performs "f >= (next_u - 2eps)" so that if, for + // numerical reasons, f is very close to a power of ten but + // not strictly equal, we still treat it as that power of 10. + // The comparison was failing for maybe 10% of 1eX values, but + // although rounding fixed many of them, there were still some + // rendering as 9.99999998e(X-1). + if (fp_ge_eps(f, next_u)) { + u_base = next_u; e += e1; - f *= *neg_pow; } } - // It can be that f was right on the edge of an entry in pos_pow needs to be reduced - if ((int)f >= 10) { - e += 1; - f *= FPCONST(0.1); - } - // If the user specified fixed format (fmt == 'f') and e makes the // number too big to fit into the available buffer, then we'll // switch to the 'e' format. @@ -310,15 +315,15 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } else { e_sign = '+'; } + signed_e = e; } if (prec < 0) { // This can happen when the prec is trimmed to prevent buffer overflow prec = 0; } - // We now have num.f as a floating point number between >= 1 and < 10 - // (or equal to zero), and e contains the absolute value of the power of - // 10 exponent. and (dec + 1) == the number of dgits before the decimal. + // At this point e contains the absolute value of the power of 10 exponent. + // (dec + 1) == the number of dgits before the decimal. // For e, prec is # digits after the decimal // For f, prec is # digits after the decimal @@ -336,25 +341,63 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch num_digits = prec; } - // Print the digits of the mantissa - for (int i = 0; i < num_digits; ++i, --dec) { - int32_t d = (int32_t)f; - if (d < 0) { - *s++ = '0'; - } else { + if (signed_e < 0) { + // The algorithm below treats numbers smaller than 1 by scaling them + // repeatedly by 10 to bring the new digit to the top. Our input number + // was smaller than 1, so scale it up to be 1 <= f < 10. + FPTYPE u_base = FPCONST(1.0); + const FPTYPE *pow_u = g_pos_pow; + for (int m = FPDECEXP; m; m >>= 1, pow_u++) { + if (m & e) { + u_base *= *pow_u; + } + } + f *= u_base; + } + + int d = 0; + int num_digits_left = num_digits; + for (int digit_index = signed_e; num_digits_left >= 0; --digit_index) { + FPTYPE u_base = FPCONST(1.0); + if (digit_index > 0) { + // Generate 10^digit_index for positive digit_index. + const FPTYPE *pow_u = g_pos_pow; + int target_index = digit_index; + for (int m = FPDECEXP; m; m >>= 1, pow_u++) { + if (m & target_index) { + u_base *= *pow_u; + } + } + } + for (d = 0; d < 9; ++d) { + // This is essentially "if (f < u_base)", but with 2eps margin + // so that if f is just a tiny bit smaller, we treat it as + // equal (and accept the additional digit value). + if (!fp_ge_eps(f, u_base)) { + break; + } + f -= u_base; + } + // We calculate one more digit than we display, to use in rounding + // below. So only emit the digit if it's one that we display. + if (num_digits_left > 0) { + // Emit this number (the leading digit). *s++ = '0' + d; + if (dec == 0 && prec > 0) { + *s++ = '.'; + } } - if (dec == 0 && prec > 0) { - *s++ = '.'; + --dec; + --num_digits_left; + if (digit_index <= 0) { + // Once we get below 1.0, we scale up f instead of calculting + // negative powers of 10 in u_base. This provides better + // renditions of exact decimals like 1/16 etc. + f *= FPCONST(10.0); } - f -= (FPTYPE)d; - f *= FPCONST(10.0); } - - // Round - // If we print non-exponential format (i.e. 'f'), but a digit we're going - // to round by (e) is too far away, then there's nothing to round. - if ((org_fmt != 'f' || e <= num_digits) && f >= FPCONST(5.0)) { + // Rounding. If the next digit to print is >= 5, round up. + if (d >= 5) { char *rs = s; rs--; while (1) { @@ -394,7 +437,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } } else { // Need at extra digit at the end to make room for the leading '1' - s++; + // but if we're at the buffer size limit, just drop the final digit. + if ((size_t)(s + 1 - buf) < buf_size) { + s++; + } } char *ss = s; while (ss > rs) { diff --git a/tests/float/float_format_ftoe.py b/tests/float/float_format_ftoe.py new file mode 100644 index 000000000000..bc4e5a4a53eb --- /dev/null +++ b/tests/float/float_format_ftoe.py @@ -0,0 +1,4 @@ +# check a case where rounding was suppressed inappropriately when "f" was +# promoted to "e" for large numbers. +v = 8.888e32 +print("%.2f" % v) # '%.2f' format with e32 becomes '%.2e', expect 8.89e+32. diff --git a/tests/float/float_format_ftoe.py.exp b/tests/float/float_format_ftoe.py.exp new file mode 100644 index 000000000000..f8b1deb3eca8 --- /dev/null +++ b/tests/float/float_format_ftoe.py.exp @@ -0,0 +1 @@ +8.89e+32 diff --git a/tests/float/float_format_ints.py b/tests/float/float_format_ints.py new file mode 100644 index 000000000000..0bf4baf12d0a --- /dev/null +++ b/tests/float/float_format_ints.py @@ -0,0 +1,31 @@ +# Test that integers format to exact values. + +for b in [13, 123, 457, 23456]: + for r in range(1, 10): + e_fmt = "{:." + str(r) + "e}" + f_fmt = "{:." + str(r) + "f}" + g_fmt = "{:." + str(r) + "g}" + for e in range(0, 5): + f = b * (10**e) + title = str(b) + " x 10^" + str(e) + print(title, "with format", e_fmt, "gives", e_fmt.format(f)) + print(title, "with format", f_fmt, "gives", f_fmt.format(f)) + print(title, "with format", g_fmt, "gives", g_fmt.format(f)) + +# Check that powers of 10 (that fit in float32) format correctly. +for i in range(31): + # It works to 12 digits on all platforms *except* qemu-arm, where + # 10^11 comes out as 10000000820 or something. + print("{:.7g}".format(float("1e" + str(i)))) + +# 16777215 is 2^24 - 1, the largest integer that can be completely held +# in a float32. +print("{:f}".format(16777215)) +# 4294967040 = 16777215 * 128 is the largest integer that is exactly +# represented by a float32 and that will also fit within a (signed) int32. +# The upper bound of our integer-handling code is actually double this, +# but that constant might cause trouble on systems using 32 bit ints. +print("{:f}".format(2147483520)) +# Very large positive integers can be a test for precision and resolution. +# This is a weird way to represent 1e38 (largest power of 10 for float32). +print("{:.6e}".format(float("9" * 30 + "e8"))) diff --git a/tests/float/float_format_ints_doubleprec.py b/tests/float/float_format_ints_doubleprec.py new file mode 100644 index 000000000000..57899d6d65a8 --- /dev/null +++ b/tests/float/float_format_ints_doubleprec.py @@ -0,0 +1,15 @@ +# Test formatting of very large ints. +# Relies on double-precision floats. + +import array +import sys + +# Challenging way to express 1e200 and 1e100. +print("{:.12e}".format(float("9" * 400 + "e-200"))) +print("{:.12e}".format(float("9" * 400 + "e-300"))) + +# These correspond to the binary representation of 1e200 in float64s: +v1 = 0x54B249AD2594C37D # 1e100 +v2 = 0x6974E718D7D7625A # 1e200 +print("{:.12e}".format(array.array("d", v1.to_bytes(8, sys.byteorder))[0])) +print("{:.12e}".format(array.array("d", v2.to_bytes(8, sys.byteorder))[0])) diff --git a/tests/run-tests.py b/tests/run-tests.py index baab7bdd4a90..2745ee1393ba 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -516,6 +516,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): if upy_float_precision < 64: skip_tests.add("float/float_divmod.py") # tested by float/float_divmod_relaxed.py instead skip_tests.add("float/float2int_doubleprec_intbig.py") + skip_tests.add("float/float_format_ints_doubleprec.py") skip_tests.add("float/float_parse_doubleprec.py") if not has_complex: diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index f1169a34d4bd..feda75f283d3 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -79,6 +79,7 @@ def script_to_map(test_file): "float/float_divmod.py", # requires double precision floating point to work "float/float2int_doubleprec_intbig.py", + "float/float_format_ints_doubleprec.py", "float/float_parse_doubleprec.py", # inline asm FP tests (require Cortex-M4) "inlineasm/asmfpaddsub.py", From 1230d86dca414baec926b2268156d241346efd66 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 27 Jul 2022 11:37:53 +1000 Subject: [PATCH 1541/4290] py/builtinimport: Remove duplicate static function argument. context==mc in all cases where this function was being called. Signed-off-by: Angus Gratton --- py/builtinimport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py/builtinimport.c b/py/builtinimport.c index cd9636ccdc2d..36cdac07675e 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -159,7 +159,7 @@ STATIC void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) { #endif #if (MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD) || MICROPY_MODULE_FROZEN_MPY -STATIC void do_execute_raw_code(mp_module_context_t *context, const mp_raw_code_t *rc, const mp_module_context_t *mc, const char *source_name) { +STATIC void do_execute_raw_code(const mp_module_context_t *context, const mp_raw_code_t *rc, const char *source_name) { (void)source_name; #if MICROPY_PY___FILE__ @@ -179,7 +179,7 @@ STATIC void do_execute_raw_code(mp_module_context_t *context, const mp_raw_code_ nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - mp_obj_t module_fun = mp_make_function_from_raw_code(rc, mc, NULL); + mp_obj_t module_fun = mp_make_function_from_raw_code(rc, context, NULL); mp_call_function_0(module_fun); // finish nlr block, restore context @@ -224,7 +224,7 @@ STATIC void do_load(mp_module_context_t *module_obj, vstr_t *file) { if (frozen_type == MP_FROZEN_MPY) { const mp_frozen_module_t *frozen = modref; module_obj->constants = frozen->constants; - do_execute_raw_code(module_obj, frozen->rc, module_obj, file_str + frozen_path_prefix_len); + do_execute_raw_code(module_obj, frozen->rc, file_str + frozen_path_prefix_len); return; } #endif @@ -237,7 +237,7 @@ STATIC void do_load(mp_module_context_t *module_obj, vstr_t *file) { #if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_compiled_module_t cm = mp_raw_code_load_file(file_str, module_obj); - do_execute_raw_code(module_obj, cm.rc, cm.context, file_str); + do_execute_raw_code(cm.context, cm.rc, file_str); return; } #endif From 45ab801c300d605db96229f6e0626ebe2801f24d Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Tue, 26 Jul 2022 15:56:07 +0100 Subject: [PATCH 1542/4290] rp2/cyw43_configport: Add event hook into cyw43_delay_ms. Still see some USB issues apparently caused by delays loading wifi firmware. cyw43_delay_ms is used to wait in the driver, so we should call the event hook in there. Fixes #8963. --- ports/rp2/cyw43_configport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/rp2/cyw43_configport.h b/ports/rp2/cyw43_configport.h index b6f5b3cad8a7..a5ce8a9e74de 100644 --- a/ports/rp2/cyw43_configport.h +++ b/ports/rp2/cyw43_configport.h @@ -93,6 +93,7 @@ static inline void cyw43_delay_ms(uint32_t ms) { int32_t start = mp_hal_ticks_us(); while (mp_hal_ticks_us() - start < us) { __WFI(); + MICROPY_EVENT_POLL_HOOK_FAST; } } From 3c32ca6e77143704ac08d5694b7260781f127c3d Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 15 Apr 2022 12:04:01 -0500 Subject: [PATCH 1543/4290] unix/unix_mphal: Allow overriding hal time functions. This adds #ifdefs around each of the mp_hal_* time functions for the unix port. This allows variants to override individual functions as needed. Signed-off-by: David Lechner --- ports/unix/unix_mphal.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/unix/unix_mphal.c b/ports/unix/unix_mphal.c index c224f78700c0..6f2def890330 100644 --- a/ports/unix/unix_mphal.c +++ b/ports/unix/unix_mphal.c @@ -199,6 +199,7 @@ void mp_hal_stdout_tx_str(const char *str) { mp_hal_stdout_tx_strn(str, strlen(str)); } +#ifndef mp_hal_ticks_ms mp_uint_t mp_hal_ticks_ms(void) { #if (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(_POSIX_MONOTONIC_CLOCK) struct timespec tv; @@ -210,7 +211,9 @@ mp_uint_t mp_hal_ticks_ms(void) { return tv.tv_sec * 1000 + tv.tv_usec / 1000; #endif } +#endif +#ifndef mp_hal_ticks_us mp_uint_t mp_hal_ticks_us(void) { #if (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(_POSIX_MONOTONIC_CLOCK) struct timespec tv; @@ -222,13 +225,17 @@ mp_uint_t mp_hal_ticks_us(void) { return tv.tv_sec * 1000000 + tv.tv_usec; #endif } +#endif +#ifndef mp_hal_time_ns uint64_t mp_hal_time_ns(void) { struct timeval tv; gettimeofday(&tv, NULL); return (uint64_t)tv.tv_sec * 1000000000ULL + (uint64_t)tv.tv_usec * 1000ULL; } +#endif +#ifndef mp_hal_delay_ms void mp_hal_delay_ms(mp_uint_t ms) { #ifdef MICROPY_EVENT_POLL_HOOK mp_uint_t start = mp_hal_ticks_ms(); @@ -242,6 +249,7 @@ void mp_hal_delay_ms(mp_uint_t ms) { usleep(ms * 1000); #endif } +#endif void mp_hal_get_random(size_t n, void *buf) { #ifdef _HAVE_GETRANDOM From fdfe4eca745dce5f20fb65a3c197006b9053999a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 28 Jul 2022 17:56:27 +1000 Subject: [PATCH 1544/4290] ports: Always include debug information in the ELF. For bare metal ARM & xtensa targets, passing -g will make the ELF file larger but doesn't change the binary size. However, this means tools like gdb, addr2line, etc can extract source-level information from the ELF. Also standardise -ggdb to -g, these produce the exact same ELF file on arm-none-eabi-gcc and will use DWARF format for all these ports. --- ports/esp8266/Makefile | 2 +- ports/mimxrt/Makefile | 3 ++- ports/minimal/Makefile | 3 ++- ports/nrf/Makefile | 5 +++-- ports/renesas-ra/Makefile | 3 ++- ports/samd/Makefile | 3 ++- ports/stm32/Makefile | 3 ++- ports/teensy/Makefile | 3 ++- 8 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index f70fbd228406..52ba18d7d8b0 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -68,8 +68,8 @@ LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LIBS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc # Debugging/Optimization +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) -CFLAGS += -g COPT = -O0 else CFLAGS += -fdata-sections -ffunction-sections diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index de560bdb66a6..13b766eb3cc5 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -297,8 +297,9 @@ SRC_QSTR += \ # Compiler Flags # ============================================================================= +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG),1) -CFLAGS += -Og -ggdb +CFLAGS += -Og else CFLAGS += -Os -DNDEBUG endif diff --git a/ports/minimal/Makefile b/ports/minimal/Makefile index 4a17df6803e1..169132a1a29f 100644 --- a/ports/minimal/Makefile +++ b/ports/minimal/Makefile @@ -34,8 +34,9 @@ endif CSUPEROPT = -Os # save some code space # Tune for Debugging or Optimization +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) -CFLAGS += -O0 -ggdb +CFLAGS += -O0 else CFLAGS += -Os -DNDEBUG CFLAGS += -fdata-sections -ffunction-sections diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 47653ae71683..0586524ba614 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -124,7 +124,7 @@ endif CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) -CFLAGS += $(INC) -Wall -Werror -g -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Werror -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += -fno-strict-aliasing CFLAGS += -Iboards/$(BOARD) CFLAGS += -DNRF5_HAL_H='<$(MCU_VARIANT)_hal.h>' @@ -138,9 +138,10 @@ LDFLAGS += -Wl,'--defsym=_fs_size=$(FS_SIZE)' endif #Debugging/Optimization +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) #ASMFLAGS += -g -gtabs+ -CFLAGS += -O0 -ggdb +CFLAGS += -O0 LDFLAGS += -O0 else CFLAGS += -Os -DNDEBUG diff --git a/ports/renesas-ra/Makefile b/ports/renesas-ra/Makefile index d326c81e7858..92d8be0692af 100644 --- a/ports/renesas-ra/Makefile +++ b/ports/renesas-ra/Makefile @@ -148,8 +148,9 @@ CFLAGS += -fdata-sections -ffunction-sections LDFLAGS += --gc-sections # Debugging/Optimization +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) -CFLAGS += -g -DPENDSV_DEBUG +CFLAGS += -DPENDSV_DEBUG #COPT = -Og COPT = -Os # Disable text compression in debug builds diff --git a/ports/samd/Makefile b/ports/samd/Makefile index b3d6d8b228fd..7091365f4968 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -57,8 +57,9 @@ LDFLAGS += $(LDFLAGS_MOD) LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Tune for Debugging or Optimization +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG),1) -CFLAGS += -O0 -ggdb +CFLAGS += -O0 else CFLAGS += -Os -DNDEBUG LDFLAGS += --gc-sections diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 652dff19fe1d..657524798cf5 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -114,8 +114,9 @@ $(BUILD)/stm32_it.o $(BUILD)/pendsv.o: CFLAGS += -fno-lto endif # Debugging/Optimization +CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) -CFLAGS += -g -DPENDSV_DEBUG +CFLAGS += -DPENDSV_DEBUG COPT ?= -Og # Disable text compression in debug builds MICROPY_ROM_TEXT_COMPRESSION = 0 diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index 745f530d7a31..d7161fcbbc3b 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -105,8 +105,9 @@ LIBS += -L $(dir $(LIBC_FILE_NAME)) -lc LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc #Debugging/Optimization +CFLAGS += -g # always include debug info in the ELF ifdef DEBUG -CFLAGS += -Og -ggdb +CFLAGS += -Og else CFLAGS += -Os #-DNDEBUG endif From fe5598452dd82ab24cf19221777b901a6decccdd Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Wed, 27 Jul 2022 18:19:42 +0100 Subject: [PATCH 1545/4290] docs/library/time: Provide more info about which epoch is used. Some embedded targets use 1970 epoch. --- docs/library/time.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/library/time.rst b/docs/library/time.rst index 6ca172f22128..3ab5caf248c6 100644 --- a/docs/library/time.rst +++ b/docs/library/time.rst @@ -10,8 +10,8 @@ The ``time`` module provides functions for getting the current time and date, measuring time intervals, and for delays. **Time Epoch**: Unix port uses standard for POSIX systems epoch of -1970-01-01 00:00:00 UTC. However, embedded ports use epoch of -2000-01-01 00:00:00 UTC. +1970-01-01 00:00:00 UTC. However, some embedded ports use epoch of +2000-01-01 00:00:00 UTC. Epoch year may be determined with ``gmtime(0)[0]``. **Maintaining actual calendar date/time**: This requires a Real Time Clock (RTC). On systems with underlying OS (including some From e168d47424eefc15ab74c3c15e363d02deb46fba Mon Sep 17 00:00:00 2001 From: chrismas9 Date: Sun, 26 Jun 2022 22:59:09 +1000 Subject: [PATCH 1546/4290] docs/library/pyb.Pin: Fix out-of-context paragraphs, and AF_PP typo. Remove out of context callback paragraph, it was part of the wipy docs. And move the paragraph about PULL_UP/PULL_DOWN resistor values to within the init() method docs. Also fix pull-pull -> push-pull. Signed-off-by: Chris Mason --- docs/library/pyb.Pin.rst | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index d13cb9741cd2..292758c11cd0 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -58,16 +58,6 @@ an ordinal pin number: You can set ``pyb.Pin.debug(True)`` to get some debug information about how a particular object gets mapped to a pin. -When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled, -that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND -respectively (except pin Y5 which has 11k Ohm resistors). - -Now every time a falling edge is seen on the gpio pin, the callback will be -executed. Caution: mechanical push buttons have "bounce" and pushing or -releasing a switch will often generate multiple edges. -See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed -explanation, along with various techniques for debouncing. - All pin objects go through the pin mapper to come up with one of the gpio pins. @@ -107,7 +97,7 @@ Methods - ``Pin.IN`` - configure the pin for input; - ``Pin.OUT_PP`` - configure the pin for output, with push-pull control; - ``Pin.OUT_OD`` - configure the pin for output, with open-drain control; - - ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull; + - ``Pin.AF_PP`` - configure the pin for alternate function, push-pull; - ``Pin.AF_OD`` - configure the pin for alternate function, open-drain; - ``Pin.ANALOG`` - configure the pin for analog. @@ -117,6 +107,10 @@ Methods - ``Pin.PULL_UP`` - enable the pull-up resistor; - ``Pin.PULL_DOWN`` - enable the pull-down resistor. + When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled, + that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND + respectively (except pin Y5 which has 11k Ohm resistors). + - *value* if not None will set the port output value before enabling the pin. - *alt* can be used when mode is ``Pin.AF_PP`` or ``Pin.AF_OD`` to set the From 33ea400ce849777617bf1e8f44b10928530b64b9 Mon Sep 17 00:00:00 2001 From: chrismas9 Date: Sun, 26 Jun 2022 23:30:37 +1000 Subject: [PATCH 1547/4290] docs/library/pyb.Pin: Add Pin.ALT constant. Some Pin alternate functions are inputs, for example, timer capture and break inputs. In Pyb.Pin the only way to set alt mode is with Pin.AF_PP or Pin.AF_OD. It is not intuitive to use an output mode to configure an input. Pin.ALT is used in the machine.Pin class and works in pyb.Pin. The examples are changed to use Pin.ALT because TIM2_CH3 can be a capture input or pulse output. Signed-off-by: Chris Mason --- docs/library/pyb.Pin.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 292758c11cd0..b93924508b94 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -97,6 +97,7 @@ Methods - ``Pin.IN`` - configure the pin for input; - ``Pin.OUT_PP`` - configure the pin for output, with push-pull control; - ``Pin.OUT_OD`` - configure the pin for output, with open-drain control; + - ``Pin.ALT`` - configure the pin for alternate function, input or output; - ``Pin.AF_PP`` - configure the pin for alternate function, push-pull; - ``Pin.AF_OD`` - configure the pin for alternate function, open-drain; - ``Pin.ANALOG`` - configure the pin for analog. @@ -113,8 +114,8 @@ Methods - *value* if not None will set the port output value before enabling the pin. - - *alt* can be used when mode is ``Pin.AF_PP`` or ``Pin.AF_OD`` to set the - index or name of one of the alternate functions associated with a pin. + - *alt* can be used when mode is ``Pin.ALT`` , ``Pin.AF_PP`` or ``Pin.AF_OD`` to + set the index or name of one of the alternate functions associated with a pin. This arg was previously called *af* which can still be used if needed. Returns: ``None``. @@ -177,6 +178,10 @@ Methods Constants --------- +.. data:: Pin.ALT + + initialise the pin to alternate-function mode for input or output + .. data:: Pin.AF_OD initialise the pin to alternate-function mode with an open-drain drive @@ -237,11 +242,11 @@ control is desired. To configure X3 to expose TIM2_CH3, you could use:: - pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, alt=pyb.Pin.AF1_TIM2) + pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.ALT, alt=pyb.Pin.AF1_TIM2) or:: - pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, alt=1) + pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.ALT, alt=1) Methods ------- From c038ea0cc68bff18ce9ac338a283d2dd4cf29f1e Mon Sep 17 00:00:00 2001 From: chrismas9 Date: Sun, 26 Jun 2022 23:54:37 +1000 Subject: [PATCH 1548/4290] docs/library/pyb.Timer: Document how to use BKIN pin with example. Document how to connect the Timer block BRK_IN to a physical Pin alternate function. Add an example of PWM Motor drive using complementary outputs with dead time and break input to kill the PWM and generate a callback. Signed-off-by: Chris Mason --- docs/library/pyb.Timer.rst | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/library/pyb.Timer.rst b/docs/library/pyb.Timer.rst index 53213666ba87..1749efce2d50 100644 --- a/docs/library/pyb.Timer.rst +++ b/docs/library/pyb.Timer.rst @@ -111,7 +111,9 @@ Methods the PWM when the ``BRK_IN`` input is asserted. The value of this argument determines if break is enabled and what the polarity is, and can be one of ``Timer.BRK_OFF``, ``Timer.BRK_LOW`` or - ``Timer.BRK_HIGH``. + ``Timer.BRK_HIGH``. To select the ``BRK_IN`` pin construct a Pin object with + ``mode=Pin.ALT, alt=Pin.AFn_TIMx``. The pin's GPIO input features are + available in alt mode - ``pull=`` , ``value()`` and ``irq()``. You must either specify freq or both of period and prescaler. @@ -204,6 +206,17 @@ Methods ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=8000) ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=16000) + PWM Motor Example with complementary outputs, dead time, break input and break callback:: + + from pyb import Timer + from machine import Pin # machine.Pin supports alt mode and irq on the same pin. + pin_t8_1 = Pin(Pin.board.Y1, mode=Pin.ALT, af=Pin.AF3_TIM8) # Pin PC6, TIM8_CH1 + pin_t8_1n = Pin(Pin.board.X8, mode=Pin.ALT, af=Pin.AF3_TIM8) # Pin PA7, TIM8_CH1N + pin_bkin = Pin(Pin.board.X7, mode=Pin.ALT, af=Pin.AF3_TIM8) # Pin PA6, TIM8_BKIN + pin_bkin.irq(handler=break_callabck, trigger=Pin.IRQ_FALLING) + timer = pyb.Timer(8, freq=1000, deadtime=1008, brk=Timer.BRK_LOW) + ch1 = timer.channel(1, pyb.Timer.PWM, pulse_width_percent=30) + .. method:: Timer.counter([value]) Get or set the timer counter. From 963e599ec0d253534eb835ade7020e8ac3d7919b Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 29 Jul 2022 12:06:08 +1000 Subject: [PATCH 1549/4290] tests/cpydiff: Fix formatting of code snippet to use double quotes. Signed-off-by: Damien George --- tests/cpydiff/types_float_implicit_conversion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpydiff/types_float_implicit_conversion.py b/tests/cpydiff/types_float_implicit_conversion.py index 8d39a7cd4109..3726839fac6d 100644 --- a/tests/cpydiff/types_float_implicit_conversion.py +++ b/tests/cpydiff/types_float_implicit_conversion.py @@ -2,7 +2,7 @@ categories: Types,float description: uPy allows implicit conversion of objects in maths operations while CPython does not. cause: Unknown -workaround: Objects should be wrapped in `float(obj)` for compatibility with CPython. +workaround: Objects should be wrapped in ``float(obj)`` for compatibility with CPython. """ From 9a1b7d8448346b353e3aa7ae11ff2b441b6d5313 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 8 Jul 2022 14:32:12 +1000 Subject: [PATCH 1550/4290] lib/micropython-lib: Add micropython-lib as a submodule. Several boards now depend on libraries from micropython-lib. Rather than expecting micropython-lib to be available as a sibling of the micropython repo, instead make it a submodule. Signed-off-by: Jim Mussared --- .gitmodules | 3 +++ lib/micropython-lib | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/micropython-lib diff --git a/.gitmodules b/.gitmodules index 3d1e2fea745e..3c47b5959aad 100644 --- a/.gitmodules +++ b/.gitmodules @@ -53,3 +53,6 @@ [submodule "lib/cyw43-driver"] path = lib/cyw43-driver url = https://github.com/georgerobotics/cyw43-driver.git +[submodule "lib/micropython-lib"] + path = lib/micropython-lib + url = https://github.com/micropython/micropython-lib.git diff --git a/lib/micropython-lib b/lib/micropython-lib new file mode 160000 index 000000000000..70e422dc2e88 --- /dev/null +++ b/lib/micropython-lib @@ -0,0 +1 @@ +Subproject commit 70e422dc2e885bbaafe6eb7e3d81118e17d4b555 From be83c08f463c75bb52619ea4f35b5256fc479158 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 8 Jul 2022 14:59:33 +1000 Subject: [PATCH 1551/4290] ports: Always append to GIT_SUBMODULES. Avoids overwriting submodules required by base makefiles. Signed-off-by: Jim Mussared --- ports/esp32/Makefile | 2 +- ports/esp8266/Makefile | 2 +- ports/mimxrt/Makefile | 2 +- ports/nrf/Makefile | 2 +- ports/samd/Makefile | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index c8ca9262c8f1..88f946fa983b 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -14,7 +14,7 @@ BAUD ?= 460800 PYTHON ?= python3 -GIT_SUBMODULES = lib/berkeley-db-1.xx +GIT_SUBMODULES += lib/berkeley-db-1.xx .PHONY: all clean deploy erase submodules FORCE diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 52ba18d7d8b0..c027f690fb10 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -32,7 +32,7 @@ FROZEN_MANIFEST ?= boards/manifest.py include $(TOP)/py/py.mk include $(TOP)/extmod/extmod.mk -GIT_SUBMODULES = lib/axtls lib/berkeley-db-1.xx +GIT_SUBMODULES += lib/axtls lib/berkeley-db-1.xx FWBIN = $(BUILD)/firmware-combined.bin PORT ?= /dev/ttyACM0 diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 13b766eb3cc5..6312ecdd8f3e 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -7,7 +7,7 @@ BOARD_DIR ?= boards/$(BOARD) BUILD ?= build-$(BOARD) PORT ?= /dev/ttyACM0 CROSS_COMPILE ?= arm-none-eabi- -GIT_SUBMODULES = lib/tinyusb lib/nxp_driver lib/lwip lib/mbedtls +GIT_SUBMODULES += lib/tinyusb lib/nxp_driver lib/lwip lib/mbedtls # MicroPython feature configurations FROZEN_MANIFEST ?= boards/manifest.py diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 0586524ba614..23be4430f396 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -58,7 +58,7 @@ FROZEN_MANIFEST ?= modules/manifest.py include ../../py/py.mk include ../../extmod/extmod.mk -GIT_SUBMODULES = lib/nrfx lib/tinyusb +GIT_SUBMODULES += lib/nrfx lib/tinyusb MICROPY_VFS_FAT ?= 0 diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 7091365f4968..aed8637abcc1 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -24,7 +24,7 @@ FROZEN_MANIFEST ?= boards/manifest.py include $(TOP)/py/py.mk include $(TOP)/extmod/extmod.mk -GIT_SUBMODULES = lib/asf4 lib/tinyusb +GIT_SUBMODULES += lib/asf4 lib/tinyusb INC += -I. INC += -I$(TOP) From 9a7ac41be61a4d80234ac91c97ee5f099af29626 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 8 Jul 2022 15:26:06 +1000 Subject: [PATCH 1552/4290] rp2/Makefile: Always use cmake to discover submodules. Used to be special-cased for Pico, but now everything depends on micropython-lib if it's using a frozen manifest. Signed-off-by: Jim Mussared --- ports/rp2/CMakeLists.txt | 11 +++++++++-- ports/rp2/Makefile | 15 ++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index f9a9efe62a8c..f5bd61c44ea8 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -54,6 +54,10 @@ if (MICROPY_PY_NETWORK_CYW43) set(PICO_CYW43_DRIVER_PATH ${MICROPY_DIR}/lib/cyw43-driver) endif() +# Necessary submodules for all boards. +string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/mbedtls) +string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/tinyusb) + # Include component cmake fragments include(${MICROPY_DIR}/py/py.cmake) include(${MICROPY_DIR}/extmod/extmod.cmake) @@ -278,6 +282,11 @@ if (MICROPY_PY_NETWORK_NINAW10) endif() if (MICROPY_PY_NETWORK_WIZNET5K) + string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/wiznet5k) + if((NOT (${ECHO_SUBMODULES})) AND NOT EXISTS ${MICROPY_DIR}/lib/wiznet5k/README.md) + message(FATAL_ERROR " wiznet5k not initialized.\n Run 'make BOARD=${MICROPY_BOARD} submodules'") + endif() + target_compile_definitions(${MICROPY_TARGET} PRIVATE MICROPY_PY_NETWORK_WIZNET5K=1 WIZCHIP_PREFIXED_EXPORTS=1 @@ -312,8 +321,6 @@ if (MICROPY_PY_NETWORK_WIZNET5K) list(APPEND MICROPY_SOURCE_EXTMOD ${MICROPY_DIR}/extmod/network_wiznet5k.c ) - - string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/wiznet5k) endif() # Add qstr sources for extmod and usermod, in case they are modified by components above. diff --git a/ports/rp2/Makefile b/ports/rp2/Makefile index 6f8c621c2a4a..6d2fc009642d 100644 --- a/ports/rp2/Makefile +++ b/ports/rp2/Makefile @@ -29,17 +29,10 @@ all: clean: $(RM) -rf $(BUILD) -GIT_SUBMODULES += lib/mbedtls lib/tinyusb - +# First ensure that pico-sdk is initialised, then use cmake to pick everything +# else (including board-specific dependencies). submodules: - # lib/pico-sdk is required for the cmake build to function (as used for boards other than PICO below) $(MAKE) -f ../../py/mkrules.mk GIT_SUBMODULES="lib/pico-sdk" submodules -ifeq ($(BOARD),PICO) - # Run the standard submodules target with minimum required submodules above - $(MAKE) -f ../../py/mkrules.mk GIT_SUBMODULES="$(GIT_SUBMODULES)" submodules -else - # Run submodules task through cmake interface to pick up any board specific dependencies. - GIT_SUBMODULES=$$(cmake -B $(BUILD)/submodules -DECHO_SUBMODULES=1 -DGIT_SUBMODULES="$(GIT_SUBMODULES)" ${CMAKE_ARGS} -S . 2>&1 | \ - grep 'GIT_SUBMODULES=' | cut -d= -f2); \ + GIT_SUBMODULES=$$(cmake -B $(BUILD)/submodules -DECHO_SUBMODULES=1 ${CMAKE_ARGS} -S . 2>&1 | \ + grep '^GIT_SUBMODULES=' | cut -d= -f2); \ $(MAKE) -f ../../py/mkrules.mk GIT_SUBMODULES="$${GIT_SUBMODULES}" submodules -endif From 19f5da9e1bf23821095da2252c2f3c2381f2fe21 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 8 Jul 2022 15:26:52 +1000 Subject: [PATCH 1553/4290] esp32/Makefile: Force micropython-lib as a required submodule. Also use mkrules.mk's submodule target rather than duplicating the call to `submodule sync`. Until we can find a way to use idf.py/cmake to discover submodules we have no way to discover optional or board-specific submodules so need to err on the side of including everything. Signed-off-by: Jim Mussared --- ports/esp32/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 88f946fa983b..b7d804d0730e 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -14,7 +14,11 @@ BAUD ?= 460800 PYTHON ?= python3 -GIT_SUBMODULES += lib/berkeley-db-1.xx +# Would be good to use cmake to discover submodules (see how rp2/Makefile does +# it), but on ESP32 the same trick doesn't work because "idf.py build" fails +# on berkeley-db dependency before printing out the submodule list. +# For now just force the submodule dependencies here. +GIT_SUBMODULES += lib/berkeley-db-1.xx lib/micropython-lib .PHONY: all clean deploy erase submodules FORCE @@ -52,4 +56,4 @@ erase: idf.py $(IDFPY_FLAGS) -p $(PORT) -b $(BAUD) erase_flash submodules: - git submodule update --init $(addprefix ../../,$(GIT_SUBMODULES)) + $(MAKE) -f ../../py/mkrules.mk GIT_SUBMODULES="$(GIT_SUBMODULES)" submodules From 58bed5ec14a2575fd53ca1822be80860f7e3023a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 8 Jul 2022 15:27:23 +1000 Subject: [PATCH 1554/4290] tools/ci.sh: Initialise submodules for more ports. Signed-off-by: Jim Mussared --- tools/ci.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/ci.sh b/tools/ci.sh index 6c3914b1449d..7e2479e43d38 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -245,8 +245,10 @@ function ci_qemu_arm_setup { function ci_qemu_arm_build { make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/qemu-arm submodules make ${MAKEOPTS} -C ports/qemu-arm CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 make ${MAKEOPTS} -C ports/qemu-arm clean + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test submodules make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test clean make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test BOARD=sabrelite test @@ -354,6 +356,7 @@ function ci_teensy_setup { } function ci_teensy_build { + make ${MAKEOPTS} -C ports/teensy submodules make ${MAKEOPTS} -C ports/teensy } @@ -577,6 +580,7 @@ function ci_unix_float_clang_run_tests { function ci_unix_settrace_build { make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix submodules make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE[@]}" } @@ -586,6 +590,7 @@ function ci_unix_settrace_run_tests { function ci_unix_settrace_stackless_build { make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix submodules make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" } @@ -661,6 +666,7 @@ function ci_windows_setup { function ci_windows_build { make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/windows submodules make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32- } From 579f330508e4ba46f4a71193582c36bdf7aa56bd Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 8 Jul 2022 15:00:33 +1000 Subject: [PATCH 1555/4290] py/mkenv.mk: Use micropython-lib from submodule by default. Also adds micropython-lib to 'make submodules' when using a frozen manifest (for make and cmake). Signed-off-by: Jim Mussared --- ports/windows/.appveyor.yml | 4 ++++ ports/windows/msvc/genhdr.targets | 2 +- py/mkenv.mk | 3 ++- py/mkrules.cmake | 7 ++++++- py/mkrules.mk | 7 +++++++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ports/windows/.appveyor.yml b/ports/windows/.appveyor.yml index d7192236dfbd..110511fe22c6 100644 --- a/ports/windows/.appveyor.yml +++ b/ports/windows/.appveyor.yml @@ -74,6 +74,10 @@ after_test: throw "$env:MSYSTEM mpy_cross build exited with code $LASTEXITCODE" } cd (Join-Path $env:APPVEYOR_BUILD_FOLDER 'ports/windows') + C:\msys64\usr\bin\bash.exe -l -c "make -B VARIANT=$($env:PyVariant) submodules" + if ($LASTEXITCODE -ne 0) { + throw "$env:MSYSTEM build exited with code $LASTEXITCODE" + } C:\msys64\usr\bin\bash.exe -l -c "make -B -j4 V=1 MICROPY_MPYCROSS=../../mpy-cross/mpy-cross.exe VARIANT=$($env:PyVariant)" if ($LASTEXITCODE -ne 0) { throw "$env:MSYSTEM build exited with code $LASTEXITCODE" diff --git a/ports/windows/msvc/genhdr.targets b/ports/windows/msvc/genhdr.targets index aa796088efec..308a6a1f5fe2 100644 --- a/ports/windows/msvc/genhdr.targets +++ b/ports/windows/msvc/genhdr.targets @@ -170,7 +170,7 @@ using(var outFile = System.IO.File.CreateText(OutputFile)) { MICROPY_MODULE_FROZEN_MPY=1;MICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool;%(PreprocessorDefinitions) - + diff --git a/py/mkenv.mk b/py/mkenv.mk index 2b247974b68e..cc04a8c0b307 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -57,7 +57,8 @@ MAKE_MANIFEST = $(PYTHON) $(TOP)/tools/makemanifest.py MAKE_FROZEN = $(PYTHON) $(TOP)/tools/make-frozen.py MPY_TOOL = $(PYTHON) $(TOP)/tools/mpy-tool.py -MPY_LIB_DIR = $(TOP)/../micropython-lib +MPY_LIB_SUBMODULE_DIR = $(TOP)/lib/micropython-lib +MPY_LIB_DIR = $(MPY_LIB_SUBMODULE_DIR) ifeq ($(MICROPY_MPYCROSS),) MICROPY_MPYCROSS = $(TOP)/mpy-cross/mpy-cross diff --git a/py/mkrules.cmake b/py/mkrules.cmake index d7be0f934b15..2f168ede6f2b 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -180,7 +180,12 @@ if(MICROPY_FROZEN_MANIFEST) # Note: target_compile_definitions already added earlier. if(NOT MICROPY_LIB_DIR) - set(MICROPY_LIB_DIR ${MICROPY_DIR}/../micropython-lib) + string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/micropython-lib) + set(MICROPY_LIB_DIR ${MICROPY_DIR}/lib/micropython-lib) + endif() + + if(NOT (${ECHO_SUBMODULES}) AND NOT EXISTS ${MICROPY_LIB_DIR}/README.md) + message(FATAL_ERROR " micropython-lib not initialized.\n Run 'make BOARD=${MICROPY_BOARD} submodules'") endif() # If MICROPY_MPYCROSS is not explicitly defined in the environment (which diff --git a/py/mkrules.mk b/py/mkrules.mk index a7c437386f8e..41ec4b064159 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -174,8 +174,15 @@ $(error Support for FROZEN_MPY_DIR was removed. Please use manifest.py instead, endif ifneq ($(FROZEN_MANIFEST),) +# If we're using the default submodule path for micropython-lib, then make +# sure it's included in "make submodules". +ifeq ($(MPY_LIB_DIR),$(MPY_LIB_SUBMODULE_DIR)) +GIT_SUBMODULES += lib/micropython-lib +endif + # to build frozen_content.c from a manifest $(BUILD)/frozen_content.c: FORCE $(BUILD)/genhdr/qstrdefs.generated.h $(BUILD)/genhdr/root_pointers.h | $(MICROPY_MPYCROSS_DEPENDENCY) + $(Q)test -e "$(MPY_LIB_DIR)/README.md" || (echo "Error: micropython-lib not initialized. Run 'make submodules'"; false) $(Q)$(MAKE_MANIFEST) -o $@ -v "MPY_DIR=$(TOP)" -v "MPY_LIB_DIR=$(MPY_LIB_DIR)" -v "PORT_DIR=$(shell pwd)" -v "BOARD_DIR=$(BOARD_DIR)" -b "$(BUILD)" $(if $(MPY_CROSS_FLAGS),-f"$(MPY_CROSS_FLAGS)",) --mpy-tool-flags="$(MPY_TOOL_FLAGS)" $(FROZEN_MANIFEST) endif From 6152bbe3dd82fb7dc1b063e24c19a42af03bf321 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 28 Jul 2022 19:25:59 -0500 Subject: [PATCH 1556/4290] stm32/boards/LEGO_HUB_NO6: Fix typo in README. This fixes a typo in the build directory path. Signed-off-by: David Lechner --- ports/stm32/boards/LEGO_HUB_NO6/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/README.md b/ports/stm32/boards/LEGO_HUB_NO6/README.md index 376d0f2b0e44..cc67b6a4bb6b 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/README.md +++ b/ports/stm32/boards/LEGO_HUB_NO6/README.md @@ -112,8 +112,8 @@ To use this feature, build the firmware (see above for details) then gzip it and copy the resulting file to the Hub (eg using mpremote): $ make BOARD=LEGO_HUB_NO6 - $ gzip boards/LEGO_HUB_NO6/firmware.dfu - $ mpremote cp boards/LEGO_HUB_NO6/firmware.dfu.gz : + $ gzip build-LEGO_HUB_NO6/firmware.dfu + $ mpremote cp build-LEGO_HUB_NO6/firmware.dfu.gz : Then get a REPL on the Hub and execute: From 7cc6df3303f467e218a6ac4f12924eac0ed15045 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 29 Jul 2022 13:58:33 -0500 Subject: [PATCH 1557/4290] stm32/boards/LEGO_HUB_NO6: Use named pins. This changes all uses of pins to use the alias names of the pins. This makes the code easier to understand and will also allow sharing more code with LEGO_HUB_NO7. Signed-off-by: David Lechner --- ports/stm32/boards/LEGO_HUB_NO6/appupdate.py | 9 +++- ports/stm32/boards/LEGO_HUB_NO6/board_init.c | 2 +- ports/stm32/boards/LEGO_HUB_NO6/hub_display.c | 30 ++++++------ .../stm32/boards/LEGO_HUB_NO6/mpconfigboard.h | 49 +++++++++---------- ports/stm32/boards/LEGO_HUB_NO6/pins.csv | 8 +-- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py b/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py index 65954454a582..0927f16111fe 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py +++ b/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py @@ -23,8 +23,13 @@ def update_app(filename): key = struct.pack("CCR2 = 2; tim->EGR = 1; // UG - mp_hal_pin_config(pin_B15, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 9); + mp_hal_pin_config(pyb_pin_TLC_GS_CLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 9); } static void hub_display_spi_init(void) { @@ -93,9 +93,9 @@ static void hub_display_spi_init(void) { spi->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | 0 << SPI_CR1_BR_Pos | SPI_CR1_MSTR; spi->CR1 |= SPI_CR1_SPE; - mp_hal_pin_config(pin_A5, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); - mp_hal_pin_config(pin_A6, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); - mp_hal_pin_config(pin_A7, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); + mp_hal_pin_config(pyb_pin_TLC_SCLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); + mp_hal_pin_config(pyb_pin_TLC_SOUT, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); + mp_hal_pin_config(pyb_pin_TLC_SIN, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); } static void hub_display_spi_write(uint8_t value) { @@ -123,9 +123,9 @@ static void hub_display_latch_ctrl(uint8_t dc, uint32_t mc, uint32_t bc, uint8_t for (int i = 0; i < 42; ++i) { hub_display_spi_write(dc); } - mp_hal_pin_high(pin_A15); + mp_hal_pin_high(pyb_pin_TLC_LAT); mp_hal_delay_us(1); - mp_hal_pin_low(pin_A15); + mp_hal_pin_low(pyb_pin_TLC_LAT); } void hub_display_set(uint8_t led, uint16_t value) { @@ -142,17 +142,17 @@ void hub_display_update(void) { for (int i = 0; i < 96; ++i) { hub_display_spi_write(hub_display_gs_state[95 - i]); } - mp_hal_pin_high(pin_A15); + mp_hal_pin_high(pyb_pin_TLC_LAT); mp_hal_delay_us(1); - mp_hal_pin_low(pin_A15); + mp_hal_pin_low(pyb_pin_TLC_LAT); } void hub_display_on(void) { if (hub_display_init) { return; } - mp_hal_pin_output(pin_A15); - mp_hal_pin_low(pin_A15); + mp_hal_pin_output(pyb_pin_TLC_LAT); + mp_hal_pin_low(pyb_pin_TLC_LAT); hub_display_spi_init(); for (int i = 0; i < 2; ++i) { hub_display_latch_ctrl(0xff, 0, 0x1fffff, 0x11); @@ -171,10 +171,10 @@ void hub_display_off(void) { __HAL_RCC_SPI1_CLK_DISABLE(); __HAL_RCC_SPI1_FORCE_RESET(); __HAL_RCC_SPI1_RELEASE_RESET(); - mp_hal_pin_config(pin_A5, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config(pin_A6, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config(pin_A7, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config(pin_A15, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config(pin_B15, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pyb_pin_TLC_SCLK, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pyb_pin_TLC_SOUT, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pyb_pin_TLC_SIN, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pyb_pin_TLC_LAT, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pyb_pin_TLC_GS_CLK, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); hub_display_init = false; } diff --git a/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h index cab46fa02d57..7f0b1fbe45c9 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h +++ b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h @@ -34,41 +34,40 @@ // UART buses // Bluetooth HCI -#define MICROPY_HW_UART2_CTS (pin_D3) -#define MICROPY_HW_UART2_RTS (pin_D4) -#define MICROPY_HW_UART2_TX (pin_D5) -#define MICROPY_HW_UART2_RX (pin_D6) +#define MICROPY_HW_UART2_CTS (pyb_pin_BT_CTS) +#define MICROPY_HW_UART2_RTS (pyb_pin_BT_RTS) +#define MICROPY_HW_UART2_TX (pyb_pin_BT_TX) +#define MICROPY_HW_UART2_RX (pyb_pin_BT_RX) // Port B -#define MICROPY_HW_UART4_TX (pin_D1) -#define MICROPY_HW_UART4_RX (pin_D0) +#define MICROPY_HW_UART4_TX (pyb_pin_PORTB_TX) +#define MICROPY_HW_UART4_RX (pyb_pin_PORTB_RX) // Port D -#define MICROPY_HW_UART5_TX (pin_C12) -#define MICROPY_HW_UART5_RX (pin_D2) +#define MICROPY_HW_UART5_TX (pyb_pin_PORTD_TX) +#define MICROPY_HW_UART5_RX (pyb_pin_PORTD_RX) // Port A -#define MICROPY_HW_UART7_TX (pin_E8) -#define MICROPY_HW_UART7_RX (pin_E7) +#define MICROPY_HW_UART7_TX (pyb_pin_PORTA_TX) +#define MICROPY_HW_UART7_RX (pyb_pin_PORTA_RX) // Port C -#define MICROPY_HW_UART8_TX (pin_E1) -#define MICROPY_HW_UART8_RX (pin_E0) +#define MICROPY_HW_UART8_TX (pyb_pin_PORTC_TX) +#define MICROPY_HW_UART8_RX (pyb_pin_PORTC_RX) // Port F -#define MICROPY_HW_UART9_TX (pin_D15) -#define MICROPY_HW_UART9_RX (pin_D14) +#define MICROPY_HW_UART9_TX (pyb_pin_PORTF_TX) +#define MICROPY_HW_UART9_RX (pyb_pin_PORTF_RX) // Port E -#define MICROPY_HW_UART10_TX (pin_E3) -#define MICROPY_HW_UART10_RX (pin_E2) +#define MICROPY_HW_UART10_TX (pyb_pin_PORTE_TX) +#define MICROPY_HW_UART10_RX (pyb_pin_PORTE_RX) // SPI buses -#define MICROPY_HW_SPI1_NSS (pin_A4) // shared with DAC -#define MICROPY_HW_SPI1_SCK (pin_A5) // shared with DAC -#define MICROPY_HW_SPI1_MISO (pin_A6) -#define MICROPY_HW_SPI1_MOSI (pin_A7) -#define MICROPY_HW_SPI2_NSS (pin_B12) -#define MICROPY_HW_SPI2_SCK (pin_B13) -#define MICROPY_HW_SPI2_MISO (pin_C2) -#define MICROPY_HW_SPI2_MOSI (pin_C3) +#define MICROPY_HW_SPI1_SCK (pyb_pin_TLC_SCLK) +#define MICROPY_HW_SPI1_MISO (pyb_pin_TLC_SOUT) +#define MICROPY_HW_SPI1_MOSI (pyb_pin_TLC_SIN) +#define MICROPY_HW_SPI2_NSS (pyb_pin_FLASH_NSS) +#define MICROPY_HW_SPI2_SCK (pyb_pin_FLASH_SCK) +#define MICROPY_HW_SPI2_MISO (pyb_pin_FLASH_MISO) +#define MICROPY_HW_SPI2_MOSI (pyb_pin_FLASH_MOSI) // USB config -#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pyb_pin_USB_VBUS) #define MICROPY_HW_USB_FS (1) #define MICROPY_HW_USB_MSC (1) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/pins.csv b/ports/stm32/boards/LEGO_HUB_NO6/pins.csv index 9e56e2c79de4..1d0b8f35d8d8 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/pins.csv +++ b/ports/stm32/boards/LEGO_HUB_NO6/pins.csv @@ -26,14 +26,14 @@ PORTD_M1,PB8 PORTD_M2,PB9 LSM6_SCL,PB10 ,PB11 -,PB12 -,PB13 +FLASH_NSS,PB12 +FLASH_SCK,PB13 ,PB14 TLC_GS_CLK,PB15 BAT_IMON_ADC,PC0 BAT_VMON_ADC,PC1 -,PC2 -,PC3 +FLASH_MISO,PC2 +FLASH_MOSI,PC3 CHGOK_CENBTN_3V3OK_ADC,PC4 PORTF_EN,PC5 PORTE_M1,PC6 From 9a51273d96405527e3950441cfebc6c7314a6bcf Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 29 Jul 2022 15:25:10 -0500 Subject: [PATCH 1558/4290] stm32/boards/LEGO_HUB_NO6/appupdate: Detect filesystem size at runtime. This changes appupdate.py to get the filesystem size at runtime. This will allow the code to be shared with LEGO_HUB_NO7 which has a similar flash chip with a different size. Signed-off-by: David Lechner --- ports/stm32/boards/LEGO_HUB_NO6/appupdate.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py b/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py index 0927f16111fe..57b24d3f2e60 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py +++ b/ports/stm32/boards/LEGO_HUB_NO6/appupdate.py @@ -2,13 +2,20 @@ # MIT license; Copyright (c) 2022 Damien P. George from micropython import const -import struct, machine, fwupdate, spiflash +import struct, machine, fwupdate, spiflash, pyb + +_IOCTL_BLOCK_COUNT = const(4) +_IOCTL_BLOCK_SIZE = const(5) _SPIFLASH_UPDATE_KEY_ADDR = const(1020 * 1024) _SPIFLASH_UPDATE_KEY_VALUE = const(0x12345678) _FILESYSTEM_ADDR = const(0x8000_0000 + 1024 * 1024) -_FILESYSTEM_LEN = const(31 * 1024 * 1024) + +# Roundabout way to get actual filesystem size from config. +# This takes into account the 1M "reserved" section of the flash memory. +flash = pyb.Flash(start=0) +_FILESYSTEM_LEN = flash.ioctl(_IOCTL_BLOCK_COUNT, None) * flash.ioctl(_IOCTL_BLOCK_SIZE, None) def update_app(filename): @@ -30,6 +37,8 @@ def update_app(filename): baudrate=50_000_000, ) cs = machine.Pin(machine.Pin.board.FLASH_NSS, machine.Pin.OUT, value=1) + + # We can't use pyb.Flash() because we need to write to the "reserved" 1M area. flash = spiflash.SPIFlash(spi, cs) # Write the update key and elements to the SPI flash. From f69af1661923c05149b2a998d5d074d85c51026d Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 29 Jul 2022 15:45:13 -0500 Subject: [PATCH 1559/4290] stm32/boards/LEGO_HUB_NO6/spiflash: Pick command type at runtime. This changes spiflash.py to read the flash chip ID at runtime to select the read/write/erase commands. This will allow the code to be shared with LEGO_HUB_NO7 which doesn't use the 32-bit commands. Also remove an unused constant while we are touching this. Signed-off-by: David Lechner --- ports/stm32/boards/LEGO_HUB_NO6/spiflash.py | 24 +++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/spiflash.py b/ports/stm32/boards/LEGO_HUB_NO6/spiflash.py index e052f7738b70..e483ace95084 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/spiflash.py +++ b/ports/stm32/boards/LEGO_HUB_NO6/spiflash.py @@ -4,18 +4,34 @@ from micropython import const _PAGE_SIZE = const(256) # maximum bytes writable in one SPI transfer +_CMD_WRITE = const(0x02) +_CMD_READ = const(0x03) _CMD_RDSR = const(0x05) _CMD_WREN = const(0x06) _CMD_WRITE_32 = const(0x12) _CMD_READ_32 = const(0x13) +_CMD_SEC_ERASE = const(0x20) _CMD_SEC_ERASE_32 = const(0x21) -_CMD_C4READ_32 = const(0xEC) +_CMD_JEDEC_ID = const(0x9F) class SPIFlash: def __init__(self, spi, cs): self.spi = spi self.cs = cs + self.id = self._get_id() + # flash chip on Hub No. 6 uses 32-bit addressing + _32_bit = self.id == b"\xef\x40\x19" + self._READ = _CMD_READ_32 if _32_bit else _CMD_READ + self._WRITE = _CMD_WRITE_32 if _32_bit else _CMD_WRITE + self._ERASE = _CMD_SEC_ERASE_32 if _32_bit else _CMD_SEC_ERASE + + def _get_id(self): + self.cs(0) + self.spi.write(bytearray([_CMD_JEDEC_ID])) + buf = self.spi.read(3) + self.cs(1) + return buf def _wait_wel1(self): # wait WEL=1 @@ -52,11 +68,11 @@ def _flash_modify(self, cmd, addr, buf): self._wait_wip0() def erase_block(self, addr): - self._flash_modify(_CMD_SEC_ERASE_32, addr, None) + self._flash_modify(self._ERASE, addr, None) def readinto(self, addr, buf): self.cs(0) - self.spi.write(bytearray([_CMD_READ_32, addr >> 16, addr >> 8, addr])) + self.spi.write(bytearray([self._READ, addr >> 16, addr >> 8, addr])) self.spi.readinto(buf) self.cs(1) @@ -67,7 +83,7 @@ def write(self, addr, buf): buf_offset = 0 while remain: l = min(_PAGE_SIZE - offset, remain) - self._flash_modify(_CMD_WRITE_32, addr, buf[buf_offset : buf_offset + l]) + self._flash_modify(self._WRITE, addr, buf[buf_offset : buf_offset + l]) remain -= l addr += l buf_offset += l From 0f0f2351bb3c45801250352e72e026e1671fd5d8 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 14 Jun 2022 22:32:44 -0500 Subject: [PATCH 1560/4290] stm32/boards/LEGO_HUB_NO6/cc2564: Make timer configurable. This adds configurable macros to define the timer and channel used to provide the Bluetooth 32768 MHz clock. This will allow code to be shared with LEGO_HUB_NO7. Signed-off-by: David Lechner --- ports/stm32/boards/LEGO_HUB_NO6/cc2564.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c b/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c index c54daf3002fe..50ba81c57ac1 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c +++ b/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c @@ -38,6 +38,12 @@ #define CC2564_PIN_BT_SLOWCLK (pyb_pin_BT_SLOWCLK) #define CC2564_PIN_BT_ENABLE (pyb_pin_BT_ENABLE) +// slight difference between LEGO_HUB_NO6 and LEGO_HUB_NO7 +#ifndef CC2564_TIMER_BT_SLOWCLOCK_TIM +#define CC2564_TIMER_BT_SLOWCLOCK_TIM 8 +#define CC2564_TIMER_BT_SLOWCLOCK_TIM_CH 4 +#endif + STATIC void cc2564_wait_cts_low(mp_hal_pin_obj_t cts, uint32_t timeout_ms) { for (int i = 0; i < timeout_ms; ++i) { if (mp_hal_pin_read(cts) == 0) { @@ -53,18 +59,18 @@ int mp_bluetooth_hci_controller_init(void) { mp_hal_pin_low(CC2564_PIN_BT_ENABLE); // Output a 32768Hz signal on BTSLOWCLK. - // tim8 = pyb.Timer(8, freq=32768) - // tim8_ch4 = tim8.channel(4, pyb.Timer.PWM, pin=btclk) - // tim8_ch4.pulse_width_percent(50) - mp_obj_t args[6] = { MP_OBJ_NEW_SMALL_INT(8), MP_OBJ_NEW_QSTR(MP_QSTR_freq), MP_OBJ_NEW_SMALL_INT(32768), MP_OBJ_NULL }; - mp_obj_t tim8 = pyb_timer_type.make_new(&pyb_timer_type, 1, 1, args); - mp_load_method(tim8, MP_QSTR_channel, args); - args[2] = MP_OBJ_NEW_SMALL_INT(4); + // tim = pyb.Timer(TIM, freq=32768) + // tim_ch = tim.channel(TIM_CH, pyb.Timer.PWM, pin=btclk) + // tim_ch.pulse_width_percent(50) + mp_obj_t args[6] = { MP_OBJ_NEW_SMALL_INT(CC2564_TIMER_BT_SLOWCLOCK_TIM), MP_OBJ_NEW_QSTR(MP_QSTR_freq), MP_OBJ_NEW_SMALL_INT(32768), MP_OBJ_NULL }; + mp_obj_t tim = pyb_timer_type.make_new(&pyb_timer_type, 1, 1, args); + mp_load_method(tim, MP_QSTR_channel, args); + args[2] = MP_OBJ_NEW_SMALL_INT(CC2564_TIMER_BT_SLOWCLOCK_TIM_CH); args[3] = MP_OBJ_NEW_SMALL_INT(0); // CHANNEL_MODE_PWM_NORMAL args[4] = MP_OBJ_NEW_QSTR(MP_QSTR_pin); args[5] = (mp_obj_t)CC2564_PIN_BT_SLOWCLK; - mp_obj_t tim8_ch4 = mp_call_method_n_kw(2, 1, args); - mp_load_method(tim8_ch4, MP_QSTR_pulse_width_percent, args); + mp_obj_t tim_ch = mp_call_method_n_kw(2, 1, args); + mp_load_method(tim_ch, MP_QSTR_pulse_width_percent, args); args[2] = MP_OBJ_NEW_SMALL_INT(50); mp_call_method_n_kw(1, 0, args); From 10f85fee183404a3cba2795e6cd22c12be742fb3 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 14 Jun 2022 22:32:44 -0500 Subject: [PATCH 1561/4290] stm32/boards/LEGO_HUB_NO7: Add LEGO Hub No. 7 board definition. This adds support for the LEGO Hub No. 7, aka LEGO Technic Small hub, aka LEGO SPIKE Essential hub. This board is largely similar to Hub No. 6: - Same MCU (STM32F413 - different packaging with fewer pins). - Same Bluetooth chip (TI CC2564). - Same IMU chip. - Similar external flash chip - 4MiB instead of 32MiB. - 2 I/O ports instead of 6. - No display - only status and battery LEDs. - Different LED driver chip. - Only 1 button which is also the power button. - No speaker. Signed-off-by: David Lechner --- ports/stm32/boards/LEGO_HUB_NO7/README.md | 135 +++++++++++ ports/stm32/boards/LEGO_HUB_NO7/bdev.c | 3 + .../LEGO_HUB_NO7/bluetooth_init_cc2564C_1.5.c | 3 + ports/stm32/boards/LEGO_HUB_NO7/board.json | 13 ++ ports/stm32/boards/LEGO_HUB_NO7/board_init.c | 212 ++++++++++++++++++ ports/stm32/boards/LEGO_HUB_NO7/cc2564.c | 6 + ports/stm32/boards/LEGO_HUB_NO7/hub_display.c | 190 ++++++++++++++++ ports/stm32/boards/LEGO_HUB_NO7/hub_display.h | 4 + ports/stm32/boards/LEGO_HUB_NO7/manifest.py | 5 + .../stm32/boards/LEGO_HUB_NO7/mpconfigboard.h | 152 +++++++++++++ .../boards/LEGO_HUB_NO7/mpconfigboard.mk | 50 +++++ ports/stm32/boards/LEGO_HUB_NO7/pins.csv | 114 ++++++++++ .../boards/LEGO_HUB_NO7/stm32f4xx_hal_conf.h | 23 ++ 13 files changed, 910 insertions(+) create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/README.md create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/bdev.c create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/bluetooth_init_cc2564C_1.5.c create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/board.json create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/board_init.c create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/cc2564.c create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/hub_display.c create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/hub_display.h create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/manifest.py create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.h create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.mk create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/pins.csv create mode 100644 ports/stm32/boards/LEGO_HUB_NO7/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/LEGO_HUB_NO7/README.md b/ports/stm32/boards/LEGO_HUB_NO7/README.md new file mode 100644 index 000000000000..8159cf3f4713 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/README.md @@ -0,0 +1,135 @@ +LEGO Hub No.7 +============= + +This board definition is for the LEGO Hub No. 7, a LEGO control unit with 1 button, +2 RGB LEDs, 2 Powered Up ports, 6-DOF sensor, Bluetooth, USB, 4MiB external SPI +flash storage, and a rechargeable battery. + +Features that are currently supported: +- standard MicroPython +- machine and bluetooth modules +- filesystem +- USB VCP, MSC and HID + +The Hub has a bootloader preinstalled at 0x08000000 (which is 32kiB in size) which +cannot be erased. This bootloader is entered by holding down the button for 5 seconds, +at which point the USB DFU device appears. If the battery is installed then the +RGB LED will flash purple. If the battery is not installed, the LED will flash orange +briefly and then the hub will turn off (so having the battery installed is required). +When this bootloader is active, the flash from 0x08008000 and up can be erased +and programmed via USB DFU. + +The built-in bootloader has some drawbacks: it cannot be entered programmatically, +and it does not keep the Hub powered up when running from battery (which requires +keeping BAT_PWR_EN high). As such, this board is configured to work with mboot as +a secondary bootloader: mboot is placed at 0x08008000 and the main application +firmware at 0x08010000. When mboot is installed it can be entered programatically +via machine.bootloader(). + +Backing up original Hub firmware +-------------------------------- + +Before installing MicroPython it is advised to backup the original LEGO firmware that +the Hub comes installed with. To do this, enter the built-in bootloader by holding +down the power button for 5 seconds while powering up the Hub via USB (you may +need to take out the battery and disconnect USB to power off the Hub first). Then +run the following command from the root of this repository: + + $ cd ports/stm32 + $ make BOARD=LEGO_HUB_NO7 backup-hub-firmware + +This will create a file called `lego_hub_firmware.dfu`. Put this file in a safe +location. To restore it, enter the built-in bootloader again and run: + + $ make BOARD=LEGO_HUB_NO7 restore-hub-firmware + +This will restore the original firmware but not the filesystem. To recreate the +original filesystem the Hub must be updated using the appropriate LEGO PC +application. + +Installing MicroPython +---------------------- + +You first need to build and install mboot, which only needs to be done once. From +the root of this repository run: + + $ cd ports/stm32/mboot + $ make BOARD=LEGO_HUB_NO7 + +Now enter the built-in bootloader by holding down the power button for 5 +seconds while powering up the Hub via USB (you may need to take out the battery +and disconnect USB to power off the Hub first). Then run: + + $ make BOARD=LEGO_HUB_NO7 deploy + +mboot should now be installed. To enter mboot, remove USB and the battery. +Connect the USB cable (the other end of the USB cable must be connected to +something that provides power). The status light should start cycling through +different colors. Replace the battery (the button will not work without the +battery present). Press the button to activate the desired boot mode: + +- Status light is red - run application (normal boot). +- Status light is green - run application in factory file system mode. +- Status light is blue - run application in safe mode. +- Status light is white - start DFU on the USB port. + + +Now build MicroPython (start at the root of this repository): + + $ cd mpy-cross + $ make + $ cd ../ports/stm32 + $ make submodules + $ make BOARD=LEGO_HUB_NO7 + +And deploy to the Hub (making sure mboot DFU is active, the center button is +blinking red): + + $ make BOARD=LEGO_HUB_NO7 deploy + +If successful, the Hub should now appear as a USB serial and mass storage device. + +Using MicroPython on the Hub +---------------------------- + +Access the MicroPython REPL using mpremote (pip install mpremote), or with any +serial terminal program. + +To scan for BLE devices: + + >>> import bluetooth + >>> ble = bluetooth.BLE() + >>> ble.irq(lambda *x: print(*x)) + >>> ble.active(1) + >>> ble.gap_scan(2000, 625, 625) + +Use help("modules") to see available built-in modules. + +Updating MicroPython from the Hub's filesystem +---------------------------------------------- + +You can update the MicroPython application firmware using the instructions above +for installing the firmware for the first time. The Hub also supports updating +the application firmware from within MicroPython itself, using the on-board +filesystem. + +To use this feature, build the firmware (see above for details) then gzip it and +copy the resulting file to the Hub (eg using mpremote): + + $ make BOARD=LEGO_HUB_NO7 + $ gzip build-LEGO_HUB_NO7/firmware.dfu + $ mpremote cp build-LEGO_HUB_NO7/firmware.dfu.gz : + +Then get a REPL on the Hub and execute: + + >>> import appupdate + >>> appupdate.update_app("firmware.dfu.gz") + +You can alternatively run this REPL command using mpremote: + + $ mpremote exec --no-follow "import appupdate; appupdate.update_app('firmware.dfu.gz')" + +At that point the Hub should restart and the LED on the central button will flash +different colours. Once the update is complete the LED will stop flashing and the +Hub will appear again as a USB device. The application firmware is now updated +and you can remove the firmware.dfu.gz file if desired. diff --git a/ports/stm32/boards/LEGO_HUB_NO7/bdev.c b/ports/stm32/boards/LEGO_HUB_NO7/bdev.c new file mode 100644 index 000000000000..f104c0f3f463 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/bdev.c @@ -0,0 +1,3 @@ +// LEGO_HUB_NO7 is identical to LEGO_HUB_NO6 in this regard. + +#include "../LEGO_HUB_NO6/bdev.c" diff --git a/ports/stm32/boards/LEGO_HUB_NO7/bluetooth_init_cc2564C_1.5.c b/ports/stm32/boards/LEGO_HUB_NO7/bluetooth_init_cc2564C_1.5.c new file mode 100644 index 000000000000..6ea298f68839 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/bluetooth_init_cc2564C_1.5.c @@ -0,0 +1,3 @@ +// LEGO_HUB_NO7 is identical to LEGO_HUB_NO6 in this regard. + +#include "../LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c" diff --git a/ports/stm32/boards/LEGO_HUB_NO7/board.json b/ports/stm32/boards/LEGO_HUB_NO7/board.json new file mode 100644 index 000000000000..1ef02c17a063 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/board.json @@ -0,0 +1,13 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [], + "images": [], + "mcu": "stm32f4", + "product": "Hub No.7", + "thumbnail": "", + "url": "", + "vendor": "LEGO" +} diff --git a/ports/stm32/boards/LEGO_HUB_NO7/board_init.c b/ports/stm32/boards/LEGO_HUB_NO7/board_init.c new file mode 100644 index 000000000000..7b155b1c3cea --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/board_init.c @@ -0,0 +1,212 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021-2022 Damien P. George + * Copyright (c) 2022 David Lechner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mphal.h" +#include "irq.h" + +void board_init(void) { + if (query_irq() == IRQ_STATE_DISABLED) { + enable_irq(IRQ_STATE_ENABLED); + } + + // Enable 3V3 for all ports + mp_hal_pin_output(pyb_pin_PORT_3V3_EN); + mp_hal_pin_high(pyb_pin_PORT_3V3_EN); + + // Port A + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTA_EN); + mp_hal_pin_low(pyb_pin_PORTA_EN); + + // Port B + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTB_EN); + mp_hal_pin_low(pyb_pin_PORTB_EN); +} + +#if BUILDING_MBOOT + +#include "drivers/memory/spiflash.h" +#include "mboot/mboot.h" +#include "boardctrl.h" +#include "adc.h" +#include "hub_display.h" + +#define RESET_MODE_NUM_STATES (4) +#define RESET_MODE_TIMEOUT_CYCLES (8) + +// Location and value for the SPI flash update key. If this key exists at the defined +// location then mboot will attempt to do a filesystem-load update of the main firmware. +// This makes the update robust to power failures: if the update does not complete then +// it will be restarted the next time it powers up. Only when it fully completes will +// this key be erased, and then the application can run. +#define SPIFLASH_UPDATE_KEY_ADDR (1020 * 1024) +#define SPIFLASH_UPDATE_KEY_VALUE (0x12345678) + +static void board_led_pattern(int reset_mode, uint16_t brightness) { + switch (reset_mode) { + case BOARDCTRL_RESET_MODE_NORMAL: + // set status light to red + hub_display_set(3, brightness); + hub_display_set(4, 0); + hub_display_set(5, 0); + break; + case BOARDCTRL_RESET_MODE_SAFE_MODE: + // set status light to green + hub_display_set(3, 0); + hub_display_set(4, brightness); + hub_display_set(5, 0); + break; + case BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM: + // set status light to blue + hub_display_set(3, 0); + hub_display_set(4, 0); + hub_display_set(5, brightness); + break; + case BOARDCTRL_RESET_MODE_BOOTLOADER: + // set status light to white + hub_display_set(3, brightness); + hub_display_set(4, brightness); + hub_display_set(5, brightness); + break; + } + + hub_display_update(); +} + +static void board_battery_init(void) { + mp_hal_pin_config(pyb_pin_BAT_VMON_ADC, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0); + adc_config(ADC1, 12); +} + +// returns true if the battery is pressed, otherwise false +static int board_battery_state(void) { + uint16_t value = adc_config_and_read_u16(ADC1, 6, ADC_SAMPLETIME_15CYCLES); + // If battery voltage is above USB voltage, then we consider the battery + // to be present. + return value > 41100; // 41100 is approx 5.5V +} + +static void board_button_init(void) { + mp_hal_pin_input(pyb_pin_BUTTON); +} + +// returns true if the button is pressed, otherwise false +static int board_button_state(void) { + // button is active low + return !mp_hal_pin_read(pyb_pin_BUTTON); +} + +void board_mboot_cleanup(int reset_mode) { + board_led_pattern(0, 0); + hub_display_off(); +} + +void board_mboot_led_init(void) { + hub_display_on(); +} + +void board_mboot_led_state(int led, int state) { + if (state) { + hub_display_set(3 + led, 0x7fff); + } else { + hub_display_set(3 + led, 0); + } + + hub_display_update(); +} + +int board_mboot_get_reset_mode(uint32_t *initial_r0) { + board_battery_init(); + board_button_init(); + int reset_mode = BOARDCTRL_RESET_MODE_NORMAL; + + if (board_battery_state()) { + // Battery is present, check flash for update key and start an update if the key exists. + // Otherwise, boot normally. + + // Initialise the external SPI flash. + MBOOT_SPIFLASH_SPIFLASH->config = MBOOT_SPIFLASH_CONFIG; + mp_spiflash_init(MBOOT_SPIFLASH_SPIFLASH); + + // Read in the key. + uint32_t buf; + mp_spiflash_read(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR, 4, (uint8_t *)&buf); + + if (buf == SPIFLASH_UPDATE_KEY_VALUE) { + // The key has the correct value, so read in the FS-load elements and enter the bootloader. + mp_spiflash_read(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR + 4, ELEM_DATA_SIZE, ELEM_DATA_START); + *initial_r0 = MBOOT_INITIAL_R0_KEY_FSLOAD; + reset_mode = BOARDCTRL_RESET_MODE_BOOTLOADER; + } + } else { + // Battery is not present. Cycle through reset modes until button is pressed. + systick_init(); + hub_display_on(); + reset_mode = 0; + for (int i = 0; i < (RESET_MODE_NUM_STATES * RESET_MODE_TIMEOUT_CYCLES + 1) * 64; i++) { + if (i % 64 == 0) { + if (++reset_mode > RESET_MODE_NUM_STATES) { + reset_mode = BOARDCTRL_RESET_MODE_NORMAL; + } + board_led_pattern(reset_mode, 0x7fff); + } + + if (board_button_state()) { + break; + } + + mp_hal_delay_ms(19); + } + + // Flash the selected reset mode. + for (int i = 0; i < 6; i++) { + board_led_pattern(reset_mode, 0x0fff); + mp_hal_delay_ms(50); + board_led_pattern(reset_mode, 0x7fff); + mp_hal_delay_ms(50); + } + + mp_hal_delay_ms(300); + } + + board_led_pattern(0, 0); + return reset_mode; +} + +void board_mboot_state_change(int state, uint32_t arg) { + if (state == MBOOT_STATE_FSLOAD_END) { + // The FS-load update completed (either with success or failure), so erase the + // update key and write the result of the FS-load operation into flash. + mp_spiflash_erase_block(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR); + mp_spiflash_write(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR + 4, 4, (const uint8_t *)&arg); + } + + mboot_state_change_default(state, arg); +} + +#endif diff --git a/ports/stm32/boards/LEGO_HUB_NO7/cc2564.c b/ports/stm32/boards/LEGO_HUB_NO7/cc2564.c new file mode 100644 index 000000000000..e5bfe1b4d4ca --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/cc2564.c @@ -0,0 +1,6 @@ +// LEGO_HUB_NO7 is nearly identical to LEGO_HUB_NO6 in this regard. + +#define CC2564_TIMER_BT_SLOWCLOCK_TIM 2 +#define CC2564_TIMER_BT_SLOWCLOCK_TIM_CH 2 + +#include "../LEGO_HUB_NO6/cc2564.c" diff --git a/ports/stm32/boards/LEGO_HUB_NO7/hub_display.c b/ports/stm32/boards/LEGO_HUB_NO7/hub_display.c new file mode 100644 index 000000000000..e19485b0646f --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/hub_display.c @@ -0,0 +1,190 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * Copyright (c) 2022 David Lechner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mphal.h" +#include "hub_display.h" + +#include STM32_HAL_H + +#define I2C_ADDR 0x28 + +// Registers +#define DEVICE_CONFIG0 0x00 +#define DEVICE_CONFIG1 0x01 +#define LED_CONFIG0 0x02 +#define BANK_BRIGHTNESS 0x03 +#define BANK_A_COLOR 0x04 +#define BANK_B_COLOR 0x05 +#define BANK_C_COLOR 0x06 +#define LED0_BRIGHTNESS 0x07 +#define LED1_BRIGHTNESS 0x08 +#define LED2_BRIGHTNESS 0x09 +#define LED3_BRIGHTNESS 0x0A +#define OUT0_COLOR 0x0B +#define OUT1_COLOR 0x0C +#define OUT2_COLOR 0x0D +#define OUT3_COLOR 0x0E +#define OUT4_COLOR 0x0F +#define OUT5_COLOR 0x10 +#define OUT6_COLOR 0x11 +#define OUT7_COLOR 0x12 +#define OUT8_COLOR 0x13 +#define OUT9_COLOR 0x14 +#define OUT10_COLOR 0x15 +#define OUT11_COLOR 0x16 +#define RESET 0x17 + +// Flags +#define DEVICE_CONFIG0_CHIP_EN (1 << 6) +#define DEVICE_CONFIG1_LOG_SCALE_EN (1 << 5) +#define DEVICE_CONFIG1_POWER_SAVE_EN (1 << 4) +#define DEVICE_CONFIG1_AUTO_INCR_EN (1 << 3) +#define DEVICE_CONFIG1_PWM_DITHERING_EN (1 << 2) +#define DEVICE_CONFIG1_MAX_CURRENT_OPTION (1 << 1) +#define DEVICE_CONFIG1_LED_GLOBAL_OFF (1 << 0) +#define LED_CONFIG0_LED3_BANK_EN (1 << 3) +#define LED_CONFIG0_LED2_BANK_EN (1 << 2) +#define LED_CONFIG0_LED1_BANK_EN (1 << 1) +#define LED_CONFIG0_LED0_BANK_EN (1 << 0) + +#define LP50XX_NUM_CH 6 + +// channel mapping: +// CH 0 = battery LED - red +// CH 1 = battery LED - green +// CH 2 = battery LED - blue +// CH 3 = status LED - red +// CH 4 = status LED - green +// CH 5 = status LED - blue + +#define FMPI2C_CONVERT_TIMINGS(PRESC, SCLDEL, SDADEL, SCLH, SCLL) \ + (((PRESC) << FMPI2C_TIMINGR_PRESC_Pos) | \ + ((SCLDEL) << FMPI2C_TIMINGR_SCLDEL_Pos) | \ + ((SDADEL) << FMPI2C_TIMINGR_SDADEL_Pos) | \ + ((SCLH) << FMPI2C_TIMINGR_SCLH_Pos) | \ + ((SCLL) << FMPI2C_TIMINGR_SCLL_Pos)) + +static FMPI2C_HandleTypeDef hub_display_i2c; +static bool hub_display_init; + +static struct { + uint8_t reg; + uint8_t values[LP50XX_NUM_CH]; +} __attribute__((packed)) hub_display_data = { + .reg = OUT0_COLOR, +}; + +void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c) { + __HAL_RCC_FMPI2C1_CLK_ENABLE(); + mp_hal_pin_config(pyb_pin_LED_SCL, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_NONE, 4); + mp_hal_pin_config(pyb_pin_LED_SDA, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_NONE, 4); +} + +void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c) { + __HAL_RCC_FMPI2C1_CLK_DISABLE(); + __HAL_RCC_FMPI2C1_FORCE_RESET(); + __HAL_RCC_FMPI2C1_RELEASE_RESET(); + mp_hal_pin_config(pyb_pin_LED_SCL, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pyb_pin_LED_SDA, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); +} + +static void hub_display_i2c_init(void) { + hub_display_i2c.Instance = FMPI2C1; + hub_display_i2c.Init.Timing = FMPI2C_CONVERT_TIMINGS(0, 4, 0, 19, 28); + hub_display_i2c.Init.OwnAddress1 = 0; + hub_display_i2c.Init.AddressingMode = FMPI2C_ADDRESSINGMODE_7BIT; + hub_display_i2c.Init.DualAddressMode = FMPI2C_DUALADDRESS_DISABLE; + hub_display_i2c.Init.OwnAddress2 = 0; + hub_display_i2c.Init.OwnAddress2Masks = FMPI2C_OA2_NOMASK; + hub_display_i2c.Init.GeneralCallMode = FMPI2C_GENERALCALL_DISABLE; + hub_display_i2c.Init.NoStretchMode = FMPI2C_NOSTRETCH_DISABLE; + HAL_FMPI2C_Init(&hub_display_i2c); +} + +void hub_display_set(uint8_t led, uint16_t value) { + if (led >= LP50XX_NUM_CH) { + return; + } + + hub_display_data.values[led] = value >> 8; +} + +void hub_display_update(void) { + if (!hub_display_init) { + return; + } + + HAL_FMPI2C_Master_Transmit(&hub_display_i2c, I2C_ADDR, (uint8_t *)&hub_display_data, + sizeof(hub_display_data), HAL_MAX_DELAY); +} + +void hub_display_on(void) { + if (hub_display_init) { + return; + } + + hub_display_i2c_init(); + mp_hal_pin_output(pyb_pin_LED_EN); + mp_hal_pin_high(pyb_pin_LED_EN); + + static const struct { + uint8_t reg; + uint8_t values[11]; + } __attribute__((packed)) init_data = { + .reg = DEVICE_CONFIG0, + .values = { + [DEVICE_CONFIG0] = DEVICE_CONFIG0_CHIP_EN, + [DEVICE_CONFIG1] = DEVICE_CONFIG1_POWER_SAVE_EN | DEVICE_CONFIG1_PWM_DITHERING_EN | DEVICE_CONFIG1_AUTO_INCR_EN, + [LED_CONFIG0] = 0, + [BANK_BRIGHTNESS] = 0, + [BANK_A_COLOR] = 0, + [BANK_B_COLOR] = 0, + [BANK_C_COLOR] = 0, + [LED0_BRIGHTNESS] = 51, // battery LED + [LED1_BRIGHTNESS] = 38, // status LED + [LED2_BRIGHTNESS] = 0, + [LED3_BRIGHTNESS] = 0, + } + }; + + HAL_FMPI2C_Master_Transmit(&hub_display_i2c, I2C_ADDR, (uint8_t *)&init_data, + sizeof(init_data), HAL_MAX_DELAY); + + hub_display_init = true; +} + +void hub_display_off(void) { + if (!hub_display_init) { + return; + } + + HAL_FMPI2C_DeInit(&hub_display_i2c); + + mp_hal_pin_config(pyb_pin_LED_EN, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + + hub_display_init = false; +} diff --git a/ports/stm32/boards/LEGO_HUB_NO7/hub_display.h b/ports/stm32/boards/LEGO_HUB_NO7/hub_display.h new file mode 100644 index 000000000000..7623e128a804 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/hub_display.h @@ -0,0 +1,4 @@ +void hub_display_on(void); +void hub_display_off(void); +void hub_display_update(void); +void hub_display_set(uint8_t led, uint16_t value); diff --git a/ports/stm32/boards/LEGO_HUB_NO7/manifest.py b/ports/stm32/boards/LEGO_HUB_NO7/manifest.py new file mode 100644 index 000000000000..d746381637d9 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/manifest.py @@ -0,0 +1,5 @@ +include("$(PORT_DIR)/boards/manifest.py") + +# Modules for application firmware update. +freeze("$(PORT_DIR)/mboot", "fwupdate.py", opt=3) +freeze("$(PORT_DIR)/boards/LEGO_HUB_NO6", ("spiflash.py", "appupdate.py"), opt=3) diff --git a/ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.h b/ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.h new file mode 100644 index 000000000000..50fb6c0607f8 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.h @@ -0,0 +1,152 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2021 Damien P. George + */ + +#include + +#define MICROPY_HW_BOARD_NAME "LEGO Technic Hub No.7" +#define MICROPY_HW_MCU_NAME "STM32F413" + +#define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_PY_PYB_LEGACY (0) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_FLASH_FS_LABEL "HUB_NO7" + +// HSE is 16MHz, CPU freq set to 100MHz, buses at maximum freq +#define MICROPY_HW_CLK_PLLM (16) +#define MICROPY_HW_CLK_PLLN (200) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) +#define MICROPY_HW_CLK_PLLQ (4) +#define MICROPY_HW_CLK_AHB_DIV (RCC_SYSCLK_DIV1) +#define MICROPY_HW_CLK_APB1_DIV (RCC_HCLK_DIV2) +#define MICROPY_HW_CLK_APB2_DIV (RCC_HCLK_DIV1) + +// For 2.7 to 3.6 V, 75 to 100 MHz: 3 wait states. +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_3 + +// UART buses +// Bluetooth HCI +#define MICROPY_HW_UART2_CTS (pyb_pin_BT_CTS) +#define MICROPY_HW_UART2_RTS (pyb_pin_BT_RTS) +#define MICROPY_HW_UART2_TX (pyb_pin_BT_TX) +#define MICROPY_HW_UART2_RX (pyb_pin_BT_RX) +// Port B +#define MICROPY_HW_UART3_TX (pyb_pin_PORTB_TX) +#define MICROPY_HW_UART3_RX (pyb_pin_PORTB_RX) +// Port A +#define MICROPY_HW_UART5_TX (pyb_pin_PORTA_TX) +#define MICROPY_HW_UART5_RX (pyb_pin_PORTA_RX) + +// SPI buses +#define MICROPY_HW_SPI2_NSS (pyb_pin_FLASH_NSS) +#define MICROPY_HW_SPI2_SCK (pyb_pin_FLASH_SCK) +#define MICROPY_HW_SPI2_MISO (pyb_pin_FLASH_MISO) +#define MICROPY_HW_SPI2_MOSI (pyb_pin_FLASH_MOSI) + +// USB config +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pyb_pin_USB_VBUS) +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_MSC (1) + +// Bluetooth config +#define MICROPY_HW_BLE_UART_ID (PYB_UART_2) +#define MICROPY_HW_BLE_UART_BAUDRATE (115200) +#define MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY (921600) +#define MICROPY_HW_BLE_BTSTACK_CHIPSET_INSTANCE btstack_chipset_cc256x_instance() + +// SPI flash, for R/W storage +// The first 1MiB is skipped because it's used by the built-in bootloader +// Note: MICROPY_HW_SPIFLASH_OFFSET_BYTES must be a multiple of MP_SPIFLASH_ERASE_BLOCK_SIZE +#define MICROPY_HW_SPIFLASH_OFFSET_BYTES (1024 * 1024) +#define MICROPY_HW_SPIFLASH_BLOCKMAP(bl) ((bl) + MICROPY_HW_SPIFLASH_OFFSET_BYTES / FLASH_BLOCK_SIZE) +#define MICROPY_HW_SPIFLASH_BLOCKMAP_EXT(bl) ((bl) + MICROPY_HW_SPIFLASH_OFFSET_BYTES / MP_SPIFLASH_ERASE_BLOCK_SIZE) +#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1) +#define MICROPY_HW_SPIFLASH_SIZE_BITS (32 * 1024 * 1024 - MICROPY_HW_SPIFLASH_OFFSET_BYTES * 8) +#define MICROPY_HW_SPIFLASH_CS (MICROPY_HW_SPI2_NSS) +#define MICROPY_HW_SPIFLASH_SCK (MICROPY_HW_SPI2_SCK) +#define MICROPY_HW_SPIFLASH_MISO (MICROPY_HW_SPI2_MISO) +#define MICROPY_HW_SPIFLASH_MOSI (MICROPY_HW_SPI2_MOSI) + +// SPI flash, block device config +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \ + (op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ + ) + +// Configuration for stardard block protocol (block size FLASH_BLOCK_SIZE). +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) \ + spi_bdev_readblocks(&spi_bdev, (dest), MICROPY_HW_SPIFLASH_BLOCKMAP(bl), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) \ + spi_bdev_writeblocks(&spi_bdev, (src), MICROPY_HW_SPIFLASH_BLOCKMAP(bl), (n)) + +// Configuration for extended block protocol (block size MP_SPIFLASH_ERASE_BLOCK_SIZE). +#define MICROPY_HW_BDEV_BLOCKSIZE_EXT (MP_SPIFLASH_ERASE_BLOCK_SIZE) +#define MICROPY_HW_BDEV_READBLOCKS_EXT(dest, bl, off, len) \ + (spi_bdev_readblocks_raw(&spi_bdev, (dest), MICROPY_HW_SPIFLASH_BLOCKMAP_EXT(bl), (off), (len))) +#define MICROPY_HW_BDEV_WRITEBLOCKS_EXT(src, bl, off, len) \ + (spi_bdev_writeblocks_raw(&spi_bdev, (src), MICROPY_HW_SPIFLASH_BLOCKMAP_EXT(bl), (off), (len))) +#define MICROPY_HW_BDEV_ERASEBLOCKS_EXT(bl, len) \ + (spi_bdev_eraseblocks_raw(&spi_bdev, MICROPY_HW_SPIFLASH_BLOCKMAP_EXT(bl), (len))) + +// Board control config +#define MICROPY_BOARD_STARTUP board_init + +/******************************************************************************/ +// Bootloader configuration + +// Configure CPU frequency to 96MHz, to make updates from SPI flash faster +#define MBOOT_CLK_PLLM (MICROPY_HW_CLK_VALUE / 1000000) +#define MBOOT_CLK_PLLN (192) +#define MBOOT_CLK_PLLP (RCC_PLLP_DIV2) +#define MBOOT_CLK_PLLQ (4) +#define MBOOT_CLK_AHB_DIV (RCC_SYSCLK_DIV1) +#define MBOOT_CLK_APB1_DIV (RCC_HCLK_DIV4) +#define MBOOT_CLK_APB2_DIV (RCC_HCLK_DIV2) +#define MBOOT_FLASH_LATENCY FLASH_LATENCY_3 + +#define MBOOT_FSLOAD (1) +#define MBOOT_VFS_FAT (1) +#define MBOOT_LEAVE_BOOTLOADER_VIA_RESET (0) + +#define MBOOT_SPIFLASH_ADDR (0x80000000) +#define MBOOT_SPIFLASH_BYTE_SIZE (4 * 1024 * 1024) +#define MBOOT_SPIFLASH_LAYOUT "/0x80000000/1024*4Kg" +#define MBOOT_SPIFLASH_ERASE_BLOCKS_PER_PAGE (1) +#define MBOOT_SPIFLASH_SPIFLASH (&board_mboot_spiflash) +#define MBOOT_SPIFLASH_CONFIG (&board_mboot_spiflash_config) + +#define MBOOT_LED1 0 +#define MBOOT_LED2 1 +#define MBOOT_LED3 2 +#define MBOOT_BOARD_LED_INIT board_mboot_led_init +#define MBOOT_BOARD_LED_STATE board_mboot_led_state + +#define MBOOT_BOARD_EARLY_INIT(initial_r0) board_init() +#define MBOOT_BOARD_CLEANUP board_mboot_cleanup +#define MBOOT_BOARD_GET_RESET_MODE board_mboot_get_reset_mode +#define MBOOT_BOARD_STATE_CHANGE board_mboot_state_change + +/******************************************************************************/ +// Function declarations + +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +extern const struct _mp_spiflash_config_t board_mboot_spiflash_config; +extern struct _mp_spiflash_t board_mboot_spiflash; + +void board_init(void); +void board_mboot_cleanup(int reset_mode); +void board_mboot_led_init(void); +void board_mboot_led_state(int led, int state); +int board_mboot_get_reset_mode(uint32_t *initial_r0); +void board_mboot_state_change(int state, uint32_t arg); +void *btstack_chipset_cc256x_instance(void); diff --git a/ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.mk b/ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.mk new file mode 100644 index 000000000000..c06f9a26ad45 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/mpconfigboard.mk @@ -0,0 +1,50 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F413xx +AF_FILE = boards/stm32f413_af.csv +LD_FILES = boards/LEGO_HUB_NO6/stm32f413xg.ld boards/common_bl.ld +TEXT0_ADDR = 0x08010000 + +BOOTLOADER_DFU_USB_VID ?= 0x0694 +BOOTLOADER_DFU_USB_PID ?= 0x000C + +# MicroPython settings +MICROPY_PY_BLUETOOTH ?= 1 +MICROPY_BLUETOOTH_NIMBLE ?= 0 +MICROPY_BLUETOOTH_BTSTACK ?= 1 +MICROPY_VFS_LFS2 ?= 1 + +# Board specific frozen modules +FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py + +SRC_HAL += $(STM32LIB_HAL_BASE)/Src/stm32f4xx_hal_fmpi2c.c + +ifneq ($(BUILDING_MBOOT),1) +LIB_SRC_C += lib/btstack/chipset/cc256x/btstack_chipset_cc256x.c +endif + +# Bootloader settings +MBOOT_TEXT0_ADDR = 0x08008000 +MBOOT_LD_FILES = ../boards/LEGO_HUB_NO6/mboot_memory.ld stm32_sections.ld + +# Backup/restore original Hub firmware + +HUB_FIRMWARE = lego_hub_firmware.dfu +HUB_FIRMWARE_ADDR = $(MBOOT_TEXT0_ADDR) +HUB_FIRMWARE_SIZE = 0xf8000 + +backup-hub-firmware: + $(Q)$(DFU_UTIL) -a 0 \ + -d $(BOOTLOADER_DFU_USB_VID):$(BOOTLOADER_DFU_USB_PID) \ + -U $(HUB_FIRMWARE).bin \ + -s $(HUB_FIRMWARE_ADDR):$(HUB_FIRMWARE_SIZE) + $(Q)$(PYTHON) $(DFU) \ + -b $(HUB_FIRMWARE_ADDR):$(HUB_FIRMWARE).bin \ + -D $(BOOTLOADER_DFU_USB_VID):$(BOOTLOADER_DFU_USB_PID) \ + $(HUB_FIRMWARE) + $(Q)$(RM) $(HUB_FIRMWARE).bin + $(ECHO) "Backup created in $(HUB_FIRMWARE)" + +restore-hub-firmware: + $(Q)$(DFU_UTIL) -a 0 \ + -d $(BOOTLOADER_DFU_USB_VID):$(BOOTLOADER_DFU_USB_PID) \ + -D $(HUB_FIRMWARE) diff --git a/ports/stm32/boards/LEGO_HUB_NO7/pins.csv b/ports/stm32/boards/LEGO_HUB_NO7/pins.csv new file mode 100644 index 000000000000..dd19518b78a9 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/pins.csv @@ -0,0 +1,114 @@ +BT_CTS,PA0 +BT_RTS,PA1 +BT_TX,PA2 +BT_RX,PA3 +,PA4 +,PA5 +BAT_VMON_ADC,PA6 +BAT_IMON_ADC,PA7 +LSM6_SCL,PA8 +USB_VBUS,PA9 +CHGMODE,PA10 +USB_DM,PA11 +USB_DP,PA12 +,PA13 +,PA14 +,PA15 +BAT_NTC,PB0 +BAT_PWR_EN,PB1 +BUTTON,PB2 +BT_SLOWCLK,PB3 +PORTB_M1,PB4 +PORTB_M2,PB5 +PORTA_M1,PB6 +PORTA_M2,PB7 +PORTB_EN,PB8 +PORTA_EN,PB9 +FLASH_SCK,PB10 +,PB11 +FLASH_NSS,PB12 +LED_EN,PB13 +LED_SDA,PB14 +LED_SCL,PB15 +,PC0 +,PC1 +FLASH_MISO,PC2 +FLASH_MOSI,PC3 +CHG_IMON_ADC,PC4 +,PC5 +CHGOK,PC6 +PORT_3V3_EN,PC7 +BT_ENABLE,PC8 +LSM6_SDA,PC9 +PORTB_TX,PC10 +PORTB_RX,PC11 +PORTA_TX,PC12 +LSM6_INT1,PC13 +,PC14 +,PC15 +,PD0 +,PD1 +PORTA_RX,PD2 +,PD3 +,PD4 +,PD5 +,PD6 +,PD7 +,PD8 +,PD9 +,PD10 +,PD11 +,PD12 +,PD13 +,PD14 +,PD15 +,PE0 +,PE1 +,PE2 +,PE3 +,PE4 +,PE5 +,PE6 +,PE7 +,PE8 +,PE9 +,PE10 +,PE11 +,PE12 +,PE13 +,PE14 +,PE15 +,PF0 +,PF1 +,PF2 +,PF3 +,PF4 +,PF5 +,PF6 +,PF7 +,PF8 +,PF9 +,PF10 +,PF11 +,PF12 +,PF13 +,PF14 +,PF15 +,PG0 +,PG1 +,PG2 +,PG3 +,PG4 +,PG5 +,PG6 +,PG7 +,PG8 +,PG9 +,PG10 +,PG11 +,PG12 +,PG13 +,PG14 +,PG15 +,PH0 +,PH1 diff --git a/ports/stm32/boards/LEGO_HUB_NO7/stm32f4xx_hal_conf.h b/ports/stm32/boards/LEGO_HUB_NO7/stm32f4xx_hal_conf.h new file mode 100644 index 000000000000..bd70912748a5 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO7/stm32f4xx_hal_conf.h @@ -0,0 +1,23 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +#include "stm32f4xx_hal_fmpi2c.h" + +#define HAL_FMPI2C_MODULE_ENABLED + +// Oscillator values in Hz +#define HSE_VALUE (16000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From b560b9fe715e293caef80533d61d8c3b179b0339 Mon Sep 17 00:00:00 2001 From: Ian Davies Date: Sun, 3 Jul 2022 18:35:17 +0100 Subject: [PATCH 1562/4290] rp2/mbedtls: Enable certificate validity time validation. --- ports/rp2/mbedtls/mbedtls_config.h | 6 ++++++ ports/rp2/mbedtls/mbedtls_port.c | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/ports/rp2/mbedtls/mbedtls_config.h b/ports/rp2/mbedtls/mbedtls_config.h index 4bf606f5ea23..743d0a6a8425 100644 --- a/ports/rp2/mbedtls/mbedtls_config.h +++ b/ports/rp2/mbedtls/mbedtls_config.h @@ -93,6 +93,8 @@ #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE #define MBEDTLS_X509_CRT_PARSE_C #define MBEDTLS_X509_USE_C +#define MBEDTLS_HAVE_TIME +#define MBEDTLS_HAVE_TIME_DATE // Memory allocation hooks #include @@ -103,6 +105,10 @@ void m_tracked_free(void *ptr); #define MBEDTLS_PLATFORM_STD_FREE m_tracked_free #define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf +// Time hook +time_t rp2_rtctime_seconds(time_t *timer); +#define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds + #include "mbedtls/check_config.h" #endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/rp2/mbedtls/mbedtls_port.c b/ports/rp2/mbedtls/mbedtls_port.c index aa0f9a36e0ea..9067eca90ee5 100644 --- a/ports/rp2/mbedtls/mbedtls_port.c +++ b/ports/rp2/mbedtls/mbedtls_port.c @@ -29,6 +29,9 @@ #include "mbedtls_config.h" +#include "hardware/rtc.h" +#include "shared/timeutils/timeutils.h" + extern uint8_t rosc_random_u8(size_t cycles); int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) { @@ -39,4 +42,10 @@ int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t return 0; } +time_t rp2_rtctime_seconds(time_t *timer) { + datetime_t t; + rtc_get_datetime(&t); + return timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec); +} + #endif From fbe9417b90474dd1a08749b3a79311a8007a98fb Mon Sep 17 00:00:00 2001 From: Ian Davies Date: Wed, 6 Jul 2022 16:22:57 +0100 Subject: [PATCH 1563/4290] extmod/ntptime: Factor out ntptime module from esp8266 port. The ntptime module was previously only included in the ESP8266 port. This commit factors that module out into the extmod directory, makes it support different epochs, and includes it in the rp2 port. --- {ports/esp8266/modules => extmod}/ntptime.py | 17 +++++++++++++---- ports/esp32/boards/manifest.py | 2 +- ports/esp8266/boards/GENERIC_512K/manifest.py | 1 - ports/esp8266/boards/manifest.py | 1 + ports/rp2/boards/PICO_W/manifest.py | 1 + 5 files changed, 16 insertions(+), 6 deletions(-) rename {ports/esp8266/modules => extmod}/ntptime.py (69%) diff --git a/ports/esp8266/modules/ntptime.py b/extmod/ntptime.py similarity index 69% rename from ports/esp8266/modules/ntptime.py rename to extmod/ntptime.py index dd07e46f1d3b..05d7e9717d82 100644 --- a/ports/esp8266/modules/ntptime.py +++ b/extmod/ntptime.py @@ -1,3 +1,5 @@ +import utime + try: import usocket as socket except: @@ -7,9 +9,6 @@ except: import struct -# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60 -NTP_DELTA = 3155673600 - # The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org' host = "pool.ntp.org" @@ -26,6 +25,17 @@ def time(): finally: s.close() val = struct.unpack("!I", msg[40:44])[0] + + EPOCH_YEAR = utime.gmtime(0)[0] + if EPOCH_YEAR == 2000: + # (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60 + NTP_DELTA = 3155673600 + elif EPOCH_YEAR == 1970: + # (date(1970, 1, 1) - date(1900, 1, 1)).days * 24*60*60 + NTP_DELTA = 2208988800 + else: + raise Exception("Unsupported epoch: {}".format(EPOCH_YEAR)) + return val - NTP_DELTA @@ -33,7 +43,6 @@ def time(): def settime(): t = time() import machine - import utime tm = utime.gmtime(t) machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0)) diff --git a/ports/esp32/boards/manifest.py b/ports/esp32/boards/manifest.py index 1dc1481a420d..f0ed38b515c7 100644 --- a/ports/esp32/boards/manifest.py +++ b/ports/esp32/boards/manifest.py @@ -1,6 +1,6 @@ freeze("$(PORT_DIR)/modules") freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py")) -freeze("$(MPY_DIR)/ports/esp8266/modules", "ntptime.py") +freeze("$(MPY_DIR)/extmod", "ntptime.py") freeze("$(MPY_DIR)/drivers/dht", "dht.py") freeze("$(MPY_DIR)/drivers/onewire") include("$(MPY_DIR)/extmod/uasyncio/manifest.py") diff --git a/ports/esp8266/boards/GENERIC_512K/manifest.py b/ports/esp8266/boards/GENERIC_512K/manifest.py index ee148c80892d..e43d94843fdb 100644 --- a/ports/esp8266/boards/GENERIC_512K/manifest.py +++ b/ports/esp8266/boards/GENERIC_512K/manifest.py @@ -1,5 +1,4 @@ freeze("$(BOARD_DIR)", "_boot.py", opt=3) -freeze("$(PORT_DIR)/modules", ("apa102.py", "ntptime.py", "port_diag.py")) freeze("$(MPY_DIR)/drivers/dht", "dht.py") freeze("$(MPY_DIR)/drivers/onewire") include("$(MPY_DIR)/extmod/webrepl/manifest.py") diff --git a/ports/esp8266/boards/manifest.py b/ports/esp8266/boards/manifest.py index 598572d62ad4..c5809717e692 100644 --- a/ports/esp8266/boards/manifest.py +++ b/ports/esp8266/boards/manifest.py @@ -1,4 +1,5 @@ freeze("$(PORT_DIR)/modules") +freeze("$(MPY_DIR)/extmod", "ntptime.py") freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py")) freeze("$(MPY_DIR)/drivers/dht", "dht.py") freeze("$(MPY_DIR)/drivers/onewire") diff --git a/ports/rp2/boards/PICO_W/manifest.py b/ports/rp2/boards/PICO_W/manifest.py index 1953d5cbd069..eb748da485c9 100644 --- a/ports/rp2/boards/PICO_W/manifest.py +++ b/ports/rp2/boards/PICO_W/manifest.py @@ -2,6 +2,7 @@ freeze("$(MPY_DIR)/tools", "upip.py") freeze("$(MPY_DIR)/tools", "upip_utarfile.py") +freeze("$(MPY_DIR)/extmod", "ntptime.py") if os.path.isdir(convert_path("$(MPY_LIB_DIR)")): freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") From 1bf2fd0592df999f913dd96be981cdabc0b557ca Mon Sep 17 00:00:00 2001 From: Ian Davies Date: Thu, 21 Jul 2022 21:00:24 +0100 Subject: [PATCH 1564/4290] extmod/modussl_mbedtls: Set a more sensible default debug log level. --- extmod/modussl_mbedtls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 8365c7a4a4d2..b14ed9ad0e3d 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -74,7 +74,7 @@ STATIC const mp_obj_type_t ussl_socket_type; STATIC void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { (void)ctx; (void)level; - printf("DBG:%s:%04d: %s\n", file, line, str); + mp_printf(&mp_plat_print, "DBG:%s:%04d: %s\n", file, line, str); } #endif @@ -175,7 +175,7 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { mbedtls_ctr_drbg_init(&o->ctr_drbg); #ifdef MBEDTLS_DEBUG_C // Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose - mbedtls_debug_set_threshold(0); + mbedtls_debug_set_threshold(3); #endif mbedtls_entropy_init(&o->entropy); From b6c2196fbd27834079d9d306d21c0a0897f03c91 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 17 Jul 2022 12:59:02 +0200 Subject: [PATCH 1565/4290] drivers/cyw43: Allow configuring the netif/mDNS hostname. Allow boards to configure/override the default hostname used for netif and mDNS. --- drivers/cyw43/cyw43.h | 9 +++++++++ drivers/cyw43/cyw43_ctrl.c | 2 ++ drivers/cyw43/cyw43_lwip.c | 7 ++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/cyw43/cyw43.h b/drivers/cyw43/cyw43.h index 7d3e30f5d4ed..5ca4898318a3 100644 --- a/drivers/cyw43/cyw43.h +++ b/drivers/cyw43/cyw43.h @@ -47,6 +47,14 @@ #define CYW43_LINK_NONET (-2) #define CYW43_LINK_BADAUTH (-3) +#ifndef MICROPY_BOARD_HOSTNAME +#define MICROPY_BOARD_HOSTNAME "PYBD" +#endif + +#ifndef MICROPY_BOARD_HOSTNAME_LENGTH +#define MICROPY_BOARD_HOSTNAME_LENGTH 16 +#endif + typedef struct _cyw43_t { cyw43_ll_t cyw43_ll; @@ -76,6 +84,7 @@ typedef struct _cyw43_t { struct netif netif[2]; struct dhcp dhcp_client; dhcp_server_t dhcp_server; + char hostname[MICROPY_BOARD_HOSTNAME_LENGTH]; } cyw43_t; extern cyw43_t cyw43_state; diff --git a/drivers/cyw43/cyw43_ctrl.c b/drivers/cyw43/cyw43_ctrl.c index 203bc812ac13..73e6e5895779 100644 --- a/drivers/cyw43/cyw43_ctrl.c +++ b/drivers/cyw43/cyw43_ctrl.c @@ -101,6 +101,8 @@ void cyw43_init(cyw43_t *self) { self->ap_channel = 3; self->ap_ssid_len = 0; self->ap_key_len = 0; + strncpy(self->hostname, MICROPY_BOARD_HOSTNAME, MICROPY_BOARD_HOSTNAME_LENGTH); + self->hostname[MICROPY_BOARD_HOSTNAME_LENGTH - 1] = 0; cyw43_poll = NULL; } diff --git a/drivers/cyw43/cyw43_lwip.c b/drivers/cyw43/cyw43_lwip.c index 16ae6023755a..f12a378c5da6 100644 --- a/drivers/cyw43/cyw43_lwip.c +++ b/drivers/cyw43/cyw43_lwip.c @@ -117,7 +117,7 @@ void cyw43_tcpip_init(cyw43_t *self, int itf) { #else netif_add(n, &ipconfig[0], &ipconfig[1], &ipconfig[2], self, cyw43_netif_init, netif_input); #endif - netif_set_hostname(n, "PYBD"); + netif_set_hostname(n, self->hostname); netif_set_default(n); netif_set_up(n); @@ -132,8 +132,9 @@ void cyw43_tcpip_init(cyw43_t *self, int itf) { #if LWIP_MDNS_RESPONDER // TODO better to call after IP address is set char mdns_hostname[9]; - memcpy(&mdns_hostname[0], "PYBD", 4); - mp_hal_get_mac_ascii(MP_HAL_MAC_WLAN0, 8, 4, &mdns_hostname[4]); + int len = MIN(strlen(self->hostname), 4); + memcpy(&mdns_hostname[0], self->hostname, len); + mp_hal_get_mac_ascii(MP_HAL_MAC_WLAN0, 4 + len, 8 - len, &mdns_hostname[len]); mdns_hostname[8] = '\0'; mdns_resp_add_netif(n, mdns_hostname, 60); #endif From 9dfabcd6d3d080aced888e8474e921f11dc979bb Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 17 Jul 2022 13:05:56 +0200 Subject: [PATCH 1566/4290] extmod/network_cyw43: Add hostname config option. --- extmod/network_cyw43.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index c131fbb109ee..9df799119fe6 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -381,6 +381,11 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map cyw43_ioctl(self->cyw, CYW43_IOCTL_GET_VAR, 13, buf, self->itf); return MP_OBJ_NEW_SMALL_INT(nw_get_le32(buf) / 4); } + #if !MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER + case MP_QSTR_hostname: { + return mp_obj_new_str(self->cyw->hostname, strlen(self->cyw->hostname)); + } + #endif default: mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); } @@ -453,6 +458,14 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map cyw43_ioctl(self->cyw, CYW43_IOCTL_SET_VAR, 9 + 4, buf, self->itf); break; } + #if !MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER + case MP_QSTR_hostname: { + const char *hostname = mp_obj_str_get_str(e->value); + strncpy(self->cyw->hostname, hostname, MICROPY_BOARD_HOSTNAME_LENGTH); + self->cyw->hostname[MICROPY_BOARD_HOSTNAME_LENGTH - 1] = 0; + break; + } + #endif default: mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); } From 6baeded32236feb9ba57ce78477fd1ee80fb4697 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 5 Aug 2022 18:52:13 -0500 Subject: [PATCH 1567/4290] py/runtime: Fix crash in star arg unpacking. The reallocation trigger for unpacking star args with unknown length did not take into account the number of fixed args remaining. So it was possible that the unpacked iterators could take up exactly the memory allocated then nothing would be left for fixed args after the star args. This causes a segfault crash. This is fixed by taking into account the remaining number of fixed args in the check to decide whether to realloc yet or not. Signed-off-by: David Lechner --- py/runtime.c | 2 +- tests/basics/fun_callstardblstar.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/py/runtime.c b/py/runtime.c index 2c3b3ddde4a4..ea3553db7227 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -814,7 +814,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ mp_obj_t iterable = mp_getiter(arg, &iter_buf); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (args2_len >= args2_alloc) { + if (args2_len + (n_args - i) >= args2_alloc) { args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), args2_alloc * 2 * sizeof(mp_obj_t)); args2_alloc *= 2; diff --git a/tests/basics/fun_callstardblstar.py b/tests/basics/fun_callstardblstar.py index f395df3333de..c08e46f668eb 100644 --- a/tests/basics/fun_callstardblstar.py +++ b/tests/basics/fun_callstardblstar.py @@ -37,3 +37,7 @@ def f2(*args, **kwargs): # case where *args is not a tuple/list and takes up most of the memory allocated for **kwargs f2(*iter(range(100)), **{str(i): i for i in range(100)}) + +# regression test - iterable with unknown len() was exactly using preallocated +# memory causing args 4 and 5 to overflow the allocated arg array +print(1, *iter((1, 2, 3)), *iter((1, 2, 3)), 4, 5, sep=",") From 6804b6f54fbed1f0fdb86668ebb46274e4876fa6 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 5 Apr 2022 08:25:54 +1000 Subject: [PATCH 1568/4290] stm32/boards/NUCLEO_WB55: Add error handling to firmware update scripts. In-the-field use of these FUS/WS firmware update scripts has exposed some weak points, causing corrupted FUS/WS firmware to be flashed to the unit. The problems are mostly caused with the ST GUI application, but sometimes from un-recognised failures during bin file transfer to the WB55 prior to running the rfcore_firmware.py script. Other failures were caused by incorrect load addresses being used, again both from user error copying the address from the HTML release notes to the GUI tool, but also from similarly not updating the address correctly in rfcore_firmware.py To guard against these errors and make it easier to prepare different versions, this commit adds a few features to the rfcore firmware update tools: - When creating the bin file, automatically parse the release note in the folder to get the correct address. - Add a footer to the bin file containing the name, version, CRC, address etc. - Before flashing rfcore, check if the same version is already installed. - Verify the CRC and obfuscation key before flashing bin. - Log the name and version of file being flashed. --- .../boards/NUCLEO_WB55/rfcore_firmware.py | 249 ++++++++++++++---- .../boards/NUCLEO_WB55/rfcore_makefirmware.py | 116 +++++++- 2 files changed, 308 insertions(+), 57 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py b/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py index 4085da90fd49..7cc81b4c682a 100644 --- a/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py +++ b/ports/stm32/boards/NUCLEO_WB55/rfcore_firmware.py @@ -34,36 +34,54 @@ # # To perform a firmware update: # -# 1. Generate "obfuscated" binary images using rfcore_makefirmware.py -# ./boards/NUCLEO_WB55/rfcore_makefirmware.py ~/src/github.com/STMicroelectronics/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x/ /tmp +# 1. Generate "obfuscated" binary images using rfcore_makefirmware.py, eg. +# $ python3 ./boards/NUCLEO_WB55/rfcore_makefirmware.py ~/src/github.com/STMicroelectronics/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x/ /tmp # This will generate /tmp/{fus_102,fus_110,ws_ble_hci}.bin +# It may warn that stm32wb5x_FUS_fw_1_0_2.bin cannot be found, newer packs don't include this +# which can be ignored unless your currently flashed FUS is older than 1.0.2 # # 2. Copy required files to the device filesystem. -# In general, it's always safe to copy all three files and the updater will -# figure out what needs to be done. This is the recommended option. -# However, if you already have the latest FUS (1.1.0) installed, then just the -# WS firmware is required. -# If a FUS binary is present, then the existing WS will be removed so it's a good -# idea to always include the WS binary if updating FUS. -# Note that a WS binary will not be installed unless FUS 1.1.0 is installed. +# $ mpremote cp /tmp/fus_102.bin : +# $ mpremote cp /tmp/fus_110.bin : +# $ mpremote cp /tmp/ws_ble_hci.bin : +# $ mpremote cp ./boards/NUCLEO_WB55/rfcore_firmware.py : +# In general, it's always safe to copy all three files and the updater will +# figure out what needs to be done. This is the recommended option. +# However, if you already have the latest FUS (1.1.0) installed, then just the +# WS firmware is required. +# If a FUS binary is present, then the existing WS will be removed so it's a good +# idea to always include the WS binary if updating FUS. +# Note that a WS binary will not be installed unless FUS 1.1.0 is installed. # # 3. Ensure boot.py calls `rfcore_firmware.resume()`. -# The WB55 will reset several times during the firmware update process, so this -# script manages the update state using RTC backup registers. -# `rfcore_firmware.resume()` will continue the update operation on startup to -# resume any in-progress update operation, and either trigger another reset, or -# return 0 to indicate that the operation completed successfully, or a reason -# code (see REASON_* below) to indicate failure. +# $ mpremote exec "import rfcore_firmware; rfcore_firmware.install_boot()" +# The WB55 will reset several times during the firmware update process, so this +# script manages the update state using RTC backup registers. +# `rfcore_firmware.resume()` will continue the update operation on startup to +# resume any in-progress update operation, and either trigger another reset, or +# return 0 to indicate that the operation completed successfully, or a reason +# code (see REASON_* below) to indicate failure. # # 4. Call rfcore_firmware.check_for_updates() to start the update process. -# The device will then immediately reboot and when the firmware update completes, -# the status will be returned from rfcore_firmware.resume(). See the REASON_ codes below. -# You can use the built-in stm.rfcore_fw_version() to query the installed version -# from your application code. +# $ mpremote exec "import rfcore_firmware; rfcore_firmware.check_for_updates()" +# The device will then immediately reboot and when the firmware update completes, +# the status will be returned from rfcore_firmware.resume(). See the REASON_ codes below. +# You can use the built-in stm.rfcore_fw_version() to query the installed version +# from your application code. import struct, os -import machine, stm -from micropython import const + +try: + import machine, stm + from ubinascii import crc32 + from micropython import const +except ImportError: + # cpython + from binascii import crc32 + + machine = stm = None + const = lambda x: x + _OGF_VENDOR = const(0x3F) @@ -174,13 +192,6 @@ _PATH_FUS_110 = "fus_110.bin" _PATH_WS_BLE_HCI = "ws_ble_hci.bin" -# This address is correct for versions up to v1.8 (assuming existing firmware deleted). -# Note any address from the end of the filesystem to the SFSA would be fine, but if -# the FUS is fixed in the future to use the specified address then these are the "correct" -# ones. -_ADDR_FUS = 0x080EC000 -_ADDR_WS_BLE_HCI = 0x080DC000 - # When installing the FUS/WS it can take a long time to return to the first # GET_STATE HCI command. # e.g. Installing stm32wb5x_BLE_Stack_full_fw.bin takes 3600ms to respond. @@ -242,10 +253,79 @@ def write(self, addr, buf, sz, key=0): machine.mem32[stm.FLASH + stm.FLASH_CR] = 0 -def _copy_file_to_flash(filename, addr): +def validate_crc(f): + """Should match copy of function in rfcore_makefirmware.py to confirm operation""" + f.seek(0) + file_crc = 0 + chunk = 16 * 1024 + buff = bytearray(chunk) + while True: + read = f.readinto(buff) + if read < chunk: + file_crc = crc32(buff[0:read], file_crc) + break + file_crc = crc32(buff, file_crc) + + file_crc = 0xFFFFFFFF & -file_crc - 1 + f.seek(0) + return file_crc == 0 + + +def check_file_details(filename): + with open(filename, "rb") as f: + if not validate_crc(f): + raise ValueError("file validation failed: incorrect crc") + + # Check the footer on the file + f.seek(-64, 2) + footer = f.read() + details = struct.unpack("<37sIIIIbbbII", footer) + ( + src_filename, + addr_1m, + addr_640k, + addr_512k, + addr_256k, + vers_major, + vers_minor, + vers_patch, + KEY, + crc, + ) = details + src_filename = src_filename.strip(b"\x00").decode() + if KEY != _OBFUSCATION_KEY: + raise ValueError("file validation failed: incorrect key") + + return ( + src_filename, + addr_1m, + addr_640k, + addr_512k, + addr_256k, + (vers_major, vers_minor, vers_patch), + ) + + +def _copy_file_to_flash(filename): flash = _Flash() flash.unlock() + # Reset any previously stored address + _write_target_addr(0) try: + ( + src_filename, + addr_1m, + addr_640k, + addr_512k, + addr_256k, + vers, + ) = check_file_details(filename) + + # TODO add support for querying the correct flash size on chip + addr = load_addr = addr_1m + + log(f"Writing {src_filename} v{vers[0]}.{vers[1]}.{vers[2]} to addr: 0x{addr:x}") + # Erase the entire staging area in flash. erase_addr = STAGING_AREA_START sfr_sfsa = machine.mem32[stm.FLASH + stm.FLASH_SFR] & 0xFF @@ -266,6 +346,9 @@ def _copy_file_to_flash(filename, addr): flash.write(addr, buf, sz, _OBFUSCATION_KEY) addr += 4096 + # Cache the intended target load address + _write_target_addr(load_addr) + finally: flash.lock() @@ -308,17 +391,25 @@ def _fus_fwdelete(): return _run_sys_hci_cmd(_OGF_VENDOR, _OCF_FUS_FW_DELETE) -def _fus_run_fwupgrade(addr): +def _fus_run_fwupgrade(): # Note: Address is ignored by the FUS (see comments above). + addr = _read_target_addr() + if not addr: + log(f"Update failed: Invalid load address: 0x{addr:x}") + return False + + log(f"Loading to: 0x{addr:x}") return _run_sys_hci_cmd(_OGF_VENDOR, _OCF_FUS_FW_UPGRADE, struct.pack("= _FUS_VERSION_102 and fus_version < _FUS_VERSION_110: log("FUS 1.0.2 detected") - if _stat_and_start_copy( - _PATH_FUS_110, _ADDR_FUS, _STATE_COPYING_FUS, _STATE_COPIED_FUS - ): + if _stat_and_start_copy(_PATH_FUS_110, _STATE_COPYING_FUS, _STATE_COPIED_FUS): continue else: log("FUS is up-to-date") if fus_version >= _FUS_VERSION_110: if _stat_and_start_copy( - _PATH_WS_BLE_HCI, _ADDR_WS_BLE_HCI, _STATE_COPYING_WS, _STATE_COPIED_WS + _PATH_WS_BLE_HCI, + _STATE_COPYING_WS, + _STATE_COPIED_WS, ): continue else: @@ -465,7 +562,7 @@ def resume(): if fus_is_idle(): log("FUS copy complete, installing") _write_state(_STATE_INSTALLING_FUS) - _fus_run_fwupgrade(_ADDR_FUS) + _fus_run_fwupgrade() else: log("FUS copy bad state") _write_failure_state(REASON_FLASH_FUS_BAD_STATE) @@ -519,7 +616,7 @@ def resume(): if fus_is_idle(): log("WS copy complete, installing") _write_state(_STATE_INSTALLING_WS) - _fus_run_fwupgrade(_ADDR_WS_BLE_HCI) + _fus_run_fwupgrade() else: log("WS copy bad state") _write_failure_state(REASON_FLASH_WS_BAD_STATE) @@ -556,9 +653,59 @@ def resume(): _write_failure_state(REASON_WS_VENDOR + result) +def install_boot(): + boot_py = "/flash/boot.py" + header = "" + mode = "w" + try: + with open(boot_py, "r") as boot: + header = "\n" + mode = "a" + for line in boot: + if "rfcore_firmware.resume()" in line: + print("Already installed.") + return + + print("boot.py exists, adding upgrade handler.") + except OSError: + print("boot.py doesn't exists, adding with upgrade handler.") + + with open(boot_py, mode) as boot: + boot.write(header) + boot.write("# Handle rfcore updates.\n") + boot.write("import rfcore_firmware\n") + boot.write("rfcore_firmware.resume()\n") + + # Start a firmware update. # This will immediately trigger a reset and start the update process on boot. -def check_for_updates(): - log("Starting firmware update") - _write_state(_STATE_WAITING_FOR_FUS) - machine.reset() +def check_for_updates(force=False): + ( + src_filename, + addr_1m, + addr_640k, + addr_512k, + addr_256k, + vers_fus, + ) = check_file_details(_PATH_FUS_110) + ( + src_filename, + addr_1m, + addr_640k, + addr_512k, + addr_256k, + vers_ws, + ) = check_file_details(_PATH_WS_BLE_HCI) + current_version_fus = stm.rfcore_fw_version(_FW_VERSION_FUS) + fus_uptodate = current_version_fus[0:3] == vers_fus + + current_version_ws = stm.rfcore_fw_version(_FW_VERSION_WS) + ws_uptodate = current_version_ws[0:3] == vers_ws + if fus_uptodate and ws_uptodate and not force: + log(f"Already up to date: fus: {current_version_fus}, ws: {current_version_ws}") + else: + log(f"Starting firmware update") + log(f" - fus: {current_version_fus} -> {vers_fus}") + log(f" - ws: {current_version_ws} -> {vers_ws}") + _write_state(_STATE_WAITING_FOR_FUS) + machine.reset() diff --git a/ports/stm32/boards/NUCLEO_WB55/rfcore_makefirmware.py b/ports/stm32/boards/NUCLEO_WB55/rfcore_makefirmware.py index 23f3d20f0c9c..6b2fb60892a9 100755 --- a/ports/stm32/boards/NUCLEO_WB55/rfcore_makefirmware.py +++ b/ports/stm32/boards/NUCLEO_WB55/rfcore_makefirmware.py @@ -30,28 +30,70 @@ # rfcore_firmware.py as well as instructions on how to use. import os +import re import struct import sys +from binascii import crc32 +from rfcore_firmware import validate_crc, _OBFUSCATION_KEY -# Must match rfcore_firmware.py. -_OBFUSCATION_KEY = 0x0573B55AA _FIRMWARE_FILES = { "stm32wb5x_FUS_fw_1_0_2.bin": "fus_102.bin", "stm32wb5x_FUS_fw.bin": "fus_110.bin", "stm32wb5x_BLE_HCILayer_fw.bin": "ws_ble_hci.bin", } +_RELEASE_NOTES = "Release_Notes.html" + + +def get_details(release_notes, filename): + if not release_notes: + return None + file_details = re.findall( + rb"%s,(((0x[\d\S]+?),)+[vV][\d\.]+)[<,]" % filename.encode(), + release_notes, + flags=re.DOTALL, + ) + # The release note has all past version details also, but current is at top + latest_details = file_details[0][0].split(b",") + addr_1m, addr_640k, addr_512k, addr_256k, version = latest_details + addr_1m = int(addr_1m, 0) + addr_640k = int(addr_640k, 0) + addr_512k = int(addr_512k, 0) + addr_256k = int(addr_256k, 0) + version = [int(v) for v in version.lower().lstrip(b"v").split(b".")] + return addr_1m, addr_640k, addr_512k, addr_256k, version def main(src_path, dest_path): - for src_file, dest_file in _FIRMWARE_FILES.items(): - src_file = os.path.join(src_path, src_file) + + # Load the release note to parse for important details + with open(os.path.join(src_path, _RELEASE_NOTES), "rb") as f: + release_notes = f.read() + # remove some formatting + release_notes = re.sub(rb"", b"", release_notes) + # flatten tables + release_notes = re.sub( + rb"\W*\n*\W*", + b",", + release_notes.replace(b"", b"").replace(b"", b""), + ) + if ( + b"Wireless Coprocessor Binary,STM32WB5xxG(1M),STM32WB5xxY(640k),STM32WB5xxE(512K),STM32WB5xxC(256K),Version," + not in release_notes + ): + raise SystemExit( + "Cannot determine binary load address, please confirm Coprocessor folder / Release Notes format." + ) + + for src_filename, dest_file in _FIRMWARE_FILES.items(): + src_file = os.path.join(src_path, src_filename) dest_file = os.path.join(dest_path, dest_file) if not os.path.exists(src_file): print("Unable to find: {}".format(src_file)) continue sz = 0 with open(src_file, "rb") as src: + crc = 0 with open(dest_file, "wb") as dest: while True: b = src.read(4) @@ -59,9 +101,71 @@ def main(src_path, dest_path): break (v,) = struct.unpack(" Date: Sat, 23 Jul 2022 13:38:32 +0800 Subject: [PATCH 1569/4290] mpy-cross/Makefile: Respect existing CFLAGS and LDFLAGS. --- mpy-cross/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile index 2189dff9058e..4b6e03df8e84 100644 --- a/mpy-cross/Makefile +++ b/mpy-cross/Makefile @@ -19,7 +19,7 @@ INC += -I$(TOP) # compiler settings CWARN = -Wall -Werror CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith -CFLAGS = $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) +CFLAGS += $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables # Debugging/Optimization @@ -42,7 +42,7 @@ else # Use gcc syntax for map file LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections endif -LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) +LDFLAGS += $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) # source files SRC_C = \ From 736b427220ae0689694fc784bd4426605d556c4c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 27 Jul 2022 10:45:38 +0200 Subject: [PATCH 1570/4290] extmod/network_wiznet5k: Register NIC when the lwIP stack is used. That was missing, and network.route() returned an empty list. --- extmod/network_wiznet5k.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index f328276a5b26..fecb6ae8c271 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -224,6 +224,9 @@ STATIC void wiznet5k_init(void) { netif_set_link_up(&wiznet5k_obj.netif); netif_set_up(&wiznet5k_obj.netif); + + // register with network module + mod_network_register_nic(&wiznet5k_obj); } void wiznet5k_deinit(void) { From be2beab71a1a1047299601af70e99053fac508e5 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 27 Jul 2022 10:51:03 +0200 Subject: [PATCH 1571/4290] extmod/network_wiznet5k: Drop obsolete argument count check. Drop an obsolete and wrong argument check, which prevented specifying a pin for the interrupt signal. The proper checks are now done further down in the code. --- extmod/network_wiznet5k.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index fecb6ae8c271..02bf90244d7e 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -689,10 +689,8 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size #endif #ifdef MICROPY_HW_WIZNET_SPI_ID - // check arguments - mp_arg_check_num(n_args, n_kw, 0, 3, false); // Allow auto-configuration of SPI if defined for board and no args passed - if (n_args == 0) { + if (n_args == 0 && n_kw == 0) { // Initialize SPI. mp_obj_t spi_obj = MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_SPI_SCK); mp_obj_t miso_obj = MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_SPI_MISO); From 73699a846c031ecde70cf6bd629ef9a8232291e3 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 27 Jul 2022 21:01:29 +0200 Subject: [PATCH 1572/4290] extmod/network_wiznet5k: Deinit the NIC before (re-)initialisation. If nic.active(True) is called several times in a row, the device may lock up. Even if that is bad coding practice, calling wiznet5k_deinit() in wiznet5k_init() prevents the lock. --- extmod/network_wiznet5k.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 02bf90244d7e..5a26c08952da 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -198,6 +198,16 @@ STATIC void wiznet5k_config_interrupt(bool enabled) { ); } +void wiznet5k_deinit(void) { + for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { + if (netif == &wiznet5k_obj.netif) { + netif_remove(netif); + netif->flags = 0; + break; + } + } +} + STATIC void wiznet5k_init(void) { // Configure wiznet for raw ethernet frame usage. @@ -219,6 +229,9 @@ STATIC void wiznet5k_init(void) { wiznet5k_config_interrupt(true); } + // Deinit before a new init to clear the state from a previous activation + wiznet5k_deinit(); + // Hook the Wiznet into lwIP wiznet5k_lwip_init(&wiznet5k_obj); @@ -229,16 +242,6 @@ STATIC void wiznet5k_init(void) { mod_network_register_nic(&wiznet5k_obj); } -void wiznet5k_deinit(void) { - for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { - if (netif == &wiznet5k_obj.netif) { - netif_remove(netif); - netif->flags = 0; - break; - } - } -} - STATIC void wiznet5k_send_ethernet(wiznet5k_obj_t *self, size_t len, const uint8_t *buf) { uint8_t ip[4] = {1, 1, 1, 1}; // dummy int ret = WIZCHIP_EXPORT(sendto)(0, (byte *)buf, len, ip, 11); // dummy port From 999b66d53108a014194e7a30f20d4a269fdda6b4 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 29 Jul 2022 08:22:42 +0200 Subject: [PATCH 1573/4290] extmod/network_wiznet5k: Schedule clearing of interrupt flags. Avoiding conflicts between the IRQ and an active transfers. Before this change the device could lock up in heavy traffic situations. Fix found and code supplied by @omogenot. --- extmod/network_wiznet5k.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 5a26c08952da..bdf94993d1f7 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -177,11 +177,10 @@ STATIC void wiznet5k_lwip_init(wiznet5k_obj_t *self); STATIC mp_obj_t mpy_wiznet_read_int(mp_obj_t none_in) { (void)none_in; - wizchip_clrinterrupt(IK_SOCK_0); - setSn_IR(0, Sn_IR_RECV); - - // Handle incoming data - wiznet5k_try_poll(); + // Handle incoming data, unless the SPI bus is busy + if (mp_hal_pin_read(wiznet5k_obj.cs)) { + wiznet5k_try_poll(); + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mpy_wiznet_read_int_obj, mpy_wiznet_read_int); @@ -343,6 +342,10 @@ void wiznet5k_poll(void) { } } } + wizchip_clrinterrupt(IK_SOCK_0); + #if _WIZCHIP_ == W5100S + setSn_IR(0, Sn_IR_RECV); // W5100S driver bug: must write to the Sn_IR register to reset the IRQ signal + #endif } #endif // MICROPY_PY_LWIP From f000ac9e824cfa2f2f3e50d902e80b576367b4c1 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 30 Jul 2022 12:30:09 +0200 Subject: [PATCH 1574/4290] extmod/network_wiznet5k: Rearrange the function wiznet5k_poll(). To have just one exit and a more compact flag test. This is just a style change without impact to the functionality. --- extmod/network_wiznet5k.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index bdf94993d1f7..c862f16c0e7d 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -325,20 +325,18 @@ STATIC void wiznet5k_lwip_init(wiznet5k_obj_t *self) { void wiznet5k_poll(void) { wiznet5k_obj_t *self = &wiznet5k_obj; - if (!(self->netif.flags & NETIF_FLAG_UP) || - !(self->netif.flags & NETIF_FLAG_LINK_UP)) { - return; - } - uint16_t len; - while ((len = wiznet5k_recv_ethernet(self)) > 0) { - if (self->trace_flags & TRACE_ETH_RX) { - netutils_ethernet_trace(MP_PYTHON_PRINTER, len, self->eth_frame, NETUTILS_TRACE_NEWLINE); - } - struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if (p != NULL) { - pbuf_take(p, self->eth_frame, len); - if (self->netif.input(p, &self->netif) != ERR_OK) { - pbuf_free(p); + if ((self->netif.flags & (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) == (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) { + uint16_t len; + while ((len = wiznet5k_recv_ethernet(self)) > 0) { + if (self->trace_flags & TRACE_ETH_RX) { + netutils_ethernet_trace(MP_PYTHON_PRINTER, len, self->eth_frame, NETUTILS_TRACE_NEWLINE); + } + struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + if (p != NULL) { + pbuf_take(p, self->eth_frame, len); + if (self->netif.input(p, &self->netif) != ERR_OK) { + pbuf_free(p); + } } } } From af6d2845fad4fde2d36f220efce876a4b1facdaa Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 10 Aug 2022 00:53:13 +1000 Subject: [PATCH 1575/4290] extmod/network_wiznet5k: Extract SPI transfer function dynamically. Instead of using the fixed machine_spi_type entity to get the SPI transfer function, this transfer function is now extracted dynamically from the type of the SPI object. This allows the SPI object used to communicate with the WIZNET5K hardware to be SoftSPI or hardware SPI, or anything that has the SPI protocol (at the C level). Signed-off-by: Damien George --- extmod/network_wiznet5k.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index c862f16c0e7d..89c933c2d454 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -91,12 +91,11 @@ #endif #endif -extern struct _machine_spi_obj_t *spi_from_mp_obj(mp_obj_t o); - typedef struct _wiznet5k_obj_t { mp_obj_base_t base; mp_uint_t cris_state; - struct _machine_spi_obj_t *spi; + mp_obj_base_t *spi; + void (*spi_transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest); mp_hal_pin_obj_t cs; mp_hal_pin_obj_t rst; #if WIZNET5K_WITH_LWIP_STACK @@ -148,21 +147,21 @@ void mpy_wiznet_yield(void) { } STATIC void wiz_spi_read(uint8_t *buf, uint16_t len) { - ((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer((mp_obj_base_t *)wiznet5k_obj.spi, len, buf, buf); + wiznet5k_obj.spi_transfer(wiznet5k_obj.spi, len, buf, buf); } STATIC void wiz_spi_write(const uint8_t *buf, uint16_t len) { - ((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer((mp_obj_base_t *)wiznet5k_obj.spi, len, buf, NULL); + wiznet5k_obj.spi_transfer(wiznet5k_obj.spi, len, buf, NULL); } STATIC uint8_t wiz_spi_readbyte() { uint8_t buf = 0; - ((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer((mp_obj_base_t *)wiznet5k_obj.spi, 1, &buf, &buf); + wiznet5k_obj.spi_transfer(wiznet5k_obj.spi, 1, &buf, &buf); return buf; } STATIC void wiz_spi_writebyte(const uint8_t buf) { - ((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer((mp_obj_base_t *)wiznet5k_obj.spi, 1, &buf, NULL); + wiznet5k_obj.spi_transfer(wiznet5k_obj.spi, 1, &buf, NULL); } STATIC void wiznet5k_get_mac_address(wiznet5k_obj_t *self, uint8_t mac[6]) { @@ -680,7 +679,7 @@ STATIC void wiznet5k_dhcp_init(wiznet5k_obj_t *self) { // WIZNET5K(spi, pin_cs, pin_rst[, pin_intn]) // Create and return a WIZNET5K object. STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - struct _machine_spi_obj_t *spi; + mp_obj_base_t *spi; mp_hal_pin_obj_t cs; mp_hal_pin_obj_t rst; @@ -706,7 +705,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size MP_ROM_QSTR(MP_QSTR_miso), mp_pin_make_new(NULL, 1, 0, &miso_obj), MP_ROM_QSTR(MP_QSTR_mosi), mp_pin_make_new(NULL, 1, 0, &mosi_obj), }; - spi = machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 3, args); + spi = MP_OBJ_TO_PTR(machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 3, args)); cs = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_CS)})); rst = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_RST)})); @@ -724,7 +723,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size #else mp_arg_check_num(n_args, n_kw, 3, 3, false); #endif - spi = spi_from_mp_obj(args[0]); + spi = mp_hal_get_spi_obj(args[0]); cs = mp_hal_get_pin_obj(args[1]); rst = mp_hal_get_pin_obj(args[2]); #if WIZNET5K_WITH_LWIP_STACK @@ -742,6 +741,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k; wiznet5k_obj.cris_state = 0; wiznet5k_obj.spi = spi; + wiznet5k_obj.spi_transfer = ((mp_machine_spi_p_t *)spi->type->protocol)->transfer; wiznet5k_obj.cs = cs; wiznet5k_obj.rst = rst; #if WIZNET5K_WITH_LWIP_STACK From f72d3cec2338e88b9aa6e28d345f0007042d692b Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 10 Aug 2022 00:52:03 +1000 Subject: [PATCH 1576/4290] rp2/machine_spi: Add mp_hal_get_spi_obj helper function. And remove the now-obsolete spi_from_mp_obj() function. Signed-off-by: Damien George --- ports/rp2/machine_spi.c | 23 ++++++++++++++--------- ports/rp2/mphalport.h | 2 ++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ports/rp2/machine_spi.c b/ports/rp2/machine_spi.c index 742a3cfddf44..42998664a76d 100644 --- a/ports/rp2/machine_spi.c +++ b/ports/rp2/machine_spi.c @@ -269,15 +269,6 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8 } } -machine_spi_obj_t *spi_from_mp_obj(mp_obj_t o) { - if (mp_obj_is_type(o, &machine_spi_type)) { - machine_spi_obj_t *self = MP_OBJ_TO_PTR(o); - return self; - } else { - mp_raise_TypeError(MP_ERROR_TEXT("expecting an SPI object")); - } -} - STATIC const mp_machine_spi_p_t machine_spi_p = { .init = machine_spi_init, .transfer = machine_spi_transfer, @@ -291,3 +282,17 @@ const mp_obj_type_t machine_spi_type = { .protocol = &machine_spi_p, .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, }; + +mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t o) { + if (mp_obj_is_type(o, &machine_spi_type)) { + return MP_OBJ_TO_PTR(o); + } + #if MICROPY_PY_MACHINE_SOFTSPI + else if (mp_obj_is_type(o, &mp_machine_soft_spi_type)) { + return MP_OBJ_TO_PTR(o); + } + #endif + else { + mp_raise_TypeError(MP_ERROR_TEXT("expecting an SPI object")); + } +} diff --git a/ports/rp2/mphalport.h b/ports/rp2/mphalport.h index 88683d9360a4..31bedf338124 100644 --- a/ports/rp2/mphalport.h +++ b/ports/rp2/mphalport.h @@ -148,6 +148,8 @@ enum mp_hal_pin_interrupt_trigger { void mp_hal_pin_interrupt(mp_hal_pin_obj_t pin, mp_obj_t handler, mp_uint_t trigger, bool hard); +mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t spi_in); + enum { MP_HAL_MAC_WLAN0 = 0, MP_HAL_MAC_BDADDR, From 7d91a9bf5b30c11ea2dcf90e8b3d031e40b6e985 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 10 Aug 2022 14:09:02 +1000 Subject: [PATCH 1577/4290] py/mpprint: Fix formatting typo with mp_print_ext_t struct name. Signed-off-by: Damien George --- py/mpprint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/mpprint.h b/py/mpprint.h index 0dff9a770ada..8383ea85794c 100644 --- a/py/mpprint.h +++ b/py/mpprint.h @@ -56,7 +56,7 @@ typedef struct _mp_print_ext_t { mp_print_t base; const char *item_separator; const char *key_separator; -}mp_print_ext_t; +} mp_print_ext_t; #define MP_PRINT_GET_EXT(print) ((mp_print_ext_t *)print) From b5986784e4341d7d34b97b2481567d842453732d Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 10 Aug 2022 14:09:22 +1000 Subject: [PATCH 1578/4290] py/objstr: Reformat str access macros to make them readable. Signed-off-by: Damien George --- py/objstr.h | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/py/objstr.h b/py/objstr.h index 8c450baed6e4..8f87c3018a3c 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -41,24 +41,38 @@ typedef struct _mp_obj_str_t { // use this macro to extract the string hash // warning: the hash can be 0, meaning invalid, and must then be explicitly computed from the data #define GET_STR_HASH(str_obj_in, str_hash) \ - mp_uint_t str_hash; if (mp_obj_is_qstr(str_obj_in)) \ - { str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->hash; } + mp_uint_t str_hash; \ + if (mp_obj_is_qstr(str_obj_in)) { \ + str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); \ + } else { \ + str_hash = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->hash; \ + } // use this macro to extract the string length #define GET_STR_LEN(str_obj_in, str_len) \ - size_t str_len; if (mp_obj_is_qstr(str_obj_in)) \ - { str_len = qstr_len(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; } + size_t str_len; \ + if (mp_obj_is_qstr(str_obj_in)) { \ + str_len = qstr_len(MP_OBJ_QSTR_VALUE(str_obj_in)); \ + } else { \ + str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; \ + } // use this macro to extract the string data and length #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len); #define GET_STR_DATA_LEN(str_obj_in, str_data, str_len) \ - size_t str_len; const byte *str_data = mp_obj_str_get_data_no_check(str_obj_in, &str_len); + size_t str_len; \ + const byte *str_data = mp_obj_str_get_data_no_check(str_obj_in, &str_len); #else #define GET_STR_DATA_LEN(str_obj_in, str_data, str_len) \ - const byte *str_data; size_t str_len; if (mp_obj_is_qstr(str_obj_in)) \ - { str_data = qstr_data(MP_OBJ_QSTR_VALUE(str_obj_in), &str_len); } \ - else { str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; str_data = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->data; } + const byte *str_data; \ + size_t str_len; \ + if (mp_obj_is_qstr(str_obj_in)) { \ + str_data = qstr_data(MP_OBJ_QSTR_VALUE(str_obj_in), &str_len); \ + } else { \ + str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; \ + str_data = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->data; \ + } #endif mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); From 5cfbf18d5fb70a907984781b3ac01aa5c27148be Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 10 Aug 2022 14:09:44 +1000 Subject: [PATCH 1579/4290] javascript/Makefile: Remove obsolete disable of array-bounds warning. This was fixed in bb70874111dbb246624a68c013e8f1c3245ca0d8 Signed-off-by: Damien George --- ports/javascript/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/ports/javascript/Makefile b/ports/javascript/Makefile index 046d303336a9..93c7b5609b23 100644 --- a/ports/javascript/Makefile +++ b/ports/javascript/Makefile @@ -53,7 +53,4 @@ test: $(BUILD)/micropython.js $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) cd $(TOP)/tests && MICROPY_MICROPYTHON=../ports/javascript/node_run.sh ./run-tests.py -j1 -# Disable errors for array-bounds warnings on "sp[-MP_OBJ_ITER_BUF_NSLOTS + 2]" access. -$(BUILD)/py/vm.o: CFLAGS += -Wno-error=array-bounds - include $(TOP)/py/mkrules.mk From b2e82402688b53829f37475583231b067b9faea7 Mon Sep 17 00:00:00 2001 From: Daniel Jour Date: Tue, 2 Aug 2022 21:39:02 +0200 Subject: [PATCH 1580/4290] py/mkrules.mk: Keep all build artefacts inside $(BUILD) directory. The rules for lib (static library with name $(LIBMICROPYTHON)) and the default rule to build a binary (name $(PROG)) produced outputs in the current working directory. Change this to build these files in the build directory. Note: An empty BUILD variable can cause issues (references to the root directory); this is not addressed by this commit due to multiple other places having the same issue. --- py/mkrules.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/py/mkrules.mk b/py/mkrules.mk index 41ec4b064159..af116786798a 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -196,9 +196,9 @@ ifneq (,$(findstring mingw,$(COMPILER_TARGET))) PROG := $(PROG).exe endif -all: $(PROG) +all: $(BUILD)/$(PROG) -$(PROG): $(OBJ) +$(BUILD)/$(PROG): $(OBJ) $(ECHO) "LINK $@" # Do not pass COPT here - it's *C* compiler optimizations. For example, # we may want to compile using Thumb, but link with non-Thumb libc. @@ -210,8 +210,8 @@ endif clean: clean-prog clean-prog: - $(RM) -f $(PROG) - $(RM) -f $(PROG).map + $(RM) -f $(BUILD)/$(PROG) + $(RM) -f $(BUILD)/$(PROG).map .PHONY: clean-prog endif @@ -231,8 +231,8 @@ LIBMICROPYTHON = libmicropython.a # with 3rd-party projects which don't have proper dependency # tracking. Then LIBMICROPYTHON_EXTRA_CMD can e.g. touch some # other file to cause needed effect, e.g. relinking with new lib. -lib $(LIBMICROPYTHON): $(OBJ) - $(Q)$(AR) rcs $(LIBMICROPYTHON) $^ +lib $(BUILD)/$(LIBMICROPYTHON): $(OBJ) + $(Q)$(AR) rcs $(BUILD)/$(LIBMICROPYTHON) $^ $(LIBMICROPYTHON_EXTRA_CMD) clean: From 47c84286e8c8d9873e99f12711a683ecd6b9ca62 Mon Sep 17 00:00:00 2001 From: Daniel Jour Date: Tue, 2 Aug 2022 23:48:41 +0200 Subject: [PATCH 1581/4290] all: Fix paths to mpy-cross and micropython binaries. Binaries built using the Make build system now no longer appear in the working directory of the build, but rather in the build directory. Thus some paths had to be adjusted. --- .github/workflows/ports_unix.yml | 2 +- examples/embedding/Makefile | 2 +- ports/unix/Makefile | 22 +++++++++++----------- py/dynruntime.mk | 2 +- py/mkenv.mk | 2 +- py/mkrules.cmake | 2 +- py/mkrules.mk | 2 +- tests/run-natmodtests.py | 2 +- tests/run-tests.py | 6 ++++-- tools/ci.sh | 20 ++++++++++---------- tools/makemanifest.py | 2 +- 11 files changed, 33 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index 63cc1c0faa92..ab2406647a8c 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -35,7 +35,7 @@ jobs: env: SOURCE_DATE_EPOCH: 1234567890 - name: Check reproducible build date - run: echo | ports/unix/micropython-minimal -i | grep 'on 2009-02-13;' + run: echo | ports/unix/build-minimal/micropython-minimal -i | grep 'on 2009-02-13;' standard: runs-on: ubuntu-latest diff --git a/examples/embedding/Makefile b/examples/embedding/Makefile index 99f239a7c5af..7de1219b2644 100644 --- a/examples/embedding/Makefile +++ b/examples/embedding/Makefile @@ -1,6 +1,6 @@ MPTOP = ../.. CFLAGS = -std=c99 -I. -I$(MPTOP) -DNO_QSTR -LDFLAGS = -L. +LDFLAGS = -L./build hello-embed: hello-embed.o -lmicropython diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 3b339c3d3f79..709cc79853d5 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -304,18 +304,18 @@ include $(TOP)/py/mkrules.mk .PHONY: test test_full -test: $(PROG) $(TOP)/tests/run-tests.py +test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py -test_full: $(PROG) $(TOP)/tests/run-tests.py +test_full: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py -d thread - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --emit native - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) -d basics float micropython - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) --emit native -d basics float micropython - cat $(TOP)/tests/basics/0prelim.py | ./$(PROG) | grep -q 'abc' + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py -d thread + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --emit native + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) -d basics float micropython + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) --emit native -d basics float micropython + cat $(TOP)/tests/basics/0prelim.py | ./$(BUILD)/$(PROG) | grep -q 'abc' test_gcov: test_full gcov -o $(BUILD)/py $(TOP)/py/*.c @@ -346,9 +346,9 @@ $(BUILD)/lib/libffi/include/ffi.h: $(TOP)/lib/libffi/configure PREFIX = /usr/local BINDIR = $(DESTDIR)$(PREFIX)/bin -install: $(PROG) +install: $(BUILD)/$(PROG) install -d $(BINDIR) - install $(PROG) $(BINDIR)/$(PROG) + install $(BUILD)/$(PROG) $(BINDIR)/$(PROG) uninstall: -rm $(BINDIR)/$(PROG) diff --git a/py/dynruntime.mk b/py/dynruntime.mk index 09cbb2dd37cb..10feefc4a7c2 100644 --- a/py/dynruntime.mk +++ b/py/dynruntime.mk @@ -7,7 +7,7 @@ ECHO = @echo RM = /bin/rm MKDIR = /bin/mkdir PYTHON = python3 -MPY_CROSS = $(MPY_DIR)/mpy-cross/mpy-cross +MPY_CROSS = $(MPY_DIR)/mpy-cross/build/mpy-cross MPY_TOOL = $(PYTHON) $(MPY_DIR)/tools/mpy-tool.py MPY_LD = $(PYTHON) $(MPY_DIR)/tools/mpy_ld.py diff --git a/py/mkenv.mk b/py/mkenv.mk index cc04a8c0b307..ea2e34f3b64d 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -61,7 +61,7 @@ MPY_LIB_SUBMODULE_DIR = $(TOP)/lib/micropython-lib MPY_LIB_DIR = $(MPY_LIB_SUBMODULE_DIR) ifeq ($(MICROPY_MPYCROSS),) -MICROPY_MPYCROSS = $(TOP)/mpy-cross/mpy-cross +MICROPY_MPYCROSS = $(TOP)/mpy-cross/build/mpy-cross MICROPY_MPYCROSS_DEPENDENCY = $(MICROPY_MPYCROSS) endif diff --git a/py/mkrules.cmake b/py/mkrules.cmake index 2f168ede6f2b..e7c4101ddb72 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -193,7 +193,7 @@ if(MICROPY_FROZEN_MANIFEST) # to automatically build mpy-cross if needed. set(MICROPY_MPYCROSS $ENV{MICROPY_MPYCROSS}) if(NOT MICROPY_MPYCROSS) - set(MICROPY_MPYCROSS_DEPENDENCY ${MICROPY_DIR}/mpy-cross/mpy-cross) + set(MICROPY_MPYCROSS_DEPENDENCY ${MICROPY_DIR}/mpy-cross/build/mpy-cross) if(NOT MICROPY_MAKE_EXECUTABLE) set(MICROPY_MAKE_EXECUTABLE make) endif() diff --git a/py/mkrules.mk b/py/mkrules.mk index af116786798a..73c33227c09a 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -162,7 +162,7 @@ $(HEADER_BUILD): ifneq ($(MICROPY_MPYCROSS_DEPENDENCY),) # to automatically build mpy-cross, if needed $(MICROPY_MPYCROSS_DEPENDENCY): - $(MAKE) -C $(dir $@) + $(MAKE) -C $(dir $@).. endif ifneq ($(FROZEN_DIR),) diff --git a/tests/run-natmodtests.py b/tests/run-natmodtests.py index 8eb27169c4ca..9130e00d6eba 100755 --- a/tests/run-natmodtests.py +++ b/tests/run-natmodtests.py @@ -14,7 +14,7 @@ # Paths for host executables CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") -MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython-coverage") +MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-coverage/micropython-coverage") NATMOD_EXAMPLE_DIR = "../examples/natmod/" diff --git a/tests/run-tests.py b/tests/run-tests.py index 2745ee1393ba..8e9bd843134f 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -33,14 +33,16 @@ def base_path(*p): MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", base_path("../ports/windows/micropython.exe")) else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", base_path("../ports/unix/micropython")) + MICROPYTHON = os.getenv( + "MICROPY_MICROPYTHON", base_path("../ports/unix/build-standard/micropython") + ) # Use CPython options to not save .pyc files, to only access the core standard library # (not site packages which may clash with u-module names), and improve start up time. CPYTHON3_CMD = [CPYTHON3, "-BS"] # mpy-cross is only needed if --via-mpy command-line arg is passed -MPYCROSS = os.getenv("MICROPY_MPYCROSS", base_path("../mpy-cross/mpy-cross")) +MPYCROSS = os.getenv("MICROPY_MPYCROSS", base_path("../mpy-cross/build/mpy-cross")) # For diff'ing test output DIFF = os.getenv("MICROPY_DIFF", "diff -u") diff --git a/tools/ci.sh b/tools/ci.sh index 7e2479e43d38..20119342cfcf 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -409,9 +409,9 @@ function ci_unix_run_tests_full_helper { variant=$1 shift if [ $variant = standard ]; then - micropython=micropython + micropython=build-$variant/micropython else - micropython=micropython-$variant + micropython=build-$variant/micropython-$variant fi make -C ports/unix VARIANT=$variant "$@" test_full (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/$micropython ./run-multitests.py multi_net/*.py) @@ -444,7 +444,7 @@ function ci_unix_minimal_build { } function ci_unix_minimal_run_tests { - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython-minimal ./run-tests.py -e exception_chain -e self_type_check -e subclass_native_init -d basics) + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/build-minimal/micropython-minimal ./run-tests.py -e exception_chain -e self_type_check -e subclass_native_init -d basics) } function ci_unix_standard_build { @@ -491,21 +491,21 @@ function ci_unix_coverage_run_mpy_merge_tests { test=$(basename $inpy .py) echo $test outmpy=$outdir/$test.mpy - $mptop/mpy-cross/mpy-cross -o $outmpy $inpy - (cd $outdir && $mptop/ports/unix/micropython-coverage -m $test >> out-individual) + $mptop/mpy-cross/build/mpy-cross -o $outmpy $inpy + (cd $outdir && $mptop/ports/unix/build-coverage/micropython-coverage -m $test >> out-individual) allmpy+=($outmpy) done # Merge all the tests into one .mpy file, and then execute it. python3 $mptop/tools/mpy-tool.py --merge -o $outdir/merged.mpy ${allmpy[@]} - (cd $outdir && $mptop/ports/unix/micropython-coverage -m merged > out-merged) + (cd $outdir && $mptop/ports/unix/build-coverage/micropython-coverage -m merged > out-merged) # Make sure the outputs match. diff $outdir/out-individual $outdir/out-merged && /bin/rm -rf $outdir } function ci_unix_coverage_run_native_mpy_tests { - MICROPYPATH=examples/natmod/features2 ./ports/unix/micropython-coverage -m features2 + MICROPYPATH=examples/natmod/features2 ./ports/unix/build-coverage/micropython-coverage -m features2 (cd tests && ./run-natmodtests.py "$@" extmod/{btree*,framebuf*,uheapq*,urandom*,ure*,uzlib*}.py) } @@ -614,7 +614,7 @@ function ci_unix_macos_run_tests { # Issues with macOS tests: # - import_pkg7 has a problem with relative imports # - urandom_basic has a problem with getrandbits(0) - (cd tests && ./run-tests.py --exclude 'import_pkg7.py' --exclude 'urandom_basic.py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-standard/micropython ./run-tests.py --exclude 'import_pkg7.py' --exclude 'urandom_basic.py') } function ci_unix_qemu_mips_setup { @@ -634,7 +634,7 @@ function ci_unix_qemu_mips_run_tests { # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) # - ffi tests do not work file ./ports/unix/micropython-coverage - (cd tests && MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') } function ci_unix_qemu_arm_setup { @@ -654,7 +654,7 @@ function ci_unix_qemu_arm_run_tests { # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi file ./ports/unix/micropython-coverage - (cd tests && MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py') } ######################################################################################## diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 8cdc3eb7741b..e69698d3f234 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -329,7 +329,7 @@ def main(): sys.exit(1) # Get paths to tools - MPY_CROSS = VARS["MPY_DIR"] + "/mpy-cross/mpy-cross" + MPY_CROSS = VARS["MPY_DIR"] + "/mpy-cross/build/mpy-cross" if sys.platform == "win32": MPY_CROSS += ".exe" MPY_CROSS = os.getenv("MICROPY_MPYCROSS", MPY_CROSS) From 409995ac6828dc6bb70fcbe0bf9f26fd087ed22b Mon Sep 17 00:00:00 2001 From: Daniel Jour Date: Wed, 3 Aug 2022 01:32:51 +0200 Subject: [PATCH 1582/4290] tools/ci.sh: Force mpy-cross build for samd and teensy. --- tools/ci.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/ci.sh b/tools/ci.sh index 20119342cfcf..cf6fc4170587 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -293,6 +293,7 @@ function ci_samd_setup { } function ci_samd_build { + make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/samd submodules make ${MAKEOPTS} -C ports/samd } @@ -356,6 +357,7 @@ function ci_teensy_setup { } function ci_teensy_build { + make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/teensy submodules make ${MAKEOPTS} -C ports/teensy } From c7aa6a2c73854af9c0e9561e9213ef20abccf246 Mon Sep 17 00:00:00 2001 From: Daniel Jour Date: Wed, 3 Aug 2022 16:29:55 +0200 Subject: [PATCH 1583/4290] tests/run-tests.py: Provide better default MPYCROSS value for Windows. --- tests/run-tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/run-tests.py b/tests/run-tests.py index 8e9bd843134f..ca7941f6261b 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -31,18 +31,20 @@ def base_path(*p): if os.name == "nt": CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python") MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", base_path("../ports/windows/micropython.exe")) + # mpy-cross is only needed if --via-mpy command-line arg is passed + MPYCROSS = os.getenv("MICROPY_MPYCROSS", base_path("../mpy-cross/mpy-cross.exe")) else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") MICROPYTHON = os.getenv( "MICROPY_MICROPYTHON", base_path("../ports/unix/build-standard/micropython") ) + # mpy-cross is only needed if --via-mpy command-line arg is passed + MPYCROSS = os.getenv("MICROPY_MPYCROSS", base_path("../mpy-cross/build/mpy-cross")) # Use CPython options to not save .pyc files, to only access the core standard library # (not site packages which may clash with u-module names), and improve start up time. CPYTHON3_CMD = [CPYTHON3, "-BS"] -# mpy-cross is only needed if --via-mpy command-line arg is passed -MPYCROSS = os.getenv("MICROPY_MPYCROSS", base_path("../mpy-cross/build/mpy-cross")) # For diff'ing test output DIFF = os.getenv("MICROPY_DIFF", "diff -u") From d53c3b6ade01650f88972ccf7e3002d2b5a84ff6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 11 Aug 2022 12:40:23 +1000 Subject: [PATCH 1584/4290] unix/variants: Remove variant suffix from executable filename. The executable now lives in the build directory, and since the build directory already contains the variant name there is no need to also add it to the executable. Signed-off-by: Damien George --- .github/workflows/ports_unix.yml | 2 +- .../unix/variants/coverage/mpconfigvariant.mk | 2 -- ports/unix/variants/dev/mpconfigvariant.mk | 2 -- ports/unix/variants/fast/mpconfigvariant.mk | 2 -- .../unix/variants/freedos/mpconfigvariant.mk | 2 -- .../unix/variants/minimal/mpconfigvariant.mk | 1 - ports/unix/variants/nanbox/mpconfigvariant.mk | 1 - .../unix/variants/standard/mpconfigvariant.mk | 2 -- ports/windows/variants/dev/mpconfigvariant.mk | 2 -- tests/run-natmodtests.py | 2 +- tools/ci.sh | 26 ++++++++----------- tools/metrics.py | 4 +-- 12 files changed, 15 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index ab2406647a8c..45cc87e72394 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -35,7 +35,7 @@ jobs: env: SOURCE_DATE_EPOCH: 1234567890 - name: Check reproducible build date - run: echo | ports/unix/build-minimal/micropython-minimal -i | grep 'on 2009-02-13;' + run: echo | ports/unix/build-minimal/micropython -i | grep 'on 2009-02-13;' standard: runs-on: ubuntu-latest diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index fac8c0d2752e..bbbb0432b5b7 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -1,5 +1,3 @@ -PROG ?= micropython-coverage - # Disable optimisations and enable assert() on coverage builds. DEBUG ?= 1 diff --git a/ports/unix/variants/dev/mpconfigvariant.mk b/ports/unix/variants/dev/mpconfigvariant.mk index 78588d379bcd..058eda2f8d19 100644 --- a/ports/unix/variants/dev/mpconfigvariant.mk +++ b/ports/unix/variants/dev/mpconfigvariant.mk @@ -1,5 +1,3 @@ -PROG ?= micropython-dev - FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py MICROPY_ROM_TEXT_COMPRESSION = 1 diff --git a/ports/unix/variants/fast/mpconfigvariant.mk b/ports/unix/variants/fast/mpconfigvariant.mk index 595e5756457c..b8fe69e48731 100644 --- a/ports/unix/variants/fast/mpconfigvariant.mk +++ b/ports/unix/variants/fast/mpconfigvariant.mk @@ -2,6 +2,4 @@ COPT += -fno-crossjumping -O2 -PROG = micropython-fast - FROZEN_MANIFEST = diff --git a/ports/unix/variants/freedos/mpconfigvariant.mk b/ports/unix/variants/freedos/mpconfigvariant.mk index a30db3e0c149..86ab6864f45c 100644 --- a/ports/unix/variants/freedos/mpconfigvariant.mk +++ b/ports/unix/variants/freedos/mpconfigvariant.mk @@ -10,8 +10,6 @@ CFLAGS += \ -DMICROPY_EMIT_X86=0 \ -DMICROPY_NO_ALLOCA=1 \ -PROG = micropython-freedos - MICROPY_PY_SOCKET = 0 MICROPY_PY_FFI = 0 MICROPY_PY_JNI = 0 diff --git a/ports/unix/variants/minimal/mpconfigvariant.mk b/ports/unix/variants/minimal/mpconfigvariant.mk index ec3b21c0b979..9d4ddab9563e 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.mk +++ b/ports/unix/variants/minimal/mpconfigvariant.mk @@ -1,5 +1,4 @@ # build a minimal interpreter -PROG = micropython-minimal FROZEN_MANIFEST = diff --git a/ports/unix/variants/nanbox/mpconfigvariant.mk b/ports/unix/variants/nanbox/mpconfigvariant.mk index 9752b922c1e3..e588e657efc5 100644 --- a/ports/unix/variants/nanbox/mpconfigvariant.mk +++ b/ports/unix/variants/nanbox/mpconfigvariant.mk @@ -1,4 +1,3 @@ # build interpreter with nan-boxing as object model (object repr D) -PROG = micropython-nanbox MICROPY_FORCE_32BIT = 1 diff --git a/ports/unix/variants/standard/mpconfigvariant.mk b/ports/unix/variants/standard/mpconfigvariant.mk index cf3efab8ae7d..def7987d8dc8 100644 --- a/ports/unix/variants/standard/mpconfigvariant.mk +++ b/ports/unix/variants/standard/mpconfigvariant.mk @@ -1,3 +1 @@ # This is the default variant when you `make` the Unix port. - -PROG ?= micropython diff --git a/ports/windows/variants/dev/mpconfigvariant.mk b/ports/windows/variants/dev/mpconfigvariant.mk index b2a0b5bb3388..6d83f5b4dbc4 100644 --- a/ports/windows/variants/dev/mpconfigvariant.mk +++ b/ports/windows/variants/dev/mpconfigvariant.mk @@ -1,5 +1,3 @@ -PROG ?= micropython-dev - FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py MICROPY_ROM_TEXT_COMPRESSION = 1 diff --git a/tests/run-natmodtests.py b/tests/run-natmodtests.py index 9130e00d6eba..16bb46922256 100755 --- a/tests/run-natmodtests.py +++ b/tests/run-natmodtests.py @@ -14,7 +14,7 @@ # Paths for host executables CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") -MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-coverage/micropython-coverage") +MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-coverage/micropython") NATMOD_EXAMPLE_DIR = "../examples/natmod/" diff --git a/tools/ci.sh b/tools/ci.sh index cf6fc4170587..e3203f8bfb9f 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -410,14 +410,10 @@ function ci_unix_run_tests_helper { function ci_unix_run_tests_full_helper { variant=$1 shift - if [ $variant = standard ]; then - micropython=build-$variant/micropython - else - micropython=build-$variant/micropython-$variant - fi + micropython=../ports/unix/build-$variant/micropython make -C ports/unix VARIANT=$variant "$@" test_full - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/$micropython ./run-multitests.py multi_net/*.py) - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/$micropython ./run-perfbench.py 1000 1000) + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=$micropython ./run-multitests.py multi_net/*.py) + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=$micropython ./run-perfbench.py 1000 1000) } function ci_native_mpy_modules_build { @@ -446,7 +442,7 @@ function ci_unix_minimal_build { } function ci_unix_minimal_run_tests { - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/build-minimal/micropython-minimal ./run-tests.py -e exception_chain -e self_type_check -e subclass_native_init -d basics) + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/build-minimal/micropython ./run-tests.py -e exception_chain -e self_type_check -e subclass_native_init -d basics) } function ci_unix_standard_build { @@ -494,20 +490,20 @@ function ci_unix_coverage_run_mpy_merge_tests { echo $test outmpy=$outdir/$test.mpy $mptop/mpy-cross/build/mpy-cross -o $outmpy $inpy - (cd $outdir && $mptop/ports/unix/build-coverage/micropython-coverage -m $test >> out-individual) + (cd $outdir && $mptop/ports/unix/build-coverage/micropython -m $test >> out-individual) allmpy+=($outmpy) done # Merge all the tests into one .mpy file, and then execute it. python3 $mptop/tools/mpy-tool.py --merge -o $outdir/merged.mpy ${allmpy[@]} - (cd $outdir && $mptop/ports/unix/build-coverage/micropython-coverage -m merged > out-merged) + (cd $outdir && $mptop/ports/unix/build-coverage/micropython -m merged > out-merged) # Make sure the outputs match. diff $outdir/out-individual $outdir/out-merged && /bin/rm -rf $outdir } function ci_unix_coverage_run_native_mpy_tests { - MICROPYPATH=examples/natmod/features2 ./ports/unix/build-coverage/micropython-coverage -m features2 + MICROPYPATH=examples/natmod/features2 ./ports/unix/build-coverage/micropython -m features2 (cd tests && ./run-natmodtests.py "$@" extmod/{btree*,framebuf*,uheapq*,urandom*,ure*,uzlib*}.py) } @@ -635,8 +631,8 @@ function ci_unix_qemu_mips_run_tests { # Issues with MIPS tests: # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) # - ffi tests do not work - file ./ports/unix/micropython-coverage - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') + file ./ports/unix/build-coverage/micropython + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') } function ci_unix_qemu_arm_setup { @@ -655,8 +651,8 @@ function ci_unix_qemu_arm_run_tests { # Issues with ARM tests: # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi - file ./ports/unix/micropython-coverage - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py') + file ./ports/unix/build-coverage/micropython + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.py') } ######################################################################################## diff --git a/tools/metrics.py b/tools/metrics.py index c79b998e1846..da4d188568fd 100755 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -60,8 +60,8 @@ def __init__(self, name, dir, output, make_flags=None): port_data = { "b": PortData("bare-arm", "bare-arm", "build/firmware.elf"), "m": PortData("minimal x86", "minimal", "build/firmware.elf"), - "u": PortData("unix x64", "unix", "micropython"), - "n": PortData("unix nanbox", "unix", "micropython-nanbox", "VARIANT=nanbox"), + "u": PortData("unix x64", "unix", "build-standard/micropython"), + "n": PortData("unix nanbox", "unix", "build-nanbox/micropython", "VARIANT=nanbox"), "s": PortData("stm32", "stm32", "build-PYBV10/firmware.elf", "BOARD=PYBV10"), "c": PortData("cc3200", "cc3200", "build/WIPY/release/application.axf", "BTARGET=application"), "8": PortData("esp8266", "esp8266", "build-GENERIC/firmware.elf"), From 2e8816de915244ee5612178711237f4f88d754ed Mon Sep 17 00:00:00 2001 From: Mat Booth Date: Sun, 31 Jul 2022 11:41:54 +0100 Subject: [PATCH 1585/4290] py/dynruntime.mk: Allow building assembly source in natmods. Allow inclusion of assembly source files in dynamic native modules. --- py/dynruntime.mk | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/py/dynruntime.mk b/py/dynruntime.mk index 10feefc4a7c2..62db43ad149c 100644 --- a/py/dynruntime.mk +++ b/py/dynruntime.mk @@ -35,7 +35,7 @@ CFLAGS += -U _FORTIFY_SOURCE # prevent use of __*_chk libc functions MPY_CROSS_FLAGS += -march=$(ARCH) -SRC_O += $(addprefix $(BUILD)/, $(patsubst %.c,%.o,$(filter %.c,$(SRC)))) +SRC_O += $(addprefix $(BUILD)/, $(patsubst %.c,%.o,$(filter %.c,$(SRC))) $(patsubst %.S,%.o,$(filter %.S,$(SRC)))) SRC_MPY += $(addprefix $(BUILD)/, $(patsubst %.py,%.mpy,$(filter %.py,$(SRC)))) ################################################################################ @@ -134,6 +134,11 @@ $(BUILD)/%.o: %.c $(CONFIG_H) Makefile $(ECHO) "CC $<" $(Q)$(CROSS)gcc $(CFLAGS) -o $@ -c $< +# Build .o from .S source files +$(BUILD)/%.o: %.S $(CONFIG_H) Makefile + $(ECHO) "AS $<" + $(Q)$(CROSS)gcc $(CFLAGS) -o $@ -c $< + # Build .mpy from .py source files $(BUILD)/%.mpy: %.py $(ECHO) "MPY $<" From f3285fef07b4baa64cb05ef6dc034496cb0effdc Mon Sep 17 00:00:00 2001 From: Efi Weiss Date: Sun, 31 Jul 2022 22:16:49 +0300 Subject: [PATCH 1586/4290] py/nlrpowerpc: Fix generation of ppc64 code on ppc32 build. Due to inline assembly, wrong instructions were generated. Use corresponding 32 bit instructions and fix the offsets used. Signed-off-by: Efi Weiss --- py/nlrpowerpc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/py/nlrpowerpc.c b/py/nlrpowerpc.c index 940d8562e120..448459216b6e 100644 --- a/py/nlrpowerpc.c +++ b/py/nlrpowerpc.c @@ -32,6 +32,8 @@ // Saving all ABI non-vol registers here +#ifdef __LP64__ + unsigned int nlr_push(nlr_buf_t *nlr) { __asm__ volatile ( @@ -118,4 +120,95 @@ NORETURN void nlr_jump(void *val) { MP_UNREACHABLE; } +#else +// Saving all ABI non-vol registers here + +unsigned int nlr_push(nlr_buf_t *nlr) { + + __asm__ volatile ( + "li 4, 0x4eed ; " // Store canary + "stw 4, 0x00(%0) ;" + "stw 0, 0x04(%0) ;" + "stw 1, 0x08(%0) ;" + "stw 2, 0x0c(%0) ;" + "stw 14, 0x10(%0) ;" + "stw 15, 0x14(%0) ;" + "stw 16, 0x18(%0) ;" + "stw 17, 0x1c(%0) ;" + "stw 18, 0x20(%0) ;" + "stw 19, 0x24(%0) ;" + "stw 20, 0x28(%0) ;" + "stw 21, 0x2c(%0) ;" + "stw 22, 0x30(%0) ;" + "stw 23, 0x34(%0) ;" + "stw 24, 0x38(%0) ;" + "stw 25, 0x3c(%0) ;" + "stw 26, 0x40(%0) ;" + "stw 27, 0x44(%0) ;" + "stw 28, 0x48(%0) ;" + "stw 29, 0x4c(%0) ;" + "stw 30, 0x50(%0) ;" + "stw 31, 0x54(%0) ;" + + "mfcr 4 ; " + "stw 4, 0x58(%0) ;" + "mflr 4 ;" + "stw 4, 0x5c(%0) ;" + "li 4, nlr_push_tail@l ;" + "oris 4, 4, nlr_push_tail@h ;" + "mtctr 4 ;" + "mr 3, %1 ; " + "bctr ;" + : + : "r" (&nlr->regs), "r" (nlr) + : + ); + + return 0; +} + +NORETURN void nlr_jump(void *val) { + MP_NLR_JUMP_HEAD(val, top) + + __asm__ volatile ( + "l 3, 0x0(%0) ;" + "cmpdi 3, 0x4eed ; " // Check canary + "bne . ; " + "l 0, 0x04(%0) ;" + "l 1, 0x08(%0) ;" + "l 2, 0x0c(%0) ;" + "l 14, 0x10(%0) ;" + "l 15, 0x14(%0) ;" + "l 16, 0x18(%0) ;" + "l 17, 0x1c(%0) ;" + "l 18, 0x20(%0) ;" + "l 19, 0x24(%0) ;" + "l 20, 0x28(%0) ;" + "l 21, 0x2c(%0) ;" + "l 22, 0x30(%0) ;" + "l 23, 0x34(%0) ;" + "l 24, 0x38(%0) ;" + "l 25, 0x3c(%0) ;" + "l 26, 0x40(%0) ;" + "l 27, 0x44(%0) ;" + "l 28, 0x48(%0) ;" + "l 29, 0x4c(%0) ;" + "l 30, 0x50(%0) ;" + "l 31, 0x54(%0) ;" + "l 3, 0x58(%0) ;" + "mtcr 3 ;" + "l 3, 0x5c(%0) ;" + "mtlr 3 ; " + "li 3, 1;" + "blr ;" + : + : "r" (&top->regs) + : + ); + + MP_UNREACHABLE; +} + +#endif // __LP64__ + #endif // MICROPY_NLR_POWERPC From 9c6fd974f769ef1e907c1a41f4a5d9b1c1774df7 Mon Sep 17 00:00:00 2001 From: Daniel Jour Date: Sun, 31 Jul 2022 18:01:13 +0200 Subject: [PATCH 1587/4290] minimal/Makefile: Avoid terminal reset, use BUILD variable. stty can provide the current terminal settings, so that they can be stored in a shell variable and restored after running the firmware. This avoids the complete "blanking" of the terminal, and thus also removes the need for the sleep call. The run target now references the firmware file using the BUILD variable instead of using the hard coded "build/" path. --- ports/minimal/Makefile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ports/minimal/Makefile b/ports/minimal/Makefile index 169132a1a29f..5ba6514c9ed4 100644 --- a/ports/minimal/Makefile +++ b/ports/minimal/Makefile @@ -103,12 +103,11 @@ deploy: $(BUILD)/firmware.dfu # Run emulation build on a POSIX system with suitable terminal settings run: - stty raw opost -echo - build/firmware.elf - @echo Resetting terminal... -# This sleep is useful to spot segfaults - sleep 1 - reset + @saved_=`stty -g`; \ + stty raw opost -echo; \ + $(BUILD)/firmware.elf; \ + echo "Exit status: $$?"; \ + stty $$saved_ test: $(BUILD)/firmware.elf $(Q)/bin/echo -e "print('hello world!', list(x+1 for x in range(10)), end='eol\\\\n')\\r\\n\\x04" | $(BUILD)/firmware.elf | tail -n2 | grep "^hello world! \\[1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\]eol" From b6651a7a89a666ca76cdc03e065e339dbf3b9298 Mon Sep 17 00:00:00 2001 From: David Yang Date: Mon, 4 Jan 2021 23:22:08 +0800 Subject: [PATCH 1588/4290] unix/modjni: Add missing const qualifier. --- ports/unix/modjni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index c86f30653c81..6fa00731fb75 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -376,7 +376,7 @@ STATIC const char *strprev(const char *s, char c) { STATIC bool py2jvalue(const char **jtypesig, mp_obj_t arg, jvalue *out) { const char *arg_type = *jtypesig; - mp_obj_type_t *type = mp_obj_get_type(arg); + const mp_obj_type_t *type = mp_obj_get_type(arg); if (type == &mp_type_str) { if (IMATCH(arg_type, "java.lang.String") || IMATCH(arg_type, "java.lang.Object")) { From 6e51dbd95aa051533e2618e2df8f51cb0f06cfed Mon Sep 17 00:00:00 2001 From: omogenot Date: Tue, 26 Jul 2022 16:36:10 +0200 Subject: [PATCH 1589/4290] rp2/boards/W5500_EVB_PICO: Add new board definition for W5500_EVB_PICO. Signed-off-by: github@mymeterinfo.info --- ports/rp2/boards/W5500_EVB_PICO/board.json | 20 +++++++++++++++++++ .../boards/W5500_EVB_PICO/mpconfigboard.cmake | 4 ++++ .../rp2/boards/W5500_EVB_PICO/mpconfigboard.h | 19 ++++++++++++++++++ ports/rp2/boards/W5500_EVB_PICO/readme.md | 18 +++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 ports/rp2/boards/W5500_EVB_PICO/board.json create mode 100644 ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake create mode 100644 ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.h create mode 100644 ports/rp2/boards/W5500_EVB_PICO/readme.md diff --git a/ports/rp2/boards/W5500_EVB_PICO/board.json b/ports/rp2/boards/W5500_EVB_PICO/board.json new file mode 100644 index 000000000000..90b3186cd6b1 --- /dev/null +++ b/ports/rp2/boards/W5500_EVB_PICO/board.json @@ -0,0 +1,20 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Breadboard Friendly", + "Castellated Pads", + "Ethernet", + "Micro USB" + ], + "images": [ + "W5500-EVB-Pico.jpg" + ], + "mcu": "rp2040", + "product": "Wiznet W5500-EVB-Pico", + "thumbnail": "", + "url": "https://www.wiznet.io/product-item/w5500-evb-pico/", + "vendor": "Wiznet" +} diff --git a/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake b/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake new file mode 100644 index 000000000000..875b89f2befe --- /dev/null +++ b/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake @@ -0,0 +1,4 @@ +# cmake file for Wiznet W5500-EVB-Pico. +set(PICO_BOARD pico) +set(MICROPY_PY_NETWORK_WIZNET5K W5500) +set(MICROPY_PY_LWIP 1) diff --git a/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.h b/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.h new file mode 100644 index 000000000000..1ad7a0e90532 --- /dev/null +++ b/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.h @@ -0,0 +1,19 @@ +// Board config for Wiznet W5500-EVB-Pico. + +// Board and hardware specific configuration +#define MICROPY_HW_BOARD_NAME "W5500-EVB-Pico" +#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024) + +// Enable networking. +#define MICROPY_PY_NETWORK (1) + +// Wiznet HW config. +#define MICROPY_HW_WIZNET_SPI_ID (0) +#define MICROPY_HW_WIZNET_SPI_BAUDRATE (20 * 1000 * 1000) +#define MICROPY_HW_WIZNET_SPI_SCK (18) +#define MICROPY_HW_WIZNET_SPI_MOSI (19) +#define MICROPY_HW_WIZNET_SPI_MISO (16) +#define MICROPY_HW_WIZNET_PIN_CS (17) +#define MICROPY_HW_WIZNET_PIN_RST (20) +// Connecting the INTN pin enables RECV interrupt handling of incoming data. +#define MICROPY_HW_WIZNET_PIN_INTN (21) diff --git a/ports/rp2/boards/W5500_EVB_PICO/readme.md b/ports/rp2/boards/W5500_EVB_PICO/readme.md new file mode 100644 index 000000000000..be28286695fa --- /dev/null +++ b/ports/rp2/boards/W5500_EVB_PICO/readme.md @@ -0,0 +1,18 @@ +# Wiznet W5500-EVB-Pico + +## Network Example + +To use network / socket based code, connect ethernet port to network with DHCP running: + +``` +>>> import network +>>> nic = network.WIZNET5K() +>>> nic.active(True) +>>> nic.ifconfig() +('0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0') +>>> nic.ifconfig("dhcp") +('192.168.0.10', '255.255.255.0', '192.168.0.1', '192.168.0.1') +>>> nic.isconnected() +True +``` +At this point standard network communications libraries should work. From 71f6eb5ac953637e815ec9c5cbc785b4027a8759 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 5 Aug 2022 09:43:22 +0100 Subject: [PATCH 1590/4290] rp2: Mark gc_heap NOLOAD for faster boot. Create a new linker section .unitialized_bss for bss that does not need zero-initialising. Move gc_heap to this section, which saves ~30ms from rising edge of RESET to setting a pin HIGH in MicroPython. Zero fill happens in Pico SDK crt0.S before ROSC is configured. It's very, very slow. Signed-off-by: Phil Howard --- ports/rp2/main.c | 2 +- ports/rp2/memmap_mp.ld | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ports/rp2/main.c b/ports/rp2/main.c index d976464de1cc..1062236a3916 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -66,7 +66,7 @@ #endif extern uint8_t __StackTop, __StackBottom; -static char gc_heap[MICROPY_GC_HEAP_SIZE]; +__attribute__((section(".uninitialized_bss"))) static char gc_heap[MICROPY_GC_HEAP_SIZE]; // Embed version info in the binary in machine readable form bi_decl(bi_program_version_string(MICROPY_GIT_TAG)); diff --git a/ports/rp2/memmap_mp.ld b/ports/rp2/memmap_mp.ld index 0dc96743ea5c..82f9cb01c3ef 100644 --- a/ports/rp2/memmap_mp.ld +++ b/ports/rp2/memmap_mp.ld @@ -180,6 +180,12 @@ SECTIONS *(.uninitialized_data*) } > RAM + /* bss without zero init on startup */ + .uninitialized_bss (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_bss*) + } > RAM + /* Start and end symbols must be word-aligned */ .scratch_x : { __scratch_x_start__ = .; From 0546a12238b53f3243cc6ae5dfbb7bcac1d0be9a Mon Sep 17 00:00:00 2001 From: Jacob Siverskog Date: Tue, 9 Aug 2022 14:21:05 +0200 Subject: [PATCH 1591/4290] rp2: Correctly determine path to arm-none-eabi-size. Figure out path to arm-none-eabi-size the same way it's done for the other binaries, instead of assuming it to be in the user's $PATH. Signed-off-by: Jacob Siverskog --- ports/rp2/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index f5bd61c44ea8..37ac78b7339f 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -412,9 +412,11 @@ endif() pico_add_extra_outputs(${MICROPY_TARGET}) +pico_find_compiler(PICO_COMPILER_SIZE ${PICO_GCC_TRIPLE}-size) + add_custom_command(TARGET ${MICROPY_TARGET} POST_BUILD - COMMAND arm-none-eabi-size --format=berkeley ${PROJECT_BINARY_DIR}/${MICROPY_TARGET}.elf + COMMAND ${PICO_COMPILER_SIZE} --format=berkeley ${PROJECT_BINARY_DIR}/${MICROPY_TARGET}.elf VERBATIM ) From 888e831bf78518c367d40a6b77b29c6aab13a7f0 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 8 Jul 2022 13:47:54 -0500 Subject: [PATCH 1592/4290] docs: Update links for Arm GCC toolchain. The separate A and RM toolchains have been discontinued and replaced by a single toolchain. This updates the links to the RM toolchain to the new toolchain. Signed-off-by: David Lechner --- README.md | 2 +- docs/develop/gettingstarted.rst | 2 +- ports/qemu-arm/README.md | 2 +- ports/renesas-ra/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 920f10a5035b..6941102f0ac4 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ The STM32 version The "stm32" port requires an ARM compiler, arm-none-eabi-gcc, and associated bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils, arm-none-eabi-gcc and arm-none-eabi-newlib packages. Otherwise, try here: -https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm +https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads To build: diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst index 36062ddc008b..000b7d61390c 100644 --- a/docs/develop/gettingstarted.rst +++ b/docs/develop/gettingstarted.rst @@ -103,7 +103,7 @@ For the stm32 port, the ARM cross-compiler is required: $ sudo apt-get install arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib See the `ARM GCC -toolchain `_ +toolchain `_ for the latest details. Python is also required. Python 2 is supported for now, but we recommend using Python 3. diff --git a/ports/qemu-arm/README.md b/ports/qemu-arm/README.md index 2c815c54b088..f821c4d1e28f 100644 --- a/ports/qemu-arm/README.md +++ b/ports/qemu-arm/README.md @@ -16,7 +16,7 @@ The purposes of this port are to enable: process in terms of plugging things together, pressing buttons, etc. This port will only work with the [GNU ARM Embedded Toolchain]( -https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm) +https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads and not with CodeSourcery toolchain. You will need to modify `LDFLAGS` if you want to use CodeSourcery's version of `arm-none-eabi`. The difference is that CodeSourcery needs `-T generic-m-hosted.ld` while diff --git a/ports/renesas-ra/README.md b/ports/renesas-ra/README.md index 482870e1c036..c75a9e13d1ed 100644 --- a/ports/renesas-ra/README.md +++ b/ports/renesas-ra/README.md @@ -36,7 +36,7 @@ All other commands below should be executed from the ports/renesas-ra/ directory * Arm compiler An `Arm compiler` is required for the build, along with the associated binary utilities. The default compiler is `arm-none-eabi-gcc`, which is available for -Arch Linux and Windows hosts via https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads. +Linux, Mac and Windows hosts via https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads. The compiler can be changed using the `CROSS_COMPILE` variable when invoking `make`. From 9bcb2c0a209f7970e63757a5f99dd23e010dbc48 Mon Sep 17 00:00:00 2001 From: Nathan Hendler Date: Sun, 31 Jul 2022 11:40:44 -0700 Subject: [PATCH 1593/4290] docs/library/rp2: Fix pull_thresh docs to use pull instead of push. --- docs/library/rp2.StateMachine.rst | 4 ++-- docs/library/rp2.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/library/rp2.StateMachine.rst b/docs/library/rp2.StateMachine.rst index 8d73ccf772a7..7e38ba8b1a75 100644 --- a/docs/library/rp2.StateMachine.rst +++ b/docs/library/rp2.StateMachine.rst @@ -55,8 +55,8 @@ Methods `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. - *push_thresh* is the threshold in bits before auto-push or conditional re-pushing is triggered. - - *pull_thresh* is the threshold in bits before auto-push or conditional - re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-pull or conditional + re-pulling is triggered. .. method:: StateMachine.active([value]) diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst index 06affaae8cac..ec7666d7cef4 100644 --- a/docs/library/rp2.rst +++ b/docs/library/rp2.rst @@ -47,8 +47,8 @@ For running PIO programs, see :class:`rp2.StateMachine`. `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. - *push_thresh* is the threshold in bits before auto-push or conditional re-pushing is triggered. - - *pull_thresh* is the threshold in bits before auto-push or conditional - re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-pull or conditional + re-pulling is triggered. The remaining parameters are: From bfc63a5c844cd9efa25a44b418be201984fa231c Mon Sep 17 00:00:00 2001 From: Kyuchumimo <74131798+Kyuchumimo@users.noreply.github.com> Date: Tue, 9 Aug 2022 18:30:21 -0600 Subject: [PATCH 1594/4290] drivers/sdcard: Add delay in init_card_v1 to make timeout work. This now follows how init_card_v2 works. --- drivers/sdcard/sdcard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py index f4520acbb537..df28bd953448 100644 --- a/drivers/sdcard/sdcard.py +++ b/drivers/sdcard/sdcard.py @@ -118,6 +118,7 @@ def init_card(self, baudrate): def init_card_v1(self): for i in range(_CMD_TIMEOUT): + time.sleep_ms(50) self.cmd(55, 0, 0) if self.cmd(41, 0, 0) == 0: # SDSC card, uses byte addressing in read/write/erase commands From 94a19f10628f9c3a9978daae9f6f4c7ac352e9a2 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 11 Aug 2022 16:53:42 +1000 Subject: [PATCH 1595/4290] windows/Makefile: Update test dependency on $(PROG). PR #9012 (b2e82402688b53829f37475583231b067b9faea7) changed the output to $(BUILD)/$(PROG) but the tests are still looking for $(PROG). Also remove the now-unnecessary override of $(PROG) in the standard variant. Signed-off-by: Jim Mussared --- ports/windows/Makefile | 7 +++---- ports/windows/variants/standard/mpconfigvariant.mk | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ports/windows/Makefile b/ports/windows/Makefile index 45d61b0b50ac..1e793800f804 100644 --- a/ports/windows/Makefile +++ b/ports/windows/Makefile @@ -16,7 +16,6 @@ include $(VARIANT_DIR)/mpconfigvariant.mk FROZEN_MANIFEST ?= variants/manifest.py # Define main target -# This should be configured by the mpconfigvariant.mk PROG ?= micropython # qstr definitions (must come before including py.mk) @@ -98,10 +97,10 @@ include $(TOP)/py/mkrules.mk RUN_TESTS_SKIP += -e math_fun -e float2int_double -e float_parse -e math_domain_special -test: $(PROG) $(TOP)/tests/run-tests.py +test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) $(PYTHON) ./run-tests.py $(RUN_TESTS_SKIP) + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) $(PYTHON) ./run-tests.py $(RUN_TESTS_SKIP) test_full: test $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) $(PYTHON) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) $(RUN_TESTS_SKIP) -d basics float micropython + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) $(PYTHON) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) $(RUN_TESTS_SKIP) -d basics float micropython diff --git a/ports/windows/variants/standard/mpconfigvariant.mk b/ports/windows/variants/standard/mpconfigvariant.mk index 9e1f5ae059ce..a0d6712c5531 100644 --- a/ports/windows/variants/standard/mpconfigvariant.mk +++ b/ports/windows/variants/standard/mpconfigvariant.mk @@ -1,3 +1 @@ # This is the default variant when you `make` the Windows port. - -PROG ?= micropython From 82b3500724206f2baa342a3559bbe716e9819426 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 11 Aug 2022 16:34:02 +1000 Subject: [PATCH 1596/4290] py/qstr: Change qstr hash type from mp_uint_t to size_t. The hash is either 8 or 16 bits (depending on MICROPY_QSTR_BYTES_IN_HASH) so will fit in a size_t. This saves 268 bytes on the unix nanbox build. Non-nanbox configurations are unchanged because mp_uint_t is the same size as size_t. Signed-off-by: Damien George --- py/objstr.h | 4 ++-- py/qstr.c | 8 ++++---- py/qstr.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/py/objstr.h b/py/objstr.h index 8f87c3018a3c..92b065d869b4 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -30,7 +30,7 @@ typedef struct _mp_obj_str_t { mp_obj_base_t base; - mp_uint_t hash; + size_t hash; // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte size_t len; const byte *data; @@ -41,7 +41,7 @@ typedef struct _mp_obj_str_t { // use this macro to extract the string hash // warning: the hash can be 0, meaning invalid, and must then be explicitly computed from the data #define GET_STR_HASH(str_obj_in, str_hash) \ - mp_uint_t str_hash; \ + size_t str_hash; \ if (mp_obj_is_qstr(str_obj_in)) { \ str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); \ } else { \ diff --git a/py/qstr.c b/py/qstr.c index f9ca10683749..ea700566f4f7 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -60,9 +60,9 @@ #define MICROPY_ALLOC_QSTR_ENTRIES_INIT (10) // this must match the equivalent function in makeqstrdata.py -mp_uint_t qstr_compute_hash(const byte *data, size_t len) { +size_t qstr_compute_hash(const byte *data, size_t len) { // djb2 algorithm; see http://www.cse.yorku.ca/~oz/hash.html - mp_uint_t hash = 5381; + size_t hash = 5381; for (const byte *top = data + len; data < top; data++) { hash = ((hash << 5) + hash) ^ (*data); // hash * 33 ^ data } @@ -181,7 +181,7 @@ STATIC qstr qstr_add(mp_uint_t hash, mp_uint_t len, const char *q_ptr) { qstr qstr_find_strn(const char *str, size_t str_len) { // work out hash of str - mp_uint_t str_hash = qstr_compute_hash((const byte *)str, str_len); + size_t str_hash = qstr_compute_hash((const byte *)str, str_len); // search pools for the data for (const qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL; pool = pool->prev) { @@ -254,7 +254,7 @@ qstr qstr_from_strn(const char *str, size_t len) { MP_STATE_VM(qstr_last_used) += n_bytes; // store the interned strings' data - mp_uint_t hash = qstr_compute_hash((const byte *)str, len); + size_t hash = qstr_compute_hash((const byte *)str, len); memcpy(q_ptr, str, len); q_ptr[len] = '\0'; q = qstr_add(hash, len, q_ptr); diff --git a/py/qstr.h b/py/qstr.h index a463b67a1836..0ef861f33e8d 100644 --- a/py/qstr.h +++ b/py/qstr.h @@ -78,7 +78,7 @@ typedef struct _qstr_pool_t { void qstr_init(void); -mp_uint_t qstr_compute_hash(const byte *data, size_t len); +size_t qstr_compute_hash(const byte *data, size_t len); qstr qstr_find_strn(const char *str, size_t str_len); // returns MP_QSTRnull if not found qstr qstr_from_str(const char *str); From f7f56d42851aaff2027e23a8ca45c1f1973f1aca Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 10 Aug 2022 14:13:17 +1000 Subject: [PATCH 1597/4290] py/objstr: Consolidate methods for str/bytes/bytearray/array. This commit adds the bytes methods to bytearray, matching CPython. The existing implementations of these methods for str/bytes are reused for bytearray with minor updates to match CPython return types. For details on the CPython behaviour see https://docs.python.org/3/library/stdtypes.html#bytes-and-bytearray-operations The work to merge locals tables for str/bytes/bytearray/array was done by @jimmo. Because of this merging of locals the change in code size for this commit is mostly negative: bare-arm: +0 +0.000% minimal x86: +29 +0.018% unix x64: -792 -0.128% standard[incl -448(data)] unix nanbox: -436 -0.078% nanbox[incl -448(data)] stm32: -40 -0.010% PYBV10 cc3200: -32 -0.017% esp8266: -28 -0.004% GENERIC esp32: -72 -0.005% GENERIC[incl -200(data)] mimxrt: -40 -0.011% TEENSY40 renesas-ra: -40 -0.006% RA6M2_EK nrf: -16 -0.009% pca10040 rp2: -64 -0.013% PICO samd: +148 +0.105% ADAFRUIT_ITSYBITSY_M4_EXPRESS --- py/obj.h | 10 +- py/objarray.c | 22 +-- py/objarray.h | 5 + py/objstr.c | 157 ++++++++++++++++------ py/objstr.h | 19 +++ py/objstrunicode.c | 50 +------ tests/basics/bytearray_byte_operations.py | 35 +++++ tests/basics/bytearray_center.py | 8 ++ tests/basics/bytearray_count.py | 7 + tests/basics/bytearray_partition.py | 8 ++ tests/basics/bytes_center.py | 13 ++ 11 files changed, 225 insertions(+), 109 deletions(-) create mode 100644 tests/basics/bytearray_byte_operations.py create mode 100644 tests/basics/bytearray_center.py create mode 100644 tests/basics/bytearray_count.py create mode 100644 tests/basics/bytearray_partition.py create mode 100644 tests/basics/bytes_center.py diff --git a/py/obj.h b/py/obj.h index 7ba4c0a5f289..598d6508da73 100644 --- a/py/obj.h +++ b/py/obj.h @@ -394,19 +394,21 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; .table = (mp_map_elem_t *)(mp_rom_map_elem_t *)table_name, \ } -#define MP_DEFINE_CONST_DICT(dict_name, table_name) \ +#define MP_DEFINE_CONST_DICT_WITH_SIZE(dict_name, table_name, n) \ const mp_obj_dict_t dict_name = { \ .base = {&mp_type_dict}, \ .map = { \ .all_keys_are_qstrs = 1, \ .is_fixed = 1, \ .is_ordered = 1, \ - .used = MP_ARRAY_SIZE(table_name), \ - .alloc = MP_ARRAY_SIZE(table_name), \ + .used = n, \ + .alloc = n, \ .table = (mp_map_elem_t *)(mp_rom_map_elem_t *)table_name, \ }, \ } +#define MP_DEFINE_CONST_DICT(dict_name, table_name) MP_DEFINE_CONST_DICT_WITH_SIZE(dict_name, table_name, MP_ARRAY_SIZE(table_name)) + // These macros are used to declare and define constant staticmethond and classmethod objects // You can put "static" in front of the definitions to make them local @@ -789,7 +791,7 @@ mp_obj_t mp_obj_new_str(const char *data, size_t len); mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte *data, size_t len); -mp_obj_t mp_obj_new_bytearray(size_t n, void *items); +mp_obj_t mp_obj_new_bytearray(size_t n, const void *items); mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT mp_obj_t mp_obj_new_int_from_float(mp_float_t val); diff --git a/py/objarray.c b/py/objarray.c index bff3126a2bc4..11bd7bb15c41 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -381,7 +381,7 @@ STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) { self->free--; return mp_const_none; // return None, as per CPython } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_append_obj, array_append); +MP_DEFINE_CONST_FUN_OBJ_2(mp_obj_array_append_obj, array_append); STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { // self is not a memoryview, so we don't need to use (& TYPECODE_MASK) @@ -413,7 +413,7 @@ STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend); +MP_DEFINE_CONST_FUN_OBJ_2(mp_obj_array_extend_obj, array_extend); #endif STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { @@ -564,18 +564,6 @@ STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_ui return 0; } -#if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY -STATIC const mp_rom_map_elem_t array_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&array_append_obj) }, - { MP_ROM_QSTR(MP_QSTR_extend), MP_ROM_PTR(&array_extend_obj) }, - #if MICROPY_CPYTHON_COMPAT - { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&bytes_decode_obj) }, - #endif -}; - -STATIC MP_DEFINE_CONST_DICT(array_locals_dict, array_locals_dict_table); -#endif - #if MICROPY_PY_ARRAY const mp_obj_type_t mp_type_array = { { &mp_type_type }, @@ -587,7 +575,7 @@ const mp_obj_type_t mp_type_array = { .binary_op = array_binary_op, .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, - .locals_dict = (mp_obj_dict_t *)&array_locals_dict, + .locals_dict = (mp_obj_dict_t *)&mp_obj_array_locals_dict, }; #endif @@ -603,7 +591,7 @@ const mp_obj_type_t mp_type_bytearray = { .binary_op = array_binary_op, .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, - .locals_dict = (mp_obj_dict_t *)&array_locals_dict, + .locals_dict = (mp_obj_dict_t *)&mp_obj_bytearray_locals_dict, }; #endif @@ -631,7 +619,7 @@ size_t mp_obj_array_len(mp_obj_t self_in) { */ #if MICROPY_PY_BUILTINS_BYTEARRAY -mp_obj_t mp_obj_new_bytearray(size_t n, void *items) { +mp_obj_t mp_obj_new_bytearray(size_t n, const void *items) { mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, n); memcpy(o->items, items, n); return MP_OBJ_FROM_PTR(o); diff --git a/py/objarray.h b/py/objarray.h index 94c31c969386..48a26c3fb301 100644 --- a/py/objarray.h +++ b/py/objarray.h @@ -59,4 +59,9 @@ static inline void mp_obj_memoryview_init(mp_obj_array_t *self, size_t typecode, } #endif +#if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY +MP_DECLARE_CONST_FUN_OBJ_2(mp_obj_array_append_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_obj_array_extend_obj); +#endif + #endif // MICROPY_INCLUDED_PY_OBJARRAY_H diff --git a/py/objstr.c b/py/objstr.c index f15a2d974458..162229c62b2b 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -41,6 +41,26 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); +STATIC void str_check_arg_type(const mp_obj_type_t *self_type, const mp_obj_t arg) { + // String operations generally need the args type to match the object they're called on, + // e.g. str.find(str), byte.startswith(byte) + // with the exception that bytes may be used for bytearray and vice versa. + const mp_obj_type_t *arg_type = mp_obj_get_type(arg); + + #if MICROPY_PY_BUILTINS_BYTEARRAY + if (arg_type == &mp_type_bytearray) { + arg_type = &mp_type_bytes; + } + if (self_type == &mp_type_bytearray) { + self_type = &mp_type_bytes; + } + #endif + + if (arg_type != self_type) { + bad_implicit_conversion(arg); + } +} + /******************************************************************************/ /* str */ @@ -452,6 +472,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { mp_check_self(mp_obj_is_str_or_bytes(self_in)); const mp_obj_type_t *self_type = mp_obj_get_type(self_in); + const mp_obj_type_t *ret_type = self_type; // get separation string GET_STR_DATA_LEN(self_in, sep_str, sep_len); @@ -469,8 +490,19 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { // count required length size_t required_len = 0; + #if MICROPY_PY_BUILTINS_BYTEARRAY + if (self_type == &mp_type_bytearray) { + self_type = &mp_type_bytes; + } + #endif for (size_t i = 0; i < seq_len; i++) { - if (mp_obj_get_type(seq_items[i]) != self_type) { + const mp_obj_type_t *seq_type = mp_obj_get_type(seq_items[i]); + #if MICROPY_PY_BUILTINS_BYTEARRAY + if (seq_type == &mp_type_bytearray) { + seq_type = &mp_type_bytes; + } + #endif + if (seq_type != self_type) { mp_raise_TypeError( MP_ERROR_TEXT("join expects a list of str/bytes objects consistent with self object")); } @@ -496,7 +528,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { } // return joined string - return mp_obj_new_str_from_vstr(self_type, &vstr); + return mp_obj_new_str_from_vstr(ret_type, &vstr); } MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join); @@ -545,9 +577,7 @@ mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) { } else { // sep given - if (mp_obj_get_type(sep) != self_type) { - bad_implicit_conversion(sep); - } + str_check_arg_type(self_type, sep); size_t sep_len; const char *sep_str = mp_obj_str_get_data(sep, &sep_len); @@ -699,9 +729,7 @@ STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, b mp_check_self(mp_obj_is_str_or_bytes(args[0])); // check argument type - if (mp_obj_get_type(args[1]) != self_type) { - bad_implicit_conversion(args[1]); - } + str_check_arg_type(self_type, args[1]); GET_STR_DATA_LEN(args[0], haystack, haystack_len); GET_STR_DATA_LEN(args[1], needle, needle_len); @@ -805,9 +833,7 @@ STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { chars_to_del = whitespace; chars_to_del_len = sizeof(whitespace) - 1; } else { - if (mp_obj_get_type(args[1]) != self_type) { - bad_implicit_conversion(args[1]); - } + str_check_arg_type(self_type, args[1]); GET_STR_DATA_LEN(args[1], s, l); chars_to_del = s; chars_to_del_len = l; @@ -1633,13 +1659,8 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); - if (mp_obj_get_type(args[1]) != self_type) { - bad_implicit_conversion(args[1]); - } - - if (mp_obj_get_type(args[2]) != self_type) { - bad_implicit_conversion(args[2]); - } + str_check_arg_type(self_type, args[1]); + str_check_arg_type(self_type, args[2]); // extract string data @@ -1726,9 +1747,7 @@ STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { mp_check_self(mp_obj_is_str_or_bytes(args[0])); // check argument type - if (mp_obj_get_type(args[1]) != self_type) { - bad_implicit_conversion(args[1]); - } + str_check_arg_type(self_type, args[1]); GET_STR_DATA_LEN(args[0], haystack, haystack_len); GET_STR_DATA_LEN(args[1], needle, needle_len); @@ -1767,9 +1786,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { mp_check_self(mp_obj_is_str_or_bytes(self_in)); const mp_obj_type_t *self_type = mp_obj_get_type(self_in); - if (self_type != mp_obj_get_type(arg)) { - bad_implicit_conversion(arg); - } + str_check_arg_type(self_type, arg); GET_STR_DATA_LEN(self_in, str, str_len); GET_STR_DATA_LEN(arg, sep, sep_len); @@ -1795,6 +1812,12 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { result[2] = self_in; } + #if MICROPY_PY_BUILTINS_BYTEARRAY + if (mp_obj_get_type(arg) != self_type) { + arg = mp_obj_new_str_of_type(self_type, sep, sep_len); + } + #endif + const byte *position_ptr = find_subbytes(str, str_len, sep, sep_len, direction); if (position_ptr != NULL) { size_t position = position_ptr - str; @@ -1940,17 +1963,15 @@ mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_u } } -STATIC const mp_rom_map_elem_t str8_locals_dict_table[] = { +// This locals table is used for the following types: str, bytes, bytearray, array.array. +// Each type takes a different section (start to end offset) of this table. +STATIC const mp_rom_map_elem_t array_bytearray_str_bytes_locals_table[] = { + #if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY + { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&mp_obj_array_append_obj) }, + { MP_ROM_QSTR(MP_QSTR_extend), MP_ROM_PTR(&mp_obj_array_extend_obj) }, + #endif #if MICROPY_CPYTHON_COMPAT { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&bytes_decode_obj) }, - #if !MICROPY_PY_BUILTINS_STR_UNICODE - // If we have separate unicode type, then here we have methods only - // for bytes type, and it should not have encode() methods. Otherwise, - // we have non-compliant-but-practical bytestring type, which shares - // method table with bytes, so they both have encode() and decode() - // methods (which should do type checking at runtime). - { MP_ROM_QSTR(MP_QSTR_encode), MP_ROM_PTR(&str_encode_obj) }, - #endif #endif { MP_ROM_QSTR(MP_QSTR_find), MP_ROM_PTR(&str_find_obj) }, { MP_ROM_QSTR(MP_QSTR_rfind), MP_ROM_PTR(&str_rfind_obj) }, @@ -1986,9 +2007,46 @@ STATIC const mp_rom_map_elem_t str8_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_isdigit), MP_ROM_PTR(&str_isdigit_obj) }, { MP_ROM_QSTR(MP_QSTR_isupper), MP_ROM_PTR(&str_isupper_obj) }, { MP_ROM_QSTR(MP_QSTR_islower), MP_ROM_PTR(&str_islower_obj) }, + #if MICROPY_CPYTHON_COMPAT + { MP_ROM_QSTR(MP_QSTR_encode), MP_ROM_PTR(&str_encode_obj) }, + #endif }; -STATIC MP_DEFINE_CONST_DICT(str8_locals_dict, str8_locals_dict_table); +#if MICROPY_CPYTHON_COMPAT +#define TABLE_ENTRIES_COMPAT 1 +#else +#define TABLE_ENTRIES_COMPAT 0 +#endif + +#if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY +#define TABLE_ENTRIES_ARRAY 2 +#else +#define TABLE_ENTRIES_ARRAY 0 +#endif + +MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_str_locals_dict, + array_bytearray_str_bytes_locals_table + TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_COMPAT, + MP_ARRAY_SIZE(array_bytearray_str_bytes_locals_table) - (TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_COMPAT)); + +#if TABLE_ENTRIES_COMPAT == 0 +#define mp_obj_bytes_locals_dict mp_obj_str_locals_dict +#else +MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_bytes_locals_dict, + array_bytearray_str_bytes_locals_table + TABLE_ENTRIES_ARRAY, + MP_ARRAY_SIZE(array_bytearray_str_bytes_locals_table) - (TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_COMPAT)); +#endif + +#if MICROPY_PY_BUILTINS_BYTEARRAY +MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_bytearray_locals_dict, + array_bytearray_str_bytes_locals_table, + MP_ARRAY_SIZE(array_bytearray_str_bytes_locals_table) - TABLE_ENTRIES_COMPAT); +#endif + +#if MICROPY_PY_ARRAY +MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_array_locals_dict, + array_bytearray_str_bytes_locals_table, + TABLE_ENTRIES_ARRAY); +#endif #if !MICROPY_PY_BUILTINS_STR_UNICODE STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); @@ -2002,9 +2060,9 @@ const mp_obj_type_t mp_type_str = { .subscr = bytes_subscr, .getiter = mp_obj_new_str_iterator, .buffer_p = { .get_buffer = mp_obj_str_get_buffer }, - .locals_dict = (mp_obj_dict_t *)&str8_locals_dict, + .locals_dict = (mp_obj_dict_t *)&mp_obj_str_locals_dict, }; -#endif +#endif // !MICROPY_PY_BUILTINS_STR_UNICODE // Reuses most of methods from str const mp_obj_type_t mp_type_bytes = { @@ -2016,7 +2074,7 @@ const mp_obj_type_t mp_type_bytes = { .subscr = bytes_subscr, .getiter = mp_obj_new_bytes_iterator, .buffer_p = { .get_buffer = mp_obj_str_get_buffer }, - .locals_dict = (mp_obj_dict_t *)&str8_locals_dict, + .locals_dict = (mp_obj_dict_t *)&mp_obj_bytes_locals_dict, }; // The zero-length bytes object, with data that includes a null-terminating byte @@ -2044,6 +2102,10 @@ mp_obj_t mp_obj_new_str_copy(const mp_obj_type_t *type, const byte *data, size_t mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte *data, size_t len) { if (type == &mp_type_str) { return mp_obj_new_str((const char *)data, len); + #if MICROPY_PY_BUILTINS_BYTEARRAY + } else if (type == &mp_type_bytearray) { + return mp_obj_new_bytearray(len, data); + #endif } else { return mp_obj_new_bytes(data, len); } @@ -2068,18 +2130,24 @@ mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) { } } - // make a new str/bytes object - mp_obj_str_t *o = mp_obj_malloc(mp_obj_str_t, type); - o->len = vstr->len; - o->hash = qstr_compute_hash((byte *)vstr->buf, vstr->len); + byte *data; if (vstr->len + 1 == vstr->alloc) { - o->data = (byte *)vstr->buf; + data = (byte *)vstr->buf; } else { - o->data = (byte *)m_renew(char, vstr->buf, vstr->alloc, vstr->len + 1); + data = (byte *)m_renew(char, vstr->buf, vstr->alloc, vstr->len + 1); } - ((byte *)o->data)[o->len] = '\0'; // add null byte + data[vstr->len] = '\0'; // add null byte vstr->buf = NULL; vstr->alloc = 0; + #if MICROPY_PY_BUILTINS_BYTEARRAY + if (type == &mp_type_bytearray) { + return mp_obj_new_bytearray_by_ref(vstr->len, data); + } + #endif + mp_obj_str_t *o = mp_obj_malloc(mp_obj_str_t, type); + o->len = vstr->len; + o->hash = qstr_compute_hash(data, vstr->len); + o->data = data; return MP_OBJ_FROM_PTR(o); } @@ -2179,6 +2247,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len) { if (mp_obj_is_qstr(self_in)) { return qstr_data(MP_OBJ_QSTR_VALUE(self_in), len); } else { + MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE; *len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(self_in))->len; return ((mp_obj_str_t *)MP_OBJ_TO_PTR(self_in))->data; } diff --git a/py/objstr.h b/py/objstr.h index 92b065d869b4..7d86ec30baab 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -27,6 +27,7 @@ #define MICROPY_INCLUDED_PY_OBJSTR_H #include "py/obj.h" +#include "py/objarray.h" typedef struct _mp_obj_str_t { mp_obj_base_t base; @@ -36,6 +37,13 @@ typedef struct _mp_obj_str_t { const byte *data; } mp_obj_str_t; +// This static assert is used to ensure that mp_obj_str_t and mp_obj_array_t are compatible, +// meaning that their len and data/items entries are at the same offsets in the struct. +// This allows the same code to be used for str/bytes and bytearray. +#define MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE \ + MP_STATIC_ASSERT(offsetof(mp_obj_str_t, len) == offsetof(mp_obj_array_t, len) \ + && offsetof(mp_obj_str_t, data) == offsetof(mp_obj_array_t, items)) + #define MP_DEFINE_STR_OBJ(obj_name, str) mp_obj_str_t obj_name = {{&mp_type_str}, 0, sizeof(str) - 1, (const byte *)str} // use this macro to extract the string hash @@ -70,6 +78,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len); if (mp_obj_is_qstr(str_obj_in)) { \ str_data = qstr_data(MP_OBJ_QSTR_VALUE(str_obj_in), &str_len); \ } else { \ + MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE; \ str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; \ str_data = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->data; \ } @@ -118,4 +127,14 @@ MP_DECLARE_CONST_FUN_OBJ_1(str_isupper_obj); MP_DECLARE_CONST_FUN_OBJ_1(str_islower_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj); +extern const mp_obj_dict_t mp_obj_str_locals_dict; + +#if MICROPY_PY_BUILTINS_BYTEARRAY +extern const mp_obj_dict_t mp_obj_bytearray_locals_dict; +#endif + +#if MICROPY_PY_ARRAY +extern const mp_obj_dict_t mp_obj_array_locals_dict; +#endif + #endif // MICROPY_INCLUDED_PY_OBJSTR_H diff --git a/py/objstrunicode.c b/py/objstrunicode.c index ed79ad68a93c..d36dd8b1375a 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -116,7 +116,11 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s mp_obj_t index, bool is_slice) { // All str functions also handle bytes objects, and they call str_index_to_ptr(), // so it must handle bytes. - if (type == &mp_type_bytes) { + if (type == &mp_type_bytes + #if MICROPY_PY_BUILTINS_BYTEARRAY + || type == &mp_type_bytearray + #endif + ) { // Taken from objstr.c:str_index_to_ptr() size_t index_val = mp_get_index(type, self_len, index, is_slice); return self_data + index_val; @@ -225,48 +229,6 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } } -STATIC const mp_rom_map_elem_t struni_locals_dict_table[] = { - #if MICROPY_CPYTHON_COMPAT - { MP_ROM_QSTR(MP_QSTR_encode), MP_ROM_PTR(&str_encode_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_find), MP_ROM_PTR(&str_find_obj) }, - { MP_ROM_QSTR(MP_QSTR_rfind), MP_ROM_PTR(&str_rfind_obj) }, - { MP_ROM_QSTR(MP_QSTR_index), MP_ROM_PTR(&str_index_obj) }, - { MP_ROM_QSTR(MP_QSTR_rindex), MP_ROM_PTR(&str_rindex_obj) }, - { MP_ROM_QSTR(MP_QSTR_join), MP_ROM_PTR(&str_join_obj) }, - { MP_ROM_QSTR(MP_QSTR_split), MP_ROM_PTR(&str_split_obj) }, - #if MICROPY_PY_BUILTINS_STR_SPLITLINES - { MP_ROM_QSTR(MP_QSTR_splitlines), MP_ROM_PTR(&str_splitlines_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_rsplit), MP_ROM_PTR(&str_rsplit_obj) }, - { MP_ROM_QSTR(MP_QSTR_startswith), MP_ROM_PTR(&str_startswith_obj) }, - { MP_ROM_QSTR(MP_QSTR_endswith), MP_ROM_PTR(&str_endswith_obj) }, - { MP_ROM_QSTR(MP_QSTR_strip), MP_ROM_PTR(&str_strip_obj) }, - { MP_ROM_QSTR(MP_QSTR_lstrip), MP_ROM_PTR(&str_lstrip_obj) }, - { MP_ROM_QSTR(MP_QSTR_rstrip), MP_ROM_PTR(&str_rstrip_obj) }, - { MP_ROM_QSTR(MP_QSTR_format), MP_ROM_PTR(&str_format_obj) }, - { MP_ROM_QSTR(MP_QSTR_replace), MP_ROM_PTR(&str_replace_obj) }, - #if MICROPY_PY_BUILTINS_STR_COUNT - { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&str_count_obj) }, - #endif - #if MICROPY_PY_BUILTINS_STR_PARTITION - { MP_ROM_QSTR(MP_QSTR_partition), MP_ROM_PTR(&str_partition_obj) }, - { MP_ROM_QSTR(MP_QSTR_rpartition), MP_ROM_PTR(&str_rpartition_obj) }, - #endif - #if MICROPY_PY_BUILTINS_STR_CENTER - { MP_ROM_QSTR(MP_QSTR_center), MP_ROM_PTR(&str_center_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_lower), MP_ROM_PTR(&str_lower_obj) }, - { MP_ROM_QSTR(MP_QSTR_upper), MP_ROM_PTR(&str_upper_obj) }, - { MP_ROM_QSTR(MP_QSTR_isspace), MP_ROM_PTR(&str_isspace_obj) }, - { MP_ROM_QSTR(MP_QSTR_isalpha), MP_ROM_PTR(&str_isalpha_obj) }, - { MP_ROM_QSTR(MP_QSTR_isdigit), MP_ROM_PTR(&str_isdigit_obj) }, - { MP_ROM_QSTR(MP_QSTR_isupper), MP_ROM_PTR(&str_isupper_obj) }, - { MP_ROM_QSTR(MP_QSTR_islower), MP_ROM_PTR(&str_islower_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(struni_locals_dict, struni_locals_dict_table); - const mp_obj_type_t mp_type_str = { { &mp_type_type }, .name = MP_QSTR_str, @@ -277,7 +239,7 @@ const mp_obj_type_t mp_type_str = { .subscr = str_subscr, .getiter = mp_obj_new_str_iterator, .buffer_p = { .get_buffer = mp_obj_str_get_buffer }, - .locals_dict = (mp_obj_dict_t *)&struni_locals_dict, + .locals_dict = (mp_obj_dict_t *)&mp_obj_str_locals_dict, }; /******************************************************************************/ diff --git a/tests/basics/bytearray_byte_operations.py b/tests/basics/bytearray_byte_operations.py new file mode 100644 index 000000000000..7ce53cac535a --- /dev/null +++ b/tests/basics/bytearray_byte_operations.py @@ -0,0 +1,35 @@ +# test bytearray with its re-use of byte functions + +print(bytearray(b"hello world").find(b"ll")) +print(bytearray(b"hello\x00world").rfind(b"l")) + +print(bytearray(b"abc efg ").strip(b"g a")) +print(bytearray(b" spacious ").lstrip()) +print(bytearray(b"www.example.com").lstrip(b"cmowz.")) +print(bytearray(b" spacious ").rstrip()) +print(bytearray(b"mississippi").rstrip(b"ipz")) + +print(bytearray(b"abc").split(b"a")) +print(bytearray(b"abcabc").rsplit(b"bc")) + +print(bytearray(b"asdfasdf").replace(b"a", b"b")) + +print("00\x0000".index("0", 0)) +print("00\x0000".index("0", 3)) +print("00\x0000".rindex("0", 0)) +print("00\x0000".rindex("0", 3)) + +print(bytearray(b"foobar").endswith(b"bar")) +print(bytearray(b"1foo").startswith(b"foo", 1)) + +print(bytearray(b" T E \x00 S T").lower()) +print(bytearray(b" te \x00 st").upper()) + +print(bytearray(b" \t\n\r\v\f").isspace()) +print(bytearray(b"this ").isalpha()) +print(bytearray(b"0123456789").isdigit()) +print(bytearray(b"AB").isupper()) +print(bytearray(b"cheese-cake").islower()) + +print(bytearray(b",").join((bytearray(b"abc"), bytearray(b"def")))) +print(type(bytearray(b",").join((b"a", b"b", b"c")))) diff --git a/tests/basics/bytearray_center.py b/tests/basics/bytearray_center.py new file mode 100644 index 000000000000..c262a8c2097b --- /dev/null +++ b/tests/basics/bytearray_center.py @@ -0,0 +1,8 @@ +try: + bytearray.center +except AttributeError: + print("SKIP") + raise SystemExit + +print(bytearray(b"foo").center(6)) +print(type(bytearray(b"foo").center(6))) diff --git a/tests/basics/bytearray_count.py b/tests/basics/bytearray_count.py new file mode 100644 index 000000000000..a151c1e8183c --- /dev/null +++ b/tests/basics/bytearray_count.py @@ -0,0 +1,7 @@ +try: + bytearray.count +except AttributeError: + print("SKIP") + raise SystemExit + +print(bytearray(b"aaaa").count(b"a")) diff --git a/tests/basics/bytearray_partition.py b/tests/basics/bytearray_partition.py new file mode 100644 index 000000000000..b48ec4ed9b9f --- /dev/null +++ b/tests/basics/bytearray_partition.py @@ -0,0 +1,8 @@ +try: + bytearray.partition +except AttributeError: + print("SKIP") + raise SystemExit + +print(bytearray(b"asdsf").partition(b"s")) +print(bytearray(b"asdsf").rpartition(b"s")) diff --git a/tests/basics/bytes_center.py b/tests/basics/bytes_center.py new file mode 100644 index 000000000000..5d8b41d92ff2 --- /dev/null +++ b/tests/basics/bytes_center.py @@ -0,0 +1,13 @@ +try: + bytes.center +except: + print("SKIP") + raise SystemExit + +print(b"foo".center(0)) +print(b"foo".center(1)) +print(b"foo".center(3)) +print(b"foo".center(4)) +print(b"foo".center(5)) +print(b"foo".center(6)) +print(b"foo".center(20)) From 787bd9991903dc736b5eb79826dd34e4c17f72ec Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 11 Aug 2022 21:43:09 +1000 Subject: [PATCH 1598/4290] nrf/modules/ubluepy: Use mp_obj_str_get_data to extract str data. Instead of GET_STR_DATA_LEN, which is intended to be a private macro. Signed-off-by: Damien George --- ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 8 ++++---- ports/nrf/modules/ubluepy/ubluepy_uuid.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 05a72b1de63d..acfe316c0cf7 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -193,9 +193,8 @@ STATIC mp_obj_t peripheral_advertise(mp_uint_t n_args, const mp_obj_t *pos_args, memset(&adv_data, 0, sizeof(ubluepy_advertise_data_t)); if (device_name_obj != mp_const_none && mp_obj_is_str(device_name_obj)) { - GET_STR_DATA_LEN(device_name_obj, str_data, str_len); - - adv_data.p_device_name = (uint8_t *)str_data; + size_t str_len; + adv_data.p_device_name = (uint8_t *)mp_obj_str_get_data(device_name_obj, &str_len); adv_data.device_name_len = str_len; } @@ -357,7 +356,8 @@ STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, m ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler); if (mp_obj_is_str(dev_addr)) { - GET_STR_DATA_LEN(dev_addr, str_data, str_len); + size_t str_len; + const byte *str_data = (const byte *)mp_obj_str_get_data(dev_addr, &str_len); if (str_len == 17) { // Example "11:22:33:aa:bb:cc" uint8_t * p_addr = m_new(uint8_t, 6); diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c index 594d0d9130c3..aee7b9a1a899 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c +++ b/ports/nrf/modules/ubluepy/ubluepy_uuid.c @@ -70,7 +70,8 @@ STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args, s->value[1] = (((uint16_t)mp_obj_get_int(uuid_obj)) >> 8) & 0xFF; s->value[0] = ((uint8_t)mp_obj_get_int(uuid_obj)) & 0xFF; } else if (mp_obj_is_str(uuid_obj)) { - GET_STR_DATA_LEN(uuid_obj, str_data, str_len); + size_t str_len; + const byte *str_data = (const byte *)mp_obj_str_get_data(uuid_obj, &str_len); if (str_len == 6) { // Assume hex digit prefixed with 0x s->type = UBLUEPY_UUID_16_BIT; s->value[0] = unichar_xdigit_value(str_data[5]); From 6c67fbc280625c59fff7cdf93f16d5e2ad0bad8a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 11 Aug 2022 21:44:53 +1000 Subject: [PATCH 1599/4290] zephyr/machine_uart: Use mp_obj_str_get_str to get device name. This checks that the argument is actually a string. Signed-off-by: Damien George --- ports/zephyr/machine_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c index 47ca0945a5e6..3520795c5aad 100644 --- a/ports/zephyr/machine_uart.c +++ b/ports/zephyr/machine_uart.c @@ -75,10 +75,9 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - GET_STR_DATA_LEN(args[0], name, name_len); machine_uart_obj_t *self = mp_obj_malloc(machine_uart_obj_t, &machine_uart_type); - self->dev = device_get_binding(name); + self->dev = device_get_binding(mp_obj_str_get_str(args[0])); if (!self->dev) { mp_raise_ValueError(MP_ERROR_TEXT("Bad device name")); } From 28aaab95909aab092cc8c16188fec157142f18a9 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 13 Jul 2021 18:01:12 +1000 Subject: [PATCH 1600/4290] py/objstr: Add hex/fromhex to bytes/memoryview/bytearray. These were added in Python 3.5. Enabled via MICROPY_PY_BUILTINS_BYTES_HEX, and enabled by default for all ports that currently have ubinascii. Rework ubinascii to use the implementation of these methods. Signed-off-by: Jim Mussared --- extmod/modubinascii.c | 81 +++++---------------------- ports/cc3200/mpconfigport.h | 1 + ports/javascript/mpconfigport.h | 1 + ports/mimxrt/mpconfigport.h | 1 + ports/qemu-arm/mpconfigport.h | 1 + ports/samd/mpconfigport.h | 1 + ports/unix/mpconfigport.h | 1 + ports/windows/mpconfigport.h | 1 + ports/zephyr/mpconfigport.h | 1 + py/mpconfig.h | 5 ++ py/objarray.c | 9 +++ py/objstr.c | 98 ++++++++++++++++++++++++++++++++- py/objstr.h | 7 +++ 13 files changed, 138 insertions(+), 70 deletions(-) diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index c0e2c587fdd9..49c8d1fb971e 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -30,78 +30,21 @@ #include "py/runtime.h" #include "py/binary.h" +#include "py/objstr.h" #if MICROPY_PY_UBINASCII -STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) { - // First argument is the data to convert. - // Second argument is an optional separator to be used between values. - const char *sep = NULL; - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); - - // Code below assumes non-zero buffer length when computing size with - // separator, so handle the zero-length case here. - if (bufinfo.len == 0) { - return mp_const_empty_bytes; - } - - vstr_t vstr; - size_t out_len = bufinfo.len * 2; - if (n_args > 1) { - // 1-char separator between hex numbers - out_len += bufinfo.len - 1; - sep = mp_obj_str_get_str(args[1]); - } - vstr_init_len(&vstr, out_len); - byte *in = bufinfo.buf, *out = (byte *)vstr.buf; - for (mp_uint_t i = bufinfo.len; i--;) { - byte d = (*in >> 4); - if (d > 9) { - d += 'a' - '9' - 1; - } - *out++ = d + '0'; - d = (*in++ & 0xf); - if (d > 9) { - d += 'a' - '9' - 1; - } - *out++ = d + '0'; - if (sep != NULL && i != 0) { - *out++ = *sep; - } - } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +#if MICROPY_PY_BUILTINS_BYTES_HEX +STATIC mp_obj_t bytes_hex_as_bytes(size_t n_args, const mp_obj_t *args) { + return mp_obj_bytes_hex(n_args, args, &mp_type_bytes); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj, 1, 2, mod_binascii_hexlify); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_hex_as_bytes_obj, 1, 2, bytes_hex_as_bytes); -STATIC mp_obj_t mod_binascii_unhexlify(mp_obj_t data) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); - - if ((bufinfo.len & 1) != 0) { - mp_raise_ValueError(MP_ERROR_TEXT("odd-length string")); - } - vstr_t vstr; - vstr_init_len(&vstr, bufinfo.len / 2); - byte *in = bufinfo.buf, *out = (byte *)vstr.buf; - byte hex_byte = 0; - for (mp_uint_t i = bufinfo.len; i--;) { - byte hex_ch = *in++; - if (unichar_isxdigit(hex_ch)) { - hex_byte += unichar_xdigit_value(hex_ch); - } else { - mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit found")); - } - if (i & 1) { - hex_byte <<= 4; - } else { - *out++ = hex_byte; - hex_byte = 0; - } - } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +STATIC mp_obj_t bytes_fromhex_bytes(mp_obj_t data) { + return mp_obj_bytes_fromhex(MP_OBJ_FROM_PTR(&mp_type_bytes), data); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_unhexlify_obj, mod_binascii_unhexlify); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bytes_fromhex_obj, bytes_fromhex_bytes); +#endif // If ch is a character in the base64 alphabet, and is not a pad character, then // the corresponding integer between 0 and 63, inclusively, is returned. @@ -242,8 +185,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_bin STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubinascii) }, - { MP_ROM_QSTR(MP_QSTR_hexlify), MP_ROM_PTR(&mod_binascii_hexlify_obj) }, - { MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&mod_binascii_unhexlify_obj) }, + #if MICROPY_PY_BUILTINS_BYTES_HEX + { MP_ROM_QSTR(MP_QSTR_hexlify), MP_ROM_PTR(&bytes_hex_as_bytes_obj) }, + { MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&bytes_fromhex_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_a2b_base64), MP_ROM_PTR(&mod_binascii_a2b_base64_obj) }, { MP_ROM_QSTR(MP_QSTR_b2a_base64), MP_ROM_PTR(&mod_binascii_b2a_base64_obj) }, #if MICROPY_PY_UBINASCII_CRC32 diff --git a/ports/cc3200/mpconfigport.h b/ports/cc3200/mpconfigport.h index e81a2fc29bb3..f41c1fe99dbf 100644 --- a/ports/cc3200/mpconfigport.h +++ b/ports/cc3200/mpconfigport.h @@ -78,6 +78,7 @@ #define MICROPY_VFS_FAT (1) #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_TEXT cc3200_help_text diff --git a/ports/javascript/mpconfigport.h b/ports/javascript/mpconfigport.h index 01a61e391d00..6c86d816bd4f 100644 --- a/ports/javascript/mpconfigport.h +++ b/ports/javascript/mpconfigport.h @@ -89,6 +89,7 @@ #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_BUILTINS_STR_CENTER (1) #define MICROPY_PY_BUILTINS_STR_PARTITION (1) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 00714ca8d056..54d649795df0 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -74,6 +74,7 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_DELATTR_SETATTR (1) #define MICROPY_PY_FSTRINGS (1) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_BUILTINS_STR_CENTER (1) #define MICROPY_PY_BUILTINS_STR_PARTITION (1) diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index 8809d17154fd..972dce61b498 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -28,6 +28,7 @@ #define MICROPY_PY_ALL_SPECIAL_METHODS (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_FROZENSET (1) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) #define MICROPY_PY_BUILTINS_POW3 (1) diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 24b9cbfe1943..c02d9316ded3 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -56,6 +56,7 @@ #define MICROPY_MODULE_WEAK_LINKS (1) // Control over Python builtins #define MICROPY_PY_ASYNC_AWAIT (0) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_STR_COUNT (0) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) #define MICROPY_PY_BUILTINS_SET (0) diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index ed4c71097ff1..5545a74f57cc 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -61,6 +61,7 @@ #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_DELATTR_SETATTR (1) #define MICROPY_PY_FSTRINGS (1) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_BUILTINS_STR_CENTER (1) #define MICROPY_PY_BUILTINS_STR_PARTITION (1) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 5f8ad983adc4..4ed9f316e7bb 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -84,6 +84,7 @@ #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_DELATTR_SETATTR (1) #define MICROPY_PY_FSTRINGS (1) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_BUILTINS_STR_CENTER (1) #define MICROPY_PY_BUILTINS_STR_PARTITION (1) diff --git a/ports/zephyr/mpconfigport.h b/ports/zephyr/mpconfigport.h index 586b0ec91697..4c8096b44107 100644 --- a/ports/zephyr/mpconfigport.h +++ b/ports/zephyr/mpconfigport.h @@ -45,6 +45,7 @@ #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_ATTRTUPLE (0) +#define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_ENUMERATE (0) #define MICROPY_PY_BUILTINS_FILTER (0) #define MICROPY_PY_BUILTINS_MIN_MAX (0) diff --git a/py/mpconfig.h b/py/mpconfig.h index 25f37ff8b3a2..1ed34bb6fdae 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -987,6 +987,11 @@ typedef double mp_float_t; #define MICROPY_PY_STR_BYTES_CMP_WARN (0) #endif +// Add bytes.hex and bytes.fromhex +#ifndef MICROPY_PY_BUILTINS_BYTES_HEX +#define MICROPY_PY_BUILTINS_BYTES_HEX (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether str object is proper unicode #ifndef MICROPY_PY_BUILTINS_STR_UNICODE #define MICROPY_PY_BUILTINS_STR_UNICODE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) diff --git a/py/objarray.c b/py/objarray.c index 11bd7bb15c41..ecaffeb6a22e 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -245,6 +245,12 @@ STATIC void memoryview_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); dest[0] = MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->typecode & TYPECODE_MASK, NULL)); } + #if MICROPY_PY_BUILTINS_BYTES_HEX + else { + // Need to forward to locals dict. + dest[1] = MP_OBJ_SENTINEL; + } + #endif } #endif @@ -607,6 +613,9 @@ const mp_obj_type_t mp_type_memoryview = { #if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE .attr = memoryview_attr, #endif + #if MICROPY_PY_BUILTINS_BYTES_HEX + .locals_dict = (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, + #endif .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, }; diff --git a/py/objstr.c b/py/objstr.c index 162229c62b2b..45dbb9b3ebde 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -1950,6 +1950,84 @@ STATIC mp_obj_t str_encode(size_t n_args, const mp_obj_t *args) { MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode); #endif +#if MICROPY_PY_BUILTINS_BYTES_HEX +mp_obj_t mp_obj_bytes_hex(size_t n_args, const mp_obj_t *args, const mp_obj_type_t *type) { + // First argument is the data to convert. + // Second argument is an optional separator to be used between values. + const char *sep = NULL; + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); + + // Code below assumes non-zero buffer length when computing size with + // separator, so handle the zero-length case here. + if (bufinfo.len == 0) { + return mp_const_empty_bytes; + } + + vstr_t vstr; + size_t out_len = bufinfo.len * 2; + if (n_args > 1) { + // 1-char separator between hex numbers + out_len += bufinfo.len - 1; + sep = mp_obj_str_get_str(args[1]); + } + vstr_init_len(&vstr, out_len); + byte *in = bufinfo.buf, *out = (byte *)vstr.buf; + for (mp_uint_t i = bufinfo.len; i--;) { + byte d = (*in >> 4); + if (d > 9) { + d += 'a' - '9' - 1; + } + *out++ = d + '0'; + d = (*in++ & 0xf); + if (d > 9) { + d += 'a' - '9' - 1; + } + *out++ = d + '0'; + if (sep != NULL && i != 0) { + *out++ = *sep; + } + } + return mp_obj_new_str_from_vstr(type, &vstr); +} + +mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); + + if ((bufinfo.len & 1) != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("odd-length string")); + } + vstr_t vstr; + vstr_init_len(&vstr, bufinfo.len / 2); + byte *in = bufinfo.buf, *out = (byte *)vstr.buf; + byte hex_byte = 0; + for (mp_uint_t i = bufinfo.len; i--;) { + byte hex_ch = *in++; + if (unichar_isxdigit(hex_ch)) { + hex_byte += unichar_xdigit_value(hex_ch); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit found")); + } + if (i & 1) { + hex_byte <<= 4; + } else { + *out++ = hex_byte; + hex_byte = 0; + } + } + return mp_obj_new_str_from_vstr(MP_OBJ_TO_PTR(type_in), &vstr); +} + +STATIC mp_obj_t bytes_hex_as_str(size_t n_args, const mp_obj_t *args) { + return mp_obj_bytes_hex(n_args, args, &mp_type_str); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_hex_as_str_obj, 1, 2, bytes_hex_as_str); + +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bytes_fromhex_obj, mp_obj_bytes_fromhex); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bytes_fromhex_classmethod_obj, MP_ROM_PTR(&bytes_fromhex_obj)); +#endif // MICROPY_PY_BUILTINS_BYTES_HEX + mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { if (flags == MP_BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); @@ -1970,6 +2048,10 @@ STATIC const mp_rom_map_elem_t array_bytearray_str_bytes_locals_table[] = { { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&mp_obj_array_append_obj) }, { MP_ROM_QSTR(MP_QSTR_extend), MP_ROM_PTR(&mp_obj_array_extend_obj) }, #endif + #if MICROPY_PY_BUILTINS_BYTES_HEX + { MP_ROM_QSTR(MP_QSTR_hex), MP_ROM_PTR(&bytes_hex_as_str_obj) }, + { MP_ROM_QSTR(MP_QSTR_fromhex), MP_ROM_PTR(&bytes_fromhex_classmethod_obj) }, + #endif #if MICROPY_CPYTHON_COMPAT { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&bytes_decode_obj) }, #endif @@ -2018,6 +2100,12 @@ STATIC const mp_rom_map_elem_t array_bytearray_str_bytes_locals_table[] = { #define TABLE_ENTRIES_COMPAT 0 #endif +#if MICROPY_PY_BUILTINS_BYTES_HEX +#define TABLE_ENTRIES_HEX 2 +#else +#define TABLE_ENTRIES_HEX 0 +#endif + #if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY #define TABLE_ENTRIES_ARRAY 2 #else @@ -2025,8 +2113,8 @@ STATIC const mp_rom_map_elem_t array_bytearray_str_bytes_locals_table[] = { #endif MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_str_locals_dict, - array_bytearray_str_bytes_locals_table + TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_COMPAT, - MP_ARRAY_SIZE(array_bytearray_str_bytes_locals_table) - (TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_COMPAT)); + array_bytearray_str_bytes_locals_table + TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_HEX + TABLE_ENTRIES_COMPAT, + MP_ARRAY_SIZE(array_bytearray_str_bytes_locals_table) - (TABLE_ENTRIES_ARRAY + TABLE_ENTRIES_HEX + TABLE_ENTRIES_COMPAT)); #if TABLE_ENTRIES_COMPAT == 0 #define mp_obj_bytes_locals_dict mp_obj_str_locals_dict @@ -2048,6 +2136,12 @@ MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_array_locals_dict, TABLE_ENTRIES_ARRAY); #endif +#if MICROPY_PY_BUILTINS_MEMORYVIEW && MICROPY_PY_BUILTINS_BYTES_HEX +MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_memoryview_locals_dict, + array_bytearray_str_bytes_locals_table + TABLE_ENTRIES_ARRAY, + 1); // Just the "hex" entry. +#endif + #if !MICROPY_PY_BUILTINS_STR_UNICODE STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); diff --git a/py/objstr.h b/py/objstr.h index 7d86ec30baab..b1217d5872b1 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -127,8 +127,15 @@ MP_DECLARE_CONST_FUN_OBJ_1(str_isupper_obj); MP_DECLARE_CONST_FUN_OBJ_1(str_islower_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj); +mp_obj_t mp_obj_bytes_hex(size_t n_args, const mp_obj_t *args, const mp_obj_type_t *type); +mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data); + extern const mp_obj_dict_t mp_obj_str_locals_dict; +#if MICROPY_PY_BUILTINS_MEMORYVIEW && MICROPY_PY_BUILTINS_BYTES_HEX +extern const mp_obj_dict_t mp_obj_memoryview_locals_dict; +#endif + #if MICROPY_PY_BUILTINS_BYTEARRAY extern const mp_obj_dict_t mp_obj_bytearray_locals_dict; #endif From f694058f2bce7d6e5ef82c8efd2bcb6cdebfe7a8 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 13 Jul 2021 22:49:49 +1000 Subject: [PATCH 1601/4290] tests/extmod/ubinascii: Add tests for bytes.hex etc. Also make the sep test not micropython-specific. Signed-off-by: Jim Mussared --- tests/basics/builtin_str_hex.py | 24 +++++++++++++++++++++++ tests/extmod/ubinascii_hexlify.py | 17 ++++++++++++---- tests/extmod/ubinascii_micropython.py | 15 -------------- tests/extmod/ubinascii_micropython.py.exp | 2 -- tests/extmod/ubinascii_unhexlify.py | 11 +++++++---- 5 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 tests/basics/builtin_str_hex.py delete mode 100644 tests/extmod/ubinascii_micropython.py delete mode 100644 tests/extmod/ubinascii_micropython.py.exp diff --git a/tests/basics/builtin_str_hex.py b/tests/basics/builtin_str_hex.py new file mode 100644 index 000000000000..7390c8eaee17 --- /dev/null +++ b/tests/basics/builtin_str_hex.py @@ -0,0 +1,24 @@ +if not hasattr(bytes, "fromhex"): + print("SKIP") + raise SystemExit + +for x in ( + b"\x00\x01\x02\x03\x04\x05\x06\x07", + b"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + b"\x7f\x80\xff", + b"1234ABCDabcd", +): + print(x.hex()) + print(bytearray(x).hex()) + print(memoryview(x).hex()) + print(x.hex(":")) + print(bytearray(x).hex(":")) + print(memoryview(x).hex(":")) + +for x in ( + "0001020304050607", + "08090a0b0c0d0e0f", + "7f80ff", + "313233344142434461626364", +): + print(bytes.fromhex(x)) diff --git a/tests/extmod/ubinascii_hexlify.py b/tests/extmod/ubinascii_hexlify.py index 2329f53edd94..3c266fb6cc08 100644 --- a/tests/extmod/ubinascii_hexlify.py +++ b/tests/extmod/ubinascii_hexlify.py @@ -7,7 +7,16 @@ print("SKIP") raise SystemExit -print(binascii.hexlify(b"\x00\x01\x02\x03\x04\x05\x06\x07")) -print(binascii.hexlify(b"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f")) -print(binascii.hexlify(b"\x7f\x80\xff")) -print(binascii.hexlify(b"1234ABCDabcd")) +for x in ( + b"\x00\x01\x02\x03\x04\x05\x06\x07", + b"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + b"\x7f\x80\xff", + b"1234ABCDabcd", +): + print(binascii.hexlify(x)) + +# Two-argument version (now supported in CPython) +print(binascii.hexlify(b"123", ":")) + +# zero length buffer +print(binascii.hexlify(b"", b":")) diff --git a/tests/extmod/ubinascii_micropython.py b/tests/extmod/ubinascii_micropython.py deleted file mode 100644 index 94e8daa557b7..000000000000 --- a/tests/extmod/ubinascii_micropython.py +++ /dev/null @@ -1,15 +0,0 @@ -try: - try: - import ubinascii as binascii - except ImportError: - import binascii -except ImportError: - print("SKIP") - raise SystemExit - -# two arguments supported in uPy but not CPython -a = binascii.hexlify(b"123", ":") -print(a) - -# zero length buffer -print(binascii.hexlify(b"", b":")) diff --git a/tests/extmod/ubinascii_micropython.py.exp b/tests/extmod/ubinascii_micropython.py.exp deleted file mode 100644 index a195d2602c19..000000000000 --- a/tests/extmod/ubinascii_micropython.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -b'31:32:33' -b'' diff --git a/tests/extmod/ubinascii_unhexlify.py b/tests/extmod/ubinascii_unhexlify.py index 413eaf1b6fd6..2c3598ab98ec 100644 --- a/tests/extmod/ubinascii_unhexlify.py +++ b/tests/extmod/ubinascii_unhexlify.py @@ -7,10 +7,13 @@ print("SKIP") raise SystemExit -print(binascii.unhexlify(b"0001020304050607")) -print(binascii.unhexlify(b"08090a0b0c0d0e0f")) -print(binascii.unhexlify(b"7f80ff")) -print(binascii.unhexlify(b"313233344142434461626364")) +for x in ( + b"0001020304050607", + b"08090a0b0c0d0e0f", + b"7f80ff", + b"313233344142434461626364", +): + print(binascii.unhexlify(x)) try: a = binascii.unhexlify(b"0") # odd buffer length From ec24cd1d25a322192be93dc54a02ca4564fc9e7b Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 12 Aug 2022 10:12:21 +1000 Subject: [PATCH 1602/4290] mpy-cross,unix: Remove .gitignore file. Now that all build artefacts are placed in a build/ directory the gitignore is no longer needed. Signed-off-by: Damien George --- mpy-cross/.gitignore | 1 - ports/unix/.gitignore | 3 --- 2 files changed, 4 deletions(-) delete mode 100644 mpy-cross/.gitignore delete mode 100644 ports/unix/.gitignore diff --git a/mpy-cross/.gitignore b/mpy-cross/.gitignore deleted file mode 100644 index 82a0a7efaab3..000000000000 --- a/mpy-cross/.gitignore +++ /dev/null @@ -1 +0,0 @@ -mpy-cross diff --git a/ports/unix/.gitignore b/ports/unix/.gitignore deleted file mode 100644 index 3ca8f6cb2746..000000000000 --- a/ports/unix/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -micropython -micropython-* -*.gcov From 945f377b436d3ba6d0ac9962762038133e864604 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 12 Aug 2022 10:15:27 +1000 Subject: [PATCH 1603/4290] py/objstr: Remove str function object declarations from header file. Since f7f56d42851aaff2027e23a8ca45c1f1973f1aca consolidated all uses of these to a single locals dict, they no longer need to be made public. Signed-off-by: Damien George --- py/objstr.h | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/py/objstr.h b/py/objstr.h index b1217d5872b1..78441fedaf2c 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -98,35 +98,6 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s mp_obj_t index, bool is_slice); const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj); -MP_DECLARE_CONST_FUN_OBJ_2(str_join_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj); -MP_DECLARE_CONST_FUN_OBJ_KW(str_splitlines_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_lstrip_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rstrip_obj); -MP_DECLARE_CONST_FUN_OBJ_KW(str_format_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj); -MP_DECLARE_CONST_FUN_OBJ_2(str_partition_obj); -MP_DECLARE_CONST_FUN_OBJ_2(str_rpartition_obj); -MP_DECLARE_CONST_FUN_OBJ_2(str_center_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_lower_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_upper_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_isspace_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_isalpha_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_isdigit_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_isupper_obj); -MP_DECLARE_CONST_FUN_OBJ_1(str_islower_obj); -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj); - mp_obj_t mp_obj_bytes_hex(size_t n_args, const mp_obj_t *args, const mp_obj_type_t *type); mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data); From cf90e24335652462bb7eb4bd105e061683bc316a Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 12 Aug 2022 10:32:20 +1000 Subject: [PATCH 1604/4290] py/mkrules: Use abspath to find directory for mpy-cross dependency. Otherwise if the `mpy-cross/build/` directory doesn't exist then `mpy-cross/build/..` won't work. Signed-off-by: Damien George --- py/mkrules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/mkrules.mk b/py/mkrules.mk index 73c33227c09a..14f1b953cda4 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -162,7 +162,7 @@ $(HEADER_BUILD): ifneq ($(MICROPY_MPYCROSS_DEPENDENCY),) # to automatically build mpy-cross, if needed $(MICROPY_MPYCROSS_DEPENDENCY): - $(MAKE) -C $(dir $@).. + $(MAKE) -C $(abspath $(dir $@)..) endif ifneq ($(FROZEN_DIR),) From 5543b2a9cc7381931431c69d93a77ba5d5d58e2e Mon Sep 17 00:00:00 2001 From: Ned Konz Date: Wed, 1 Sep 2021 10:48:15 -0700 Subject: [PATCH 1605/4290] extmod/uasyncio: Add clear method to ThreadSafeFlag. This is useful in situations where the ThreadSafeFlag is reused and needs to be cleared of any previous, unwanted event. For example, clear the flag at the start of an operation, trigger the operation (eg an I2C write), then (a)wait for an external event to set the flag (eg a pin IRQ). Further events may trigger the flag again but these are unwanted and should be cleared before the next cycle starts. --- docs/library/uasyncio.rst | 7 ++++++- extmod/uasyncio/event.py | 5 ++++- tests/extmod/uasyncio_threadsafeflag.py | 20 ++++++++++++++++++++ tests/extmod/uasyncio_threadsafeflag.py.exp | 11 +++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/docs/library/uasyncio.rst b/docs/library/uasyncio.rst index 0abbf8dd8d7d..859d505d79a9 100644 --- a/docs/library/uasyncio.rst +++ b/docs/library/uasyncio.rst @@ -153,9 +153,14 @@ class ThreadSafeFlag .. method:: ThreadSafeFlag.set() - Set the flag. If there is a task waiting on the event, it will be scheduled + Set the flag. If there is a task waiting on the flag, it will be scheduled to run. +.. method:: ThreadSafeFlag.clear() + + Clear the flag. This may be used to ensure that a possibly previously-set + flag is clear before waiting for it. + .. method:: ThreadSafeFlag.wait() Wait for the flag to be set. If the flag is already set then it returns diff --git a/extmod/uasyncio/event.py b/extmod/uasyncio/event.py index c48904b9835c..654ccefa98e0 100644 --- a/extmod/uasyncio/event.py +++ b/extmod/uasyncio/event.py @@ -36,7 +36,7 @@ async def wait(self): # MicroPython-extension: This can be set from outside the asyncio event loop, # such as other threads, IRQs or scheduler context. Implementation is a stream # that asyncio will poll until a flag is set. -# Note: Unlike Event, this is self-clearing. +# Note: Unlike Event, this is self-clearing after a wait(). try: import uio @@ -52,6 +52,9 @@ def ioctl(self, req, flags): def set(self): self._flag = 1 + def clear(self): + self._flag = 0 + async def wait(self): if not self._flag: yield core._io_queue.queue_read(self) diff --git a/tests/extmod/uasyncio_threadsafeflag.py b/tests/extmod/uasyncio_threadsafeflag.py index 4e002a3d2a0b..a8a08d2e9258 100644 --- a/tests/extmod/uasyncio_threadsafeflag.py +++ b/tests/extmod/uasyncio_threadsafeflag.py @@ -75,5 +75,25 @@ async def main(): print("wait task") await t + # Flag set, cleared, and set again. + print("----") + print("set event") + flag.set() + print("yield") + await asyncio.sleep(0) + print("clear event") + flag.clear() + print("yield") + await asyncio.sleep(0) + t = asyncio.create_task(task(4, flag)) + print("yield") + await asyncio.sleep(0) + print("set event") + flag.set() + print("yield") + await asyncio.sleep(0) + print("wait task") + await t + asyncio.run(main()) diff --git a/tests/extmod/uasyncio_threadsafeflag.py.exp b/tests/extmod/uasyncio_threadsafeflag.py.exp index aef4e479ba44..757115ac4bdd 100644 --- a/tests/extmod/uasyncio_threadsafeflag.py.exp +++ b/tests/extmod/uasyncio_threadsafeflag.py.exp @@ -19,3 +19,14 @@ yield task 3 task 3 done wait task +---- +set event +yield +clear event +yield +yield +task 4 +set event +yield +wait task +task 4 done From 01514e80c9a150f0506bd6c8c43590ca05f8598f Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 12 Aug 2022 17:03:38 +1000 Subject: [PATCH 1606/4290] extmod/uasyncio: Rename internal _flag to state, to save a qstr. Saves about 16 bytes of flash when uasyncio is frozen in. Signed-off-by: Damien George --- extmod/uasyncio/event.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extmod/uasyncio/event.py b/extmod/uasyncio/event.py index 654ccefa98e0..3b5e79d8f23e 100644 --- a/extmod/uasyncio/event.py +++ b/extmod/uasyncio/event.py @@ -42,23 +42,23 @@ async def wait(self): class ThreadSafeFlag(uio.IOBase): def __init__(self): - self._flag = 0 + self.state = 0 def ioctl(self, req, flags): if req == 3: # MP_STREAM_POLL - return self._flag * flags + return self.state * flags return None def set(self): - self._flag = 1 + self.state = 1 def clear(self): - self._flag = 0 + self.state = 0 async def wait(self): - if not self._flag: + if not self.state: yield core._io_queue.queue_read(self) - self._flag = 0 + self.state = 0 except ImportError: pass From 69719927f1752b2d6333708c5b60067fe3b7965d Mon Sep 17 00:00:00 2001 From: MrJake222 Date: Thu, 16 Sep 2021 19:49:42 +0200 Subject: [PATCH 1607/4290] extmod/modlwip: Add support for leaving multicast groups. --- extmod/modlwip.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/extmod/modlwip.c b/extmod/modlwip.c index 25669228dffd..c6ee02132ff2 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -66,6 +66,7 @@ // All socket options should be globally distinct, // because we ignore option levels for efficiency. #define IP_ADD_MEMBERSHIP 0x400 +#define IP_DROP_MEMBERSHIP 0x401 // For compatibilily with older lwIP versions. #ifndef ip_set_option @@ -1376,7 +1377,8 @@ STATIC mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) { } // level: IPPROTO_IP - case IP_ADD_MEMBERSHIP: { + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); if (bufinfo.len != sizeof(ip_addr_t) * 2) { @@ -1384,7 +1386,12 @@ STATIC mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) { } // POSIX setsockopt has order: group addr, if addr, lwIP has it vice-versa - err_t err = igmp_joingroup((ip_addr_t *)bufinfo.buf + 1, bufinfo.buf); + err_t err; + if (opt == IP_ADD_MEMBERSHIP) { + err = igmp_joingroup((ip_addr_t *)bufinfo.buf + 1, bufinfo.buf); + } else { + err = igmp_leavegroup((ip_addr_t *)bufinfo.buf + 1, bufinfo.buf); + } if (err != ERR_OK) { mp_raise_OSError(error_lookup_table[-err]); } @@ -1769,6 +1776,7 @@ STATIC const mp_rom_map_elem_t mp_module_lwip_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(0) }, { MP_ROM_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_ROM_INT(IP_ADD_MEMBERSHIP) }, + { MP_ROM_QSTR(MP_QSTR_IP_DROP_MEMBERSHIP), MP_ROM_INT(IP_DROP_MEMBERSHIP) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table); From 6cd2e4191803e95580bdfc57c06ea818454a25d1 Mon Sep 17 00:00:00 2001 From: Dan Ellis Date: Thu, 28 Jul 2022 23:21:00 -0400 Subject: [PATCH 1608/4290] py/parsenum: Ensure that trailing zeros lead to identical results. Prior to this commit, parsenum would calculate "1e-20" as 1.0*pow(10, -20), and "1.000e-20" as 1000.0*pow(10, -23); in certain cases, this could make seemingly-identical values compare as not equal. This commit watches for trailing zeros as a special case, and ignores them when appropriate, so "1.000e-20" is also calculated as 1.0*pow(10, -20). Fixes issue #5831. --- py/parsenum.c | 70 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/py/parsenum.c b/py/parsenum.c index 5e8e5dfe8c0f..19cc71920140 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -178,31 +178,51 @@ typedef enum { PARSE_DEC_IN_EXP, } parse_dec_in_t; -#if MICROPY_PY_BUILTINS_COMPLEX -mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex) -#else -mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lexer_t *lex) -#endif -{ - #if MICROPY_PY_BUILTINS_FLOAT - +#if MICROPY_PY_BUILTINS_FLOAT // DEC_VAL_MAX only needs to be rough and is used to retain precision while not overflowing // SMALL_NORMAL_VAL is the smallest power of 10 that is still a normal float // EXACT_POWER_OF_10 is the largest value of x so that 10^x can be stored exactly in a float // Note: EXACT_POWER_OF_10 is at least floor(log_5(2^mantissa_length)). Indeed, 10^n = 2^n * 5^n // so we only have to store the 5^n part in the mantissa (the 2^n part will go into the float's // exponent). - #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT #define DEC_VAL_MAX 1e20F #define SMALL_NORMAL_VAL (1e-37F) #define SMALL_NORMAL_EXP (-37) #define EXACT_POWER_OF_10 (9) - #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE #define DEC_VAL_MAX 1e200 #define SMALL_NORMAL_VAL (1e-307) #define SMALL_NORMAL_EXP (-307) #define EXACT_POWER_OF_10 (22) - #endif +#endif + +// Break out inner digit accumulation routine to ease trailing zero deferral. +static void accept_digit(mp_float_t *p_dec_val, int dig, int *p_exp_extra, int in) { + // Core routine to ingest an additional digit. + if (*p_dec_val < DEC_VAL_MAX) { + // dec_val won't overflow so keep accumulating + *p_dec_val = 10 * *p_dec_val + dig; + if (in == PARSE_DEC_IN_FRAC) { + --(*p_exp_extra); + } + } else { + // dec_val might overflow and we anyway can't represent more digits + // of precision, so ignore the digit and just adjust the exponent + if (in == PARSE_DEC_IN_INTG) { + ++(*p_exp_extra); + } + } +} +#endif // MICROPY_BUILTINS_FLOAT + +#if MICROPY_PY_BUILTINS_COMPLEX +mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex) +#else +mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lexer_t *lex) +#endif +{ + #if MICROPY_PY_BUILTINS_FLOAT const char *top = str + len; mp_float_t dec_val = 0; @@ -255,6 +275,7 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex bool exp_neg = false; int exp_val = 0; int exp_extra = 0; + int trailing_zeros_intg = 0, trailing_zeros_frac = 0; while (str < top) { unsigned int dig = *str++; if ('0' <= dig && dig <= '9') { @@ -267,18 +288,25 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex exp_val = 10 * exp_val + dig; } } else { - if (dec_val < DEC_VAL_MAX) { - // dec_val won't overflow so keep accumulating - dec_val = 10 * dec_val + dig; - if (in == PARSE_DEC_IN_FRAC) { - --exp_extra; + if (dig == 0 || dec_val >= DEC_VAL_MAX) { + // Defer treatment of zeros in fractional part. If nothing comes afterwards, ignore them. + // Also, once we reach DEC_VAL_MAX, treat every additional digit as a trailing zero. + if (in == PARSE_DEC_IN_INTG) { + ++trailing_zeros_intg; + } else { + ++trailing_zeros_frac; } } else { - // dec_val might overflow and we anyway can't represent more digits - // of precision, so ignore the digit and just adjust the exponent - if (in == PARSE_DEC_IN_INTG) { - ++exp_extra; + // Time to un-defer any trailing zeros. Intg zeros first. + while (trailing_zeros_intg) { + accept_digit(&dec_val, 0, &exp_extra, PARSE_DEC_IN_INTG); + --trailing_zeros_intg; + } + while (trailing_zeros_frac) { + accept_digit(&dec_val, 0, &exp_extra, PARSE_DEC_IN_FRAC); + --trailing_zeros_frac; } + accept_digit(&dec_val, dig, &exp_extra, in); } } } else if (in == PARSE_DEC_IN_INTG && dig == '.') { @@ -311,7 +339,7 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex } // apply the exponent, making sure it's not a subnormal value - exp_val += exp_extra; + exp_val += exp_extra + trailing_zeros_intg; if (exp_val < SMALL_NORMAL_EXP) { exp_val -= SMALL_NORMAL_EXP; dec_val *= SMALL_NORMAL_VAL; From 6f4d424f461bede1afb69637763f4fce5f27cd90 Mon Sep 17 00:00:00 2001 From: Dan Ellis Date: Thu, 28 Jul 2022 10:49:18 -0400 Subject: [PATCH 1609/4290] py/formatfloat: Use pow(10, e) instead of pos/neg_pow lookup tables. Rework the conversion of floats to decimal strings so it aligns precisely with the conversion of strings to floats in parsenum.c. This is to avoid rendering 1eX as 9.99999eX-1 etc. This is achieved by removing the power- of-10 tables and using pow() to compute the exponent directly, and that's done efficiently by first estimating the power-of-10 exponent from the power-of-2 exponent in the floating-point representation. Code size is reduced by roughly 100 to 200 bytes by this commit. Signed-off-by: Dan Ellis --- py/formatfloat.c | 132 ++++++-------------- py/misc.h | 2 + tests/float/float_format.py | 8 ++ tests/float/float_format_ints_doubleprec.py | 3 + tests/float/string_format_modulo.py | 5 +- 5 files changed, 53 insertions(+), 97 deletions(-) diff --git a/py/formatfloat.c b/py/formatfloat.c index 357b73ace3ab..fc1b2fe7fc5b 100644 --- a/py/formatfloat.c +++ b/py/formatfloat.c @@ -62,26 +62,20 @@ #define FPMIN_BUF_SIZE 6 // +9e+99 #define FLT_SIGN_MASK 0x80000000 -#define FLT_EXP_MASK 0x7F800000 -#define FLT_MAN_MASK 0x007FFFFF -union floatbits { - float f; - uint32_t u; -}; static inline int fp_signbit(float x) { - union floatbits fb = {x}; - return fb.u & FLT_SIGN_MASK; + mp_float_union_t fb = {x}; + return fb.i & FLT_SIGN_MASK; } #define fp_isnan(x) isnan(x) #define fp_isinf(x) isinf(x) static inline int fp_iszero(float x) { - union floatbits fb = {x}; - return fb.u == 0; + mp_float_union_t fb = {x}; + return fb.i == 0; } static inline int fp_isless1(float x) { - union floatbits fb = {x}; - return fb.u < 0x3f800000; + mp_float_union_t fb = {x}; + return fb.i < 0x3f800000; } #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE @@ -99,28 +93,11 @@ static inline int fp_isless1(float x) { #endif // MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT/DOUBLE -static inline int fp_ge_eps(FPTYPE x, FPTYPE y) { - mp_float_union_t fb_y = {y}; - // Back off 2 eps. - // This is valid for almost all values, but in practice - // it's only used when y = 1eX for X>=0. - fb_y.i -= 2; - return x >= fb_y.f; +static inline int fp_expval(FPTYPE x) { + mp_float_union_t fb = {x}; + return (int)((fb.i >> MP_FLOAT_FRAC_BITS) & (~(0xFFFFFFFF << MP_FLOAT_EXP_BITS))) - MP_FLOAT_EXP_OFFSET; } -static const FPTYPE g_pos_pow[] = { - #if FPDECEXP > 32 - MICROPY_FLOAT_CONST(1e256), MICROPY_FLOAT_CONST(1e128), MICROPY_FLOAT_CONST(1e64), - #endif - MICROPY_FLOAT_CONST(1e32), MICROPY_FLOAT_CONST(1e16), MICROPY_FLOAT_CONST(1e8), MICROPY_FLOAT_CONST(1e4), MICROPY_FLOAT_CONST(1e2), MICROPY_FLOAT_CONST(1e1) -}; -static const FPTYPE g_neg_pow[] = { - #if FPDECEXP > 32 - MICROPY_FLOAT_CONST(1e-256), MICROPY_FLOAT_CONST(1e-128), MICROPY_FLOAT_CONST(1e-64), - #endif - MICROPY_FLOAT_CONST(1e-32), MICROPY_FLOAT_CONST(1e-16), MICROPY_FLOAT_CONST(1e-8), MICROPY_FLOAT_CONST(1e-4), MICROPY_FLOAT_CONST(1e-2), MICROPY_FLOAT_CONST(1e-1) -}; - int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, char sign) { char *s = buf; @@ -177,14 +154,15 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'g' && prec == 0) { prec = 1; } - int e, e1; + int e; int dec = 0; char e_sign = '\0'; int num_digits = 0; - const FPTYPE *pos_pow = g_pos_pow; - const FPTYPE *neg_pow = g_neg_pow; int signed_e = 0; + // Approximate power of 10 exponent from binary exponent. + // abs(e_guess) is lower bound on abs(power of 10 exponent). + int e_guess = (int)(fp_expval(f) * FPCONST(0.3010299956639812)); // 1/log2(10). if (fp_iszero(f)) { e = 0; if (fmt == 'f') { @@ -203,25 +181,18 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } } } else if (fp_isless1(f)) { - FPTYPE f_mod = f; + FPTYPE f_entry = f; // Save f in case we go to 'f' format. // Build negative exponent - for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { - if (*neg_pow > f_mod) { - e += e1; - f_mod *= *pos_pow; - } - } - - char e_sign_char = '-'; - if (fp_isless1(f_mod) && f_mod >= FPROUND_TO_ONE) { - f_mod = FPCONST(1.0); - if (e == 0) { - e_sign_char = '+'; - } - } else if (fp_isless1(f_mod)) { - e++; - f_mod *= FPCONST(10.0); + e = -e_guess; + FPTYPE u_base = MICROPY_FLOAT_C_FUN(pow)(10, -e); + while (u_base > f) { + ++e; + u_base = MICROPY_FLOAT_C_FUN(pow)(10, -e); } + // Normalize out the inferred unit. Use divide because + // pow(10, e) * pow(10, -e) is slightly < 1 for some e in float32 + // (e.g. print("%.12f" % ((1e13) * (1e-13)))) + f /= u_base; // If the user specified 'g' format, and e is <= 4, then we'll switch // to the fixed format ('f') @@ -241,11 +212,12 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch num_digits = prec; signed_e = 0; + f = f_entry; ++num_digits; } else { // For e & g formats, we'll be printing the exponent, so set the // sign. - e_sign = e_sign_char; + e_sign = '-'; dec = 0; if (prec > (buf_remaining - FPMIN_BUF_SIZE)) { @@ -262,19 +234,11 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch // scaling it. Instead, we find the product of powers of 10 // that is not greater than it, and use that to start the // mantissa. - FPTYPE u_base = FPCONST(1.0); - for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++) { - FPTYPE next_u = u_base * *pos_pow; - // fp_ge_eps performs "f >= (next_u - 2eps)" so that if, for - // numerical reasons, f is very close to a power of ten but - // not strictly equal, we still treat it as that power of 10. - // The comparison was failing for maybe 10% of 1eX values, but - // although rounding fixed many of them, there were still some - // rendering as 9.99999998e(X-1). - if (fp_ge_eps(f, next_u)) { - u_base = next_u; - e += e1; - } + e = e_guess; + FPTYPE next_u = MICROPY_FLOAT_C_FUN(pow)(10, e + 1); + while (f >= next_u) { + ++e; + next_u = MICROPY_FLOAT_C_FUN(pow)(10, e + 1); } // If the user specified fixed format (fmt == 'f') and e makes the @@ -341,46 +305,22 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch num_digits = prec; } - if (signed_e < 0) { - // The algorithm below treats numbers smaller than 1 by scaling them - // repeatedly by 10 to bring the new digit to the top. Our input number - // was smaller than 1, so scale it up to be 1 <= f < 10. - FPTYPE u_base = FPCONST(1.0); - const FPTYPE *pow_u = g_pos_pow; - for (int m = FPDECEXP; m; m >>= 1, pow_u++) { - if (m & e) { - u_base *= *pow_u; - } - } - f *= u_base; - } - int d = 0; - int num_digits_left = num_digits; - for (int digit_index = signed_e; num_digits_left >= 0; --digit_index) { + for (int digit_index = signed_e; num_digits >= 0; --digit_index) { FPTYPE u_base = FPCONST(1.0); if (digit_index > 0) { // Generate 10^digit_index for positive digit_index. - const FPTYPE *pow_u = g_pos_pow; - int target_index = digit_index; - for (int m = FPDECEXP; m; m >>= 1, pow_u++) { - if (m & target_index) { - u_base *= *pow_u; - } - } + u_base = MICROPY_FLOAT_C_FUN(pow)(10, digit_index); } for (d = 0; d < 9; ++d) { - // This is essentially "if (f < u_base)", but with 2eps margin - // so that if f is just a tiny bit smaller, we treat it as - // equal (and accept the additional digit value). - if (!fp_ge_eps(f, u_base)) { + if (f < u_base) { break; } f -= u_base; } // We calculate one more digit than we display, to use in rounding // below. So only emit the digit if it's one that we display. - if (num_digits_left > 0) { + if (num_digits > 0) { // Emit this number (the leading digit). *s++ = '0' + d; if (dec == 0 && prec > 0) { @@ -388,9 +328,9 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } } --dec; - --num_digits_left; + --num_digits; if (digit_index <= 0) { - // Once we get below 1.0, we scale up f instead of calculting + // Once we get below 1.0, we scale up f instead of calculating // negative powers of 10 in u_base. This provides better // renditions of exact decimals like 1/16 etc. f *= FPCONST(10.0); diff --git a/py/misc.h b/py/misc.h index e642598c56d0..134325f8946f 100644 --- a/py/misc.h +++ b/py/misc.h @@ -243,10 +243,12 @@ extern mp_uint_t mp_verbose_flag; #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE #define MP_FLOAT_EXP_BITS (11) +#define MP_FLOAT_EXP_OFFSET (1023) #define MP_FLOAT_FRAC_BITS (52) typedef uint64_t mp_float_uint_t; #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT #define MP_FLOAT_EXP_BITS (8) +#define MP_FLOAT_EXP_OFFSET (127) #define MP_FLOAT_FRAC_BITS (23) typedef uint32_t mp_float_uint_t; #endif diff --git a/tests/float/float_format.py b/tests/float/float_format.py index 4c8a217567ab..98ed0eb096fa 100644 --- a/tests/float/float_format.py +++ b/tests/float/float_format.py @@ -17,3 +17,11 @@ # check a case that would render negative digit values, eg ")" characters # the string is converted back to a float to check for no illegal characters float("%.23e" % 1e-80) + +# Check a problem with malformed "e" format numbers on the edge of 1.0e-X. +for r in range(38): + s = "%.12e" % float("1e-" + str(r)) + # It may format as 1e-r, or 9.999...e-(r+1), both are OK. + # But formatting as 0.999...e-r is NOT ok. + if s[0] == "0": + print("FAIL:", s) diff --git a/tests/float/float_format_ints_doubleprec.py b/tests/float/float_format_ints_doubleprec.py index 57899d6d65a8..67101d3e4503 100644 --- a/tests/float/float_format_ints_doubleprec.py +++ b/tests/float/float_format_ints_doubleprec.py @@ -13,3 +13,6 @@ v2 = 0x6974E718D7D7625A # 1e200 print("{:.12e}".format(array.array("d", v1.to_bytes(8, sys.byteorder))[0])) print("{:.12e}".format(array.array("d", v2.to_bytes(8, sys.byteorder))[0])) + +for i in range(300): + print(float("1e" + str(i))) diff --git a/tests/float/string_format_modulo.py b/tests/float/string_format_modulo.py index 09446153810d..3c206b739358 100644 --- a/tests/float/string_format_modulo.py +++ b/tests/float/string_format_modulo.py @@ -41,7 +41,10 @@ print(("%.40g" % 1e-1)[:2]) print(("%.40g" % 1e-2)[:2]) print(("%.40g" % 1e-3)[:2]) -print(("%.40g" % 1e-4)[:2]) +# Under Appveyor Release builds, 1e-4 was being formatted as 9.99999...e-5 +# instead of 0.0001. (Interestingly, it formatted correctly for the Debug +# build). Avoid the edge case. +print(("%.40g" % 1.1e-4)[:2]) print("%.0g" % 1) # 0 precision 'g' From a16a330da54afd392252d7ea04139fd4702f48f8 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 15 Aug 2022 16:07:00 +1000 Subject: [PATCH 1610/4290] nrf,stm32: Don't enable debug info by default if LTO is on. It seems sometimes gcc with LTO will generate otherwise valid assembly listings that cause 'as' to error out when generating DWARF debug info; see https://sourceware.org/bugzilla/show_bug.cgi?id=29494 Therefore, don't enable -g by default if LTO is on. Enabling LTO=1 DEBUG=1 is still possible but may result in random errors at link time due to 'as' (the error in this case is "Error: unaligned opcodes detected in executable segment", and the only other easy workaround is CFLAGS+=-fno-jump-tables which may increase code size significantly). Follows on from fdfe4eca745dce5f20fb65a3c197006b9053999a --- ports/nrf/Makefile | 6 ++++-- ports/stm32/Makefile | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 23be4430f396..bc295cac808e 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -138,12 +138,14 @@ LDFLAGS += -Wl,'--defsym=_fs_size=$(FS_SIZE)' endif #Debugging/Optimization -CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) #ASMFLAGS += -g -gtabs+ -CFLAGS += -O0 +CFLAGS += -g -O0 LDFLAGS += -O0 else +ifneq ($(LTO), 1) +CFLAGS += -g # always include debug info in the ELF, unless LTO is on +endif CFLAGS += -Os -DNDEBUG LDFLAGS += -Os endif diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 657524798cf5..14a93a5aa765 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -114,13 +114,15 @@ $(BUILD)/stm32_it.o $(BUILD)/pendsv.o: CFLAGS += -fno-lto endif # Debugging/Optimization -CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG), 1) -CFLAGS += -DPENDSV_DEBUG +CFLAGS += -g -DPENDSV_DEBUG COPT ?= -Og # Disable text compression in debug builds MICROPY_ROM_TEXT_COMPRESSION = 0 else +ifneq ($(LTO), 1) +CFLAGS += -g # always include debug info in the ELF, unless LTO is on +endif COPT ?= -Os -DNDEBUG endif From 454d969781564567864bb431f416df1fc1852765 Mon Sep 17 00:00:00 2001 From: David Peake Date: Mon, 15 Aug 2022 20:17:41 +1000 Subject: [PATCH 1611/4290] docs/esp32: Fix string quoting consistency in SDCard mount example. It appears that strings in the documentation are typically single quoted. --- docs/esp32/quickref.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 3cbb673c04b5..1529c0ef4929 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -589,7 +589,7 @@ See :ref:`machine.SDCard `. :: # Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23 sd = machine.SDCard(slot=2) - os.mount(sd, "/sd") # mount + os.mount(sd, '/sd') # mount os.listdir('/sd') # list directory contents From 98bd7e33b32fb00ad2900e71cbe5cc4938598a7a Mon Sep 17 00:00:00 2001 From: Efi Weiss Date: Sun, 14 Aug 2022 22:12:24 +0300 Subject: [PATCH 1612/4290] unix/modusocket: Support proto and flags arguments to getaddrinfo. Signed-off-by: Efi Weiss --- ports/unix/modusocket.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 03d069cb89ce..69ae2a78ebbb 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -564,7 +564,6 @@ STATIC mp_obj_t mod_socket_inet_ntop(mp_obj_t family_in, mp_obj_t binaddr_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_socket_inet_ntop_obj, mod_socket_inet_ntop); STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { - // TODO: Implement 5th and 6th args const char *host = mp_obj_str_get_str(args[0]); const char *serv = NULL; @@ -600,6 +599,12 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { hints.ai_family = MP_OBJ_SMALL_INT_VALUE(args[2]); if (n_args > 3) { hints.ai_socktype = MP_OBJ_SMALL_INT_VALUE(args[3]); + if (n_args > 4) { + hints.ai_protocol = MP_OBJ_SMALL_INT_VALUE(args[4]); + if (n_args > 5) { + hints.ai_flags = MP_OBJ_SMALL_INT_VALUE(args[5]); + } + } } } @@ -633,7 +638,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { freeaddrinfo(addr_list); return list; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_socket_getaddrinfo_obj, 2, 4, mod_socket_getaddrinfo); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_socket_getaddrinfo_obj, 2, 6, mod_socket_getaddrinfo); STATIC mp_obj_t mod_socket_sockaddr(mp_obj_t sockaddr_in) { mp_buffer_info_t bufinfo; From cbc9f944c4db6e3aee0bce0584b1eab674f0e5b9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 18 Aug 2022 11:46:53 +1000 Subject: [PATCH 1613/4290] tests,tools: Update path to unix micropython executable. These were missed by 47c84286e8c8d9873e99f12711a683ecd6b9ca62 Signed-off-by: Damien George --- tests/run-internalbench.py | 2 +- tests/run-multitests.py | 2 +- tests/run-perfbench.py | 2 +- tools/codestats.sh | 2 +- tools/gen-cpydiff.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/run-internalbench.py b/tests/run-internalbench.py index 606fc3b77201..0d2197850110 100755 --- a/tests/run-internalbench.py +++ b/tests/run-internalbench.py @@ -16,7 +16,7 @@ MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython") def run_tests(pyb, test_dict): diff --git a/tests/run-multitests.py b/tests/run-multitests.py index d8a4a48fa755..bd6cc70f7a51 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -18,7 +18,7 @@ MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython") # For diff'ing test output DIFF = os.getenv("MICROPY_DIFF", "diff -u") diff --git a/tests/run-perfbench.py b/tests/run-perfbench.py index d70b99693737..6f340968b2f9 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -21,7 +21,7 @@ MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython") PYTHON_TRUTH = CPYTHON3 diff --git a/tools/codestats.sh b/tools/codestats.sh index 09284a30de3a..74430739917b 100755 --- a/tools/codestats.sh +++ b/tools/codestats.sh @@ -23,7 +23,7 @@ AWK=awk MAKE="make -j2" # these are the binaries that are built; some have 2 or 3 depending on version -bin_unix=ports/unix/micropython +bin_unix=ports/unix/build-standard/micropython bin_stm32=ports/stm32/build-PYBV10/firmware.elf bin_barearm_1=ports/bare-arm/build/flash.elf bin_barearm_2=ports/bare-arm/build/firmware.elf diff --git a/tools/gen-cpydiff.py b/tools/gen-cpydiff.py index d4c8a5736d9e..46b3079cac2e 100644 --- a/tools/gen-cpydiff.py +++ b/tools/gen-cpydiff.py @@ -42,7 +42,7 @@ MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython") TESTPATH = "../tests/cpydiff/" DOCPATH = "../docs/genrst/" From 237a393bec51ae564b2b9ded404ef58949a3bc63 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 18 Aug 2022 11:48:45 +1000 Subject: [PATCH 1614/4290] extmod/vfs_posix_file: Remove unused MICROPY_VFS_POSIX_FILE. This was made obsolete by 2b409ef8a46015f8f3bd20bc44e644637dbe9bd3 Signed-off-by: Damien George --- extmod/vfs_posix_file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 795ad7bbd9ea..a758db14c3bd 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -30,7 +30,7 @@ #include "py/stream.h" #include "extmod/vfs_posix.h" -#if MICROPY_VFS_POSIX || MICROPY_VFS_POSIX_FILE +#if MICROPY_VFS_POSIX #include #include @@ -285,4 +285,4 @@ const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, S const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO}; const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_vfs_posix_textio}, STDERR_FILENO}; -#endif // MICROPY_VFS_POSIX || MICROPY_VFS_POSIX_FILE +#endif // MICROPY_VFS_POSIX From 8f4c108025d4590a1b7f9d062ad64f95c45e0bc2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 18 Aug 2022 11:54:17 +1000 Subject: [PATCH 1615/4290] all: Remove MICROPY_PY_IO_FILEIO config option. Since commit e65d1e69e88268145ff0e7e73240f028885915be there is no longer an io.FileIO class, so this option is no longer needed. This option also controlled whether or not files supported being opened in binary mode (eg 'rb'), and could, if disabled, lead to confusion as to why opening a file in binary mode silently did the wrong thing (it would just open in text mode if MICROPY_PY_IO_FILEIO was disabled). The various VFS implementations (POSIX, FAT, LFS) were the only places where enabling this option made a difference, and in almost all cases where one of these filesystems were enabled, MICROPY_PY_IO_FILEIO was also enabled. So it makes sense to just unconditionally enable this feature (ability to open a file in binary mode) in all cases, and so just remove this config option altogether. That makes configuration simpler and means binary file support always exists (and opening a file in binary mode is arguably more fundamental than opening in text mode, so if anything should be configurable then it should be the ability to open in text mode). Signed-off-by: Damien George --- examples/embedding/mpconfigport_minimal.h | 1 - extmod/vfs_fat_file.c | 4 ---- extmod/vfs_lfsx_file.c | 4 ---- extmod/vfs_posix_file.c | 5 ----- ports/cc3200/mpconfigport.h | 1 - ports/esp8266/mpconfigport.h | 1 - ports/mimxrt/mpconfigport.h | 1 - ports/nrf/mpconfigport.h | 1 - ports/renesas-ra/mpconfigport.h | 1 - ports/samd/mpconfigport.h | 1 - ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h | 1 - ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h | 1 - ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h | 1 - ports/unix/mpconfigport.h | 1 - ports/unix/variants/minimal/mpconfigvariant.h | 1 - ports/windows/mpconfigport.h | 1 - py/mpconfig.h | 5 ----- 17 files changed, 31 deletions(-) diff --git a/examples/embedding/mpconfigport_minimal.h b/examples/embedding/mpconfigport_minimal.h index 91b194bc7bc3..02089c1a6213 100644 --- a/examples/embedding/mpconfigport_minimal.h +++ b/examples/embedding/mpconfigport_minimal.h @@ -69,7 +69,6 @@ #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) #define MICROPY_PY_IO (0) -#define MICROPY_PY_IO_FILEIO (0) #define MICROPY_PY_STRUCT (0) #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_EXIT (0) diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index ebf36fc3978c..874f10c50045 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -170,7 +170,6 @@ STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(vfs_fat_rawfile_locals_dict, vfs_fat_rawfile_locals_dict_table); -#if MICROPY_PY_IO_FILEIO STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = { .read = file_obj_read, .write = file_obj_write, @@ -186,7 +185,6 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = { .protocol = &vfs_fat_fileio_stream_p, .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, }; -#endif STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { .read = file_obj_read, @@ -230,11 +228,9 @@ STATIC mp_obj_t fat_vfs_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_i case '+': mode |= FA_READ | FA_WRITE; break; - #if MICROPY_PY_IO_FILEIO case 'b': type = &mp_type_vfs_fat_fileio; break; - #endif case 't': type = &mp_type_vfs_fat_textio; break; diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c index bc1a37b90bdb..124361feb99f 100644 --- a/extmod/vfs_lfsx_file.c +++ b/extmod/vfs_lfsx_file.c @@ -68,11 +68,9 @@ mp_obj_t MP_VFS_LFSx(file_open)(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mod case '+': flags |= LFSx_MACRO(_O_RDWR); break; - #if MICROPY_PY_IO_FILEIO case 'b': type = &MP_TYPE_VFS_LFSx_(_fileio); break; - #endif case 't': type = &MP_TYPE_VFS_LFSx_(_textio); break; @@ -216,7 +214,6 @@ STATIC const mp_rom_map_elem_t MP_VFS_LFSx(file_locals_dict_table)[] = { }; STATIC MP_DEFINE_CONST_DICT(MP_VFS_LFSx(file_locals_dict), MP_VFS_LFSx(file_locals_dict_table)); -#if MICROPY_PY_IO_FILEIO STATIC const mp_stream_p_t MP_VFS_LFSx(fileio_stream_p) = { .read = MP_VFS_LFSx(file_read), .write = MP_VFS_LFSx(file_write), @@ -232,7 +229,6 @@ const mp_obj_type_t MP_TYPE_VFS_LFSx_(_fileio) = { .protocol = &MP_VFS_LFSx(fileio_stream_p), .locals_dict = (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict), }; -#endif STATIC const mp_stream_p_t MP_VFS_LFSx(textio_stream_p) = { .read = MP_VFS_LFSx(file_read), diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index a758db14c3bd..c550842cd4e8 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -83,15 +83,12 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ case '+': mode_rw = O_RDWR; break; - #if MICROPY_PY_IO_FILEIO - // If we don't have io.FileIO, then files are in text mode implicitly case 'b': type = &mp_type_vfs_posix_fileio; break; case 't': type = &mp_type_vfs_posix_textio; break; - #endif } } @@ -246,7 +243,6 @@ STATIC const mp_rom_map_elem_t vfs_posix_rawfile_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(vfs_posix_rawfile_locals_dict, vfs_posix_rawfile_locals_dict_table); -#if MICROPY_PY_IO_FILEIO STATIC const mp_stream_p_t vfs_posix_fileio_stream_p = { .read = vfs_posix_file_read, .write = vfs_posix_file_write, @@ -262,7 +258,6 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = { .protocol = &vfs_posix_fileio_stream_p, .locals_dict = (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict, }; -#endif STATIC const mp_stream_p_t vfs_posix_textio_stream_p = { .read = vfs_posix_file_read, diff --git a/ports/cc3200/mpconfigport.h b/ports/cc3200/mpconfigport.h index f41c1fe99dbf..93fc291c1a4c 100644 --- a/ports/cc3200/mpconfigport.h +++ b/ports/cc3200/mpconfigport.h @@ -105,7 +105,6 @@ #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_CMATH (0) #define MICROPY_PY_IO (1) -#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_UERRNO (1) #define MICROPY_PY_UERRNO_ERRORCODE (0) #define MICROPY_PY_THREAD (1) diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 9ff6a34ffd62..ded56663b32b 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -35,7 +35,6 @@ #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (0) #define MICROPY_PY_MATH_FACTORIAL (0) #define MICROPY_PY_MATH_ISCLOSE (0) -#define MICROPY_PY_IO_FILEIO (MICROPY_VFS) #define MICROPY_PY_SYS_PS1_PS2 (0) #define MICROPY_PY_UBINASCII_CRC32 (0) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 54d649795df0..8642d53ecc45 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -101,7 +101,6 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MATH_ISCLOSE (1) #define MICROPY_PY_CMATH (1) #define MICROPY_PY_IO_IOBASE (1) -#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_PLATFORM "mimxrt" #define MICROPY_PY_SYS_STDFILES (1) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index a25ca1ec27ef..ac238057dd42 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -155,7 +155,6 @@ #define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_SYS_MAXSIZE (1) -#define MICROPY_PY_IO_FILEIO (MICROPY_VFS_FAT || MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2) #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #define MICROPY_PY_UTIME_MP_HAL (1) diff --git a/ports/renesas-ra/mpconfigport.h b/ports/renesas-ra/mpconfigport.h index 65b194274a53..b77a3c492323 100644 --- a/ports/renesas-ra/mpconfigport.h +++ b/ports/renesas-ra/mpconfigport.h @@ -83,7 +83,6 @@ #ifndef MICROPY_PY_BUILTINS_HELP_TEXT #define MICROPY_PY_BUILTINS_HELP_TEXT ra_help_text #endif -#define MICROPY_PY_IO_FILEIO (MICROPY_VFS_FAT || MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2) #ifndef MICROPY_PY_SYS_PLATFORM // let boards override it if they want #define MICROPY_PY_SYS_PLATFORM "renesas-ra" #endif diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index c02d9316ded3..0b16b5e817af 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -77,7 +77,6 @@ #define MICROPY_PY_SYS_EXIT (1) #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_SYS_MAXSIZE (1) -#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_IO (1) #define MICROPY_PY_IO_IOBASE (1) diff --git a/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h b/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h index d4996e6c74d6..dfcca72afb55 100644 --- a/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h +++ b/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h @@ -11,7 +11,6 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_GENERATOR_PEND_THROW (0) #define MICROPY_PY_MATH (0) -#define MICROPY_PY_IO_FILEIO (0) #define MICROPY_PY_FRAMEBUF (0) #define MICROPY_PY_USOCKET (0) #define MICROPY_PY_NETWORK (0) diff --git a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h index a68b939939c1..d44bfb0bb663 100644 --- a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h @@ -5,7 +5,6 @@ #define MICROPY_EMIT_INLINE_THUMB (0) #define MICROPY_OPT_COMPUTED_GOTO (0) #define MICROPY_PY_BUILTINS_COMPLEX (0) -#define MICROPY_PY_IO_FILEIO (0) #define MICROPY_PY_USOCKET (0) #define MICROPY_PY_NETWORK (0) #define MICROPY_PY_STM (0) diff --git a/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h index 9af925d45196..c8c809eb4899 100644 --- a/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h @@ -11,7 +11,6 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_GENERATOR_PEND_THROW (0) #define MICROPY_PY_MATH (0) -#define MICROPY_PY_IO_FILEIO (0) #define MICROPY_PY_FRAMEBUF (0) #define MICROPY_PY_USOCKET (0) #define MICROPY_PY_NETWORK (0) diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 5545a74f57cc..03b8ceb1f6f9 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -87,7 +87,6 @@ #define MICROPY_PY_MATH_ISCLOSE (MICROPY_PY_MATH_SPECIAL_FUNCTIONS) #define MICROPY_PY_CMATH (1) #define MICROPY_PY_IO_IOBASE (1) -#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_UERRNO (1) diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index d6e5fc47262e..2e2c1de0cc87 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -86,7 +86,6 @@ #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) #define MICROPY_PY_IO (0) -#define MICROPY_PY_IO_FILEIO (0) #define MICROPY_PY_STRUCT (0) #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_EXIT (0) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 4ed9f316e7bb..8967242aee5f 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -125,7 +125,6 @@ #define MICROPY_PY_MATH_ISCLOSE (MICROPY_PY_MATH_SPECIAL_FUNCTIONS) #define MICROPY_PY_CMATH (1) #define MICROPY_PY_IO_IOBASE (1) -#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_GC_COLLECT_RETVAL (1) #ifndef MICROPY_STACKLESS #define MICROPY_STACKLESS (0) diff --git a/py/mpconfig.h b/py/mpconfig.h index 1ed34bb6fdae..d478c654d021 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1321,11 +1321,6 @@ typedef double mp_float_t; #define MICROPY_PY_IO_IOBASE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to provide "io.FileIO" class -#ifndef MICROPY_PY_IO_FILEIO -#define MICROPY_PY_IO_FILEIO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) -#endif - // Whether to provide "io.BytesIO" class #ifndef MICROPY_PY_IO_BYTESIO #define MICROPY_PY_IO_BYTESIO (1) From a311e9e3d419cf447c8a4cf2beed4a341e8387e3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 18 Aug 2022 12:32:10 +1000 Subject: [PATCH 1616/4290] tools/mpremote: Allow + terminator for fs commands. Signed-off-by: Jim Mussared --- docs/reference/mpremote.rst | 5 +++++ tools/mpremote/mpremote/main.py | 34 ++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index 2bbed56b8914..80290657f4c3 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -30,6 +30,9 @@ For REPL access, running ``mpremote`` without any arguments is usually all that is needed. ``mpremote`` also supports a set of commands given at the command line which will perform various actions on remote MicroPython devices. +For commands that support multiple arguments (e.g. a list of files), the +argument list can be terminated with ``+``. + The full list of supported commands are: - connect to a specified device via a device-name shortcut: @@ -248,3 +251,5 @@ Examples mpremote cp main.py : mpremote cp -r dir/ : + + mpremote cp a.py b.py : + repl diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index e0266fd71901..73cd5e153bc7 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -300,6 +300,19 @@ def show_progress_bar(size, total_size): ) +# Get all args up to the terminator ("+"). +# The passed args will be updated with these ones removed. +def get_fs_args(args): + n = 0 + for src in args: + if src == "+": + break + n += 1 + fs_args = args[:n] + args[:] = args[n + 1 :] + return fs_args + + def do_filesystem(pyb, args): def _list_recursive(files, path): if os.path.isdir(path): @@ -308,16 +321,18 @@ def _list_recursive(files, path): else: files.append(os.path.split(path)) + fs_args = get_fs_args(args) + # Don't be verbose when using cat, so output can be redirected to something. - verbose = args[0] != "cat" + verbose = fs_args[0] != "cat" - if args[0] == "cp" and args[1] == "-r": - args.pop(0) - args.pop(0) - assert args[-1] == ":" - args.pop() + if fs_args[0] == "cp" and fs_args[1] == "-r": + fs_args.pop(0) + fs_args.pop(0) + assert fs_args[-1] == ":" + fs_args.pop() src_files = [] - for path in args: + for path in fs_args: _list_recursive(src_files, path) known_dirs = {""} pyb.exec_("import uos") @@ -335,8 +350,9 @@ def _list_recursive(files, path): verbose=verbose, ) else: - pyboard.filesystem_command(pyb, args, progress_callback=show_progress_bar, verbose=verbose) - args.clear() + pyboard.filesystem_command( + pyb, fs_args, progress_callback=show_progress_bar, verbose=verbose + ) def do_repl_main_loop(pyb, console_in, console_out_write, *, code_to_inject, file_to_inject): From 263737ecfea6ec1049ef3aff37913866ebd463e5 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 18 Aug 2022 12:34:15 +1000 Subject: [PATCH 1617/4290] tools/pyboard.py: Add "touch" filesystem command. Signed-off-by: Jim Mussared --- docs/reference/mpremote.rst | 5 +++-- docs/reference/pyboard.py.rst | 5 +++-- tools/pyboard.py | 8 ++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index 80290657f4c3..3927c9badf1f 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -131,6 +131,7 @@ The full list of supported commands are: - ``rm `` to remove files on the device - ``mkdir `` to create directories on the device - ``rmdir `` to remove directories on the device + - ``touch `` to create the files (if they don't already exist) - mount the local directory on the remote device: @@ -192,8 +193,8 @@ Shortcuts can be defined using the macro system. Built-in shortcuts are:: - ``c0``, ``c1``, ``c2``, ``c3``: connect to COM? -- ``cat``, ``ls``, ``cp``, ``rm``, ``mkdir``, ``rmdir``, ``df``: filesystem - commands +- ``cat``, ``ls``, ``cp``, ``rm``, ``mkdir``, ``rmdir``, ``touch``, ``df``: + filesystem commands - ``reset``: reset the device diff --git a/docs/reference/pyboard.py.rst b/docs/reference/pyboard.py.rst index 4fedbb7aab9a..a06ffdcd8fa9 100644 --- a/docs/reference/pyboard.py.rst +++ b/docs/reference/pyboard.py.rst @@ -92,12 +92,13 @@ Filesystem access Using the ``-f`` flag, the following filesystem operations are supported: -* ``cp src [src...] dest`` Copy files to/from the device. * ``cat path`` Print the contents of a file on the device. +* ``cp src [src...] dest`` Copy files to/from the device. * ``ls [path]`` List contents of a directory (defaults to current working directory). -* ``rm path`` Remove a file. * ``mkdir path`` Create a directory. +* ``rm path`` Remove a file. * ``rmdir path`` Remove a directory. +* ``touch path`` Create a file if it doesn't already exist. The ``cp`` command uses a ``ssh``-like convention for referring to local and remote files. Any path starting with a ``:`` will be interpreted as on the diff --git a/tools/pyboard.py b/tools/pyboard.py index 7d0ab6bcd703..752504987587 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -543,6 +543,9 @@ def fs_rmdir(self, dir): def fs_rm(self, src): self.exec_("import uos\nuos.remove('%s')" % src) + def fs_touch(self, src): + self.exec_("f=open('%s','a')\nf.close()" % src) + # in Python2 exec is a keyword so one must use "exec_" # but for Python3 we want to provide the nicer version "exec" @@ -595,11 +598,12 @@ def fname_cp_dest(src, dest): op(src, dest2, progress_callback=progress_callback) else: op = { - "ls": pyb.fs_ls, "cat": pyb.fs_cat, + "ls": pyb.fs_ls, "mkdir": pyb.fs_mkdir, - "rmdir": pyb.fs_rmdir, "rm": pyb.fs_rm, + "rmdir": pyb.fs_rmdir, + "touch": pyb.fs_touch, }[cmd] if cmd == "ls" and not args: args = [""] From 59e3348c101efee4071dd2224d01ccce6075b692 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 18 Aug 2022 12:36:42 +1000 Subject: [PATCH 1618/4290] tools/mpremote: Add "edit" command. This allows a remote file to be edited locally by copying it over, running the local editor, then copying it back. Signed-off-by: Jim Mussared --- docs/reference/mpremote.rst | 11 +++++++++++ tools/mpremote/mpremote/main.py | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index 3927c9badf1f..eb0233bddae4 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -133,6 +133,17 @@ The full list of supported commands are: - ``rmdir `` to remove directories on the device - ``touch `` to create the files (if they don't already exist) +- edit a file on the device: + + .. code-block:: bash + + $ mpremote edit + + The ``edit`` command will copy each file from the device to a local temporary + directory and then launch your editor for each file (defined by the environment + variable ``$EDITOR``). If the editor exits successfully, the updated file will + be copied back to the device. + - mount the local directory on the remote device: .. code-block:: bash diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index 73cd5e153bc7..e614156dbf78 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -19,6 +19,7 @@ import os, sys from collections.abc import Mapping +import tempfile from textwrap import dedent import serial.tools.list_ports @@ -28,6 +29,7 @@ _PROG = "mpremote" +# (need_raw_repl, is_action, num_args_min, help_text) _COMMANDS = { "connect": ( False, @@ -39,6 +41,7 @@ or any valid device name/path""", ), "disconnect": (False, False, 0, "disconnect current device"), + "edit": (True, True, 1, "edit files on the device"), "resume": (False, False, 0, "resume a previous mpremote session (will not auto soft-reset)"), "soft-reset": (False, True, 0, "perform a soft-reset of the device"), "mount": ( @@ -82,6 +85,7 @@ "ls": "fs ls", "cp": "fs cp", "rm": "fs rm", + "touch": "fs touch", "mkdir": "fs mkdir", "rmdir": "fs rmdir", "df": [ @@ -355,6 +359,23 @@ def _list_recursive(files, path): ) +def do_edit(pyb, args): + if not os.getenv("EDITOR"): + raise pyboard.PyboardError("edit: $EDITOR not set") + for src in get_fs_args(args): + src = src.lstrip(":") + dest_fd, dest = tempfile.mkstemp(suffix=os.path.basename(src)) + try: + print("edit :%s" % (src,)) + os.close(dest_fd) + pyb.fs_touch(src) + pyb.fs_get(src, dest, progress_callback=show_progress_bar) + if os.system("$EDITOR '%s'" % (dest,)) == 0: + pyb.fs_put(dest, src, progress_callback=show_progress_bar) + finally: + os.unlink(dest) + + def do_repl_main_loop(pyb, console_in, console_out_write, *, code_to_inject, file_to_inject): while True: console_in.waitchar(pyb.serial) @@ -587,6 +608,8 @@ def main(): return ret elif cmd == "fs": do_filesystem(pyb, args) + elif cmd == "edit": + do_edit(pyb, args) elif cmd == "repl": do_repl(pyb, args) From 470a44bd3ade45fd10d63aabfb14c3696b60e251 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 12 Aug 2022 16:47:02 +1000 Subject: [PATCH 1619/4290] extmod/modframebuf: Optimise argument handling. Several methods extract mp_int_t from adjacent arguments. This reduces code size for the repeated calls to mp_obj_get_int. Signed-off-by: Jim Mussared --- extmod/modframebuf.c | 165 ++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 88 deletions(-) diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 5b6575d5a650..fe32e44a2626 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -263,21 +263,21 @@ STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, u formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col); } -STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) { mp_arg_check_num(n_args, n_kw, 4, 5, false); mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, type); - o->buf_obj = args[0]; + o->buf_obj = args_in[0]; mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE); + mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE); o->buf = bufinfo.buf; - o->width = mp_obj_get_int(args[1]); - o->height = mp_obj_get_int(args[2]); - o->format = mp_obj_get_int(args[3]); + o->width = mp_obj_get_int(args_in[1]); + o->height = mp_obj_get_int(args_in[2]); + o->format = mp_obj_get_int(args_in[3]); if (n_args >= 5) { - o->stride = mp_obj_get_int(args[4]); + o->stride = mp_obj_get_int(args_in[4]); } else { o->stride = o->width; } @@ -305,6 +305,12 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size return MP_OBJ_FROM_PTR(o); } +STATIC void framebuf_args(const mp_obj_t *args_in, mp_int_t *args_out, int n) { + for (int i = 0; i < n; ++i) { + args_out[i] = mp_obj_get_int(args_in[i + 1]); + } +} + STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { (void)flags; mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in); @@ -322,98 +328,71 @@ STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill); -STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t width = mp_obj_get_int(args[3]); - mp_int_t height = mp_obj_get_int(args[4]); - mp_int_t col = mp_obj_get_int(args[5]); - - fill_rect(self, x, y, width, height, col); - +STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t args[5]; // x, y, w, h, col + framebuf_args(args_in, args, 5); + fill_rect(self, args[0], args[1], args[2], args[3], args[4]); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect); -STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) { - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); +STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t x = mp_obj_get_int(args_in[1]); + mp_int_t y = mp_obj_get_int(args_in[2]); if (0 <= x && x < self->width && 0 <= y && y < self->height) { if (n_args == 3) { // get return MP_OBJ_NEW_SMALL_INT(getpixel(self, x, y)); } else { // set - setpixel(self, x, y, mp_obj_get_int(args[3])); + setpixel(self, x, y, mp_obj_get_int(args_in[3])); } } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pixel); -STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args_in) { (void)n_args; - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t w = mp_obj_get_int(args[3]); - mp_int_t col = mp_obj_get_int(args[4]); + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t args[4]; // x, y, w, col + framebuf_args(args_in, args, 4); - fill_rect(self, x, y, w, 1, col); + fill_rect(self, args[0], args[1], args[2], 1, args[3]); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hline); -STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args_in) { (void)n_args; - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t h = mp_obj_get_int(args[3]); - mp_int_t col = mp_obj_get_int(args[4]); + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t args[4]; // x, y, h, col + framebuf_args(args_in, args, 4); - fill_rect(self, x, y, 1, h, col); + fill_rect(self, args[0], args[1], 1, args[2], args[3]); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vline); -STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t w = mp_obj_get_int(args[3]); - mp_int_t h = mp_obj_get_int(args[4]); - mp_int_t col = mp_obj_get_int(args[5]); - - fill_rect(self, x, y, w, 1, col); - fill_rect(self, x, y + h - 1, w, 1, col); - fill_rect(self, x, y, 1, h, col); - fill_rect(self, x + w - 1, y, 1, h, col); - +STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t args[5]; // x, y, w, h, col + framebuf_args(args_in, args, 5); + fill_rect(self, args[0], args[1], args[2], 1, args[4]); + fill_rect(self, args[0], args[1] + args[3] - 1, args[2], 1, args[4]); + fill_rect(self, args[0], args[1], 1, args[3], args[4]); + fill_rect(self, args[0] + args[2] - 1, args[1], 1, args[3], args[4]); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rect); -STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t x1 = mp_obj_get_int(args[1]); - mp_int_t y1 = mp_obj_get_int(args[2]); - mp_int_t x2 = mp_obj_get_int(args[3]); - mp_int_t y2 = mp_obj_get_int(args[4]); - mp_int_t col = mp_obj_get_int(args[5]); - +STATIC void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, mp_int_t col) { mp_int_t dx = x2 - x1; mp_int_t sx; if (dx > 0) { @@ -452,12 +431,12 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) { mp_int_t e = 2 * dy - dx; for (mp_int_t i = 0; i < dx; ++i) { if (steep) { - if (0 <= y1 && y1 < self->width && 0 <= x1 && x1 < self->height) { - setpixel(self, y1, x1, col); + if (0 <= y1 && y1 < fb->width && 0 <= x1 && x1 < fb->height) { + setpixel(fb, y1, x1, col); } } else { - if (0 <= x1 && x1 < self->width && 0 <= y1 && y1 < self->height) { - setpixel(self, x1, y1, col); + if (0 <= x1 && x1 < fb->width && 0 <= y1 && y1 < fb->height) { + setpixel(fb, x1, y1, col); } } while (e >= 0) { @@ -468,31 +447,41 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) { e += 2 * dy; } - if (0 <= x2 && x2 < self->width && 0 <= y2 && y2 < self->height) { - setpixel(self, x2, y2, col); + if (0 <= x2 && x2 < fb->width && 0 <= y2 && y2 < fb->height) { + setpixel(fb, x2, y2, col); } +} + +STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args_in) { + (void)n_args; + + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t args[5]; // x1, y1, x2, y2, col + framebuf_args(args_in, args, 5); + + line(self, args[0], args[1], args[2], args[3], args[4]); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line); -STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) { - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - mp_obj_t source_in = mp_obj_cast_to_native_base(args[1], MP_OBJ_FROM_PTR(&mp_type_framebuf)); +STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_obj_t source_in = mp_obj_cast_to_native_base(args_in[1], MP_OBJ_FROM_PTR(&mp_type_framebuf)); if (source_in == MP_OBJ_NULL) { mp_raise_TypeError(NULL); } mp_obj_framebuf_t *source = MP_OBJ_TO_PTR(source_in); - mp_int_t x = mp_obj_get_int(args[2]); - mp_int_t y = mp_obj_get_int(args[3]); + mp_int_t x = mp_obj_get_int(args_in[2]); + mp_int_t y = mp_obj_get_int(args_in[3]); mp_int_t key = -1; if (n_args > 4) { - key = mp_obj_get_int(args[4]); + key = mp_obj_get_int(args_in[4]); } mp_obj_framebuf_t *palette = NULL; - if (n_args > 5 && args[5] != mp_const_none) { - palette = MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(args[5], MP_OBJ_FROM_PTR(&mp_type_framebuf))); + if (n_args > 5 && args_in[5] != mp_const_none) { + palette = MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(args_in[5], MP_OBJ_FROM_PTR(&mp_type_framebuf))); } if ( @@ -563,15 +552,15 @@ STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ys } STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll); -STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args_in) { // extract arguments - mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]); - const char *str = mp_obj_str_get_str(args[1]); - mp_int_t x0 = mp_obj_get_int(args[2]); - mp_int_t y0 = mp_obj_get_int(args[3]); + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + const char *str = mp_obj_str_get_str(args_in[1]); + mp_int_t x0 = mp_obj_get_int(args_in[2]); + mp_int_t y0 = mp_obj_get_int(args_in[3]); mp_int_t col = 1; if (n_args >= 5) { - col = mp_obj_get_int(args[4]); + col = mp_obj_get_int(args_in[4]); } // loop over chars @@ -626,18 +615,18 @@ STATIC const mp_obj_type_t mp_type_framebuf = { #endif // this factory function is provided for backwards compatibility with old FrameBuffer1 class -STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, &mp_type_framebuf); mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE); + mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE); o->buf = bufinfo.buf; - o->width = mp_obj_get_int(args[1]); - o->height = mp_obj_get_int(args[2]); + o->width = mp_obj_get_int(args_in[1]); + o->height = mp_obj_get_int(args_in[2]); o->format = FRAMEBUF_MVLSB; if (n_args >= 4) { - o->stride = mp_obj_get_int(args[3]); + o->stride = mp_obj_get_int(args_in[3]); } else { o->stride = o->width; } From af1f167820e685390d43dd7e250a0ffa078e138d Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 13 Aug 2022 00:46:00 +1000 Subject: [PATCH 1620/4290] py/dynruntime: Add mp_obj_is_true. Signed-off-by: Jim Mussared --- py/dynruntime.h | 1 + 1 file changed, 1 insertion(+) diff --git a/py/dynruntime.h b/py/dynruntime.h index e3200a271954..fb748eb93fe7 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -127,6 +127,7 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_obj_str_get_data(o, len) (mp_obj_str_get_data_dyn((o), (len))) #define mp_get_buffer_raise(o, bufinfo, fl) (mp_fun_table.get_buffer_raise((o), (bufinfo), (fl))) #define mp_get_stream_raise(s, flags) (mp_fun_table.get_stream_raise((s), (flags))) +#define mp_obj_is_true(o) (mp_fun_table.native_from_obj(o, MP_NATIVE_TYPE_BOOL)) #define mp_obj_len(o) (mp_obj_len_dyn(o)) #define mp_obj_subscr(base, index, val) (mp_fun_table.obj_subscr((base), (index), (val))) From 127b340438cddd55748e066cacbc1ab64131e232 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 12 Aug 2022 16:34:51 +1000 Subject: [PATCH 1621/4290] extmod/modframebuf: Add fill argument to rect(). We plan to add `ellipse` and `poly` methods, but rather than having to implement a `fill_xyz` version of each, we can make them take an optional fill argument. This commit add this to `rect` as a starting point. Signed-off-by: Jim Mussared --- docs/library/framebuf.rst | 10 +++++----- extmod/modframebuf.c | 14 +++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index 098ada815384..702461665342 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -77,12 +77,12 @@ The following methods draw shapes onto the FrameBuffer. methods draw horizontal and vertical lines respectively up to a given length. -.. method:: FrameBuffer.rect(x, y, w, h, c) -.. method:: FrameBuffer.fill_rect(x, y, w, h, c) +.. method:: FrameBuffer.rect(x, y, w, h, c[, f]) - Draw a rectangle at the given location, size and color. The `rect` - method draws only a 1 pixel outline whereas the `fill_rect` method - draws both the outline and interior. + Draw a rectangle at the given location, size and color. + + The optional *f* parameter can be set to ``True`` to fill the rectangle. + Otherwise just a one pixel outline is drawn. Drawing text ------------ diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index fe32e44a2626..590bd085459b 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -384,13 +384,17 @@ STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); mp_int_t args[5]; // x, y, w, h, col framebuf_args(args_in, args, 5); - fill_rect(self, args[0], args[1], args[2], 1, args[4]); - fill_rect(self, args[0], args[1] + args[3] - 1, args[2], 1, args[4]); - fill_rect(self, args[0], args[1], 1, args[3], args[4]); - fill_rect(self, args[0] + args[2] - 1, args[1], 1, args[3], args[4]); + if (n_args > 6 && mp_obj_is_true(args_in[6])) { + fill_rect(self, args[0], args[1], args[2], args[3], args[4]); + } else { + fill_rect(self, args[0], args[1], args[2], 1, args[4]); + fill_rect(self, args[0], args[1] + args[3] - 1, args[2], 1, args[4]); + fill_rect(self, args[0], args[1], 1, args[3], args[4]); + fill_rect(self, args[0] + args[2] - 1, args[1], 1, args[3], args[4]); + } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rect); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 7, framebuf_rect); STATIC void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, mp_int_t col) { mp_int_t dx = x2 - x1; From 42ec9703a07d1d0b55091f5557ff5f81c5134fb8 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Wed, 10 Aug 2022 14:51:19 +0100 Subject: [PATCH 1622/4290] extmod/modframebuf: Add ellipse drawing method. --- docs/library/framebuf.rst | 18 +- examples/natmod/framebuf/framebuf.c | 9 +- extmod/modframebuf.c | 95 ++++ tests/extmod/framebuf_ellipse.py | 65 +++ tests/extmod/framebuf_ellipse.py.exp | 704 +++++++++++++++++++++++++++ 5 files changed, 885 insertions(+), 6 deletions(-) create mode 100644 tests/extmod/framebuf_ellipse.py create mode 100644 tests/extmod/framebuf_ellipse.py.exp diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index 702461665342..1e23abd0f1b5 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -11,8 +11,8 @@ class FrameBuffer ----------------- The FrameBuffer class provides a pixel buffer which can be drawn upon with -pixels, lines, rectangles, text and even other FrameBuffer's. It is useful -when generating output for displays. +pixels, lines, rectangles, ellipses, text and even other FrameBuffers. It is +useful when generating output for displays. For example:: @@ -84,6 +84,20 @@ The following methods draw shapes onto the FrameBuffer. The optional *f* parameter can be set to ``True`` to fill the rectangle. Otherwise just a one pixel outline is drawn. +.. method:: FrameBuffer.ellipse(x, y, xr, yr, c[, f, m]) + + Draw an ellipse at the given location. Radii *xr* and *yr* define the + geometry; equal values cause a circle to be drawn. The *c* parameter + defines the color. + + The optional *f* parameter can be set to ``True`` to fill the ellipse. + Otherwise just a one pixel outline is drawn. + + The optional *m* parameter enables drawing to be restricted to certain + quadrants of the ellipse. The LS four bits determine which quadrants are + to be drawn, with bit 0 specifying Q1, b1 Q2, b2 Q3 and b3 Q4. Quadrants + are numbered counterclockwise with Q1 being top right. + Drawing text ------------ diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c index 8d488cffd685..53fb90c625ad 100644 --- a/examples/natmod/framebuf/framebuf.c +++ b/examples/natmod/framebuf/framebuf.c @@ -12,7 +12,7 @@ mp_obj_type_t mp_type_framebuf; #include "extmod/modframebuf.c" -mp_map_elem_t framebuf_locals_dict_table[10]; +mp_map_elem_t framebuf_locals_dict_table[11]; STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { @@ -29,9 +29,10 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) }; framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) }; framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) }; - framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; - framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; - framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; + framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_ellipse), MP_OBJ_FROM_PTR(&framebuf_ellipse_obj) }; + framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; + framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; + framebuf_locals_dict_table[10] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict; mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 590bd085459b..0fa91942c1a7 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -469,6 +469,100 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line); +STATIC void ellipse_pixel(const mp_obj_framebuf_t *fb, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask) { + if (mask && 0 <= x && x < fb->width && 0 <= y && y < fb->height) { + setpixel(fb, x, y, col); + } +} + +// Q2 Q1 +// Q3 Q4 +#define ELLIPSE_MASK_FILL (0x10) +#define ELLIPSE_MASK_ALL (0x0f) +#define ELLIPSE_MASK_Q1 (0x01) +#define ELLIPSE_MASK_Q2 (0x02) +#define ELLIPSE_MASK_Q3 (0x04) +#define ELLIPSE_MASK_Q4 (0x08) + +STATIC void draw_ellipse_points(const mp_obj_framebuf_t *fb, mp_int_t cx, mp_int_t cy, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask) { + if (mask & ELLIPSE_MASK_FILL) { + if (mask & ELLIPSE_MASK_Q1) { + fill_rect(fb, cx, cy - y, x + 1, 1, col); + } + if (mask & ELLIPSE_MASK_Q2) { + fill_rect(fb, cx - x, cy - y, x + 1, 1, col); + } + if (mask & ELLIPSE_MASK_Q3) { + fill_rect(fb, cx - x, cy + y, x + 1, 1, col); + } + if (mask & ELLIPSE_MASK_Q4) { + fill_rect(fb, cx, cy + y, x + 1, 1, col); + } + } else { + ellipse_pixel(fb, cx + x, cy - y, col, mask & ELLIPSE_MASK_Q1); + ellipse_pixel(fb, cx - x, cy - y, col, mask & ELLIPSE_MASK_Q2); + ellipse_pixel(fb, cx - x, cy + y, col, mask & ELLIPSE_MASK_Q3); + ellipse_pixel(fb, cx + x, cy + y, col, mask & ELLIPSE_MASK_Q4); + } +} + +STATIC mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + mp_int_t args[5]; + framebuf_args(args_in, args, 5); // cx, cy, xradius, yradius, col + mp_int_t mask = (n_args > 6 && mp_obj_is_true(args_in[6])) ? ELLIPSE_MASK_FILL : 0; + if (n_args > 7) { + mask |= mp_obj_get_int(args_in[7]) & ELLIPSE_MASK_ALL; + } else { + mask |= ELLIPSE_MASK_ALL; + } + mp_int_t two_asquare = 2 * args[2] * args[2]; + mp_int_t two_bsquare = 2 * args[3] * args[3]; + mp_int_t x = args[2]; + mp_int_t y = 0; + mp_int_t xchange = args[3] * args[3] * (1 - 2 * args[2]); + mp_int_t ychange = args[2] * args[2]; + mp_int_t ellipse_error = 0; + mp_int_t stoppingx = two_bsquare * args[2]; + mp_int_t stoppingy = 0; + while (stoppingx >= stoppingy) { // 1st set of points, y' > -1 + draw_ellipse_points(self, args[0], args[1], x, y, args[4], mask); + y += 1; + stoppingy += two_asquare; + ellipse_error += ychange; + ychange += two_asquare; + if ((2 * ellipse_error + xchange) > 0) { + x -= 1; + stoppingx -= two_bsquare; + ellipse_error += xchange; + xchange += two_bsquare; + } + } + // 1st point set is done start the 2nd set of points + x = 0; + y = args[3]; + xchange = args[3] * args[3]; + ychange = args[2] * args[2] * (1 - 2 * args[3]); + ellipse_error = 0; + stoppingx = 0; + stoppingy = two_asquare * args[3]; + while (stoppingx <= stoppingy) { // 2nd set of points, y' < -1 + draw_ellipse_points(self, args[0], args[1], x, y, args[4], mask); + x += 1; + stoppingx += two_bsquare; + ellipse_error += xchange; + xchange += two_bsquare; + if ((2 * ellipse_error + ychange) > 0) { + y -= 1; + stoppingy -= two_asquare; + ellipse_error += ychange; + ychange += two_asquare; + } + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_ellipse_obj, 6, 8, framebuf_ellipse); + STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); mp_obj_t source_in = mp_obj_cast_to_native_base(args_in[1], MP_OBJ_FROM_PTR(&mp_type_framebuf)); @@ -603,6 +697,7 @@ STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_vline), MP_ROM_PTR(&framebuf_vline_obj) }, { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&framebuf_rect_obj) }, { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&framebuf_line_obj) }, + { MP_ROM_QSTR(MP_QSTR_ellipse), MP_ROM_PTR(&framebuf_ellipse_obj) }, { MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&framebuf_blit_obj) }, { MP_ROM_QSTR(MP_QSTR_scroll), MP_ROM_PTR(&framebuf_scroll_obj) }, { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&framebuf_text_obj) }, diff --git a/tests/extmod/framebuf_ellipse.py b/tests/extmod/framebuf_ellipse.py new file mode 100644 index 000000000000..a4c784aff876 --- /dev/null +++ b/tests/extmod/framebuf_ellipse.py @@ -0,0 +1,65 @@ +try: + import framebuf +except ImportError: + print("SKIP") + raise SystemExit + + +def printbuf(): + print("--8<--") + for y in range(h): + for x in range(w): + print("%02x" % buf[(x + y * w)], end="") + print() + print("-->8--") + + +w = 30 +h = 30 +buf = bytearray(w * h) +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) + +# Outline +fbuf.fill(0) +fbuf.ellipse(15, 15, 12, 6, 0xFF, False) +printbuf() + +# Fill +fbuf.fill(0) +fbuf.ellipse(15, 15, 6, 12, 0xAA, True) +printbuf() + +# Outline and fill some different quadrant combos. +for m in (0, 0b0001, 0b0010, 0b0100, 0b1000, 0b1010): + fbuf.fill(0) + fbuf.ellipse(15, 15, 6, 12, 0xAA, False, m) + printbuf() + fbuf.fill(0) + fbuf.ellipse(15, 15, 6, 12, 0xAA, True, m) + printbuf() + +# Draw ellipses that will go out of bounds at each of the edges. +for x, y in ( + ( + 4, + 4, + ), + ( + 26, + 4, + ), + ( + 26, + 26, + ), + ( + 4, + 26, + ), +): + fbuf.fill(0) + fbuf.ellipse(x, y, 6, 12, 0xAA, False) + printbuf() + fbuf.fill(0) + fbuf.ellipse(x, y, 6, 12, 0xAA, True) + printbuf() diff --git a/tests/extmod/framebuf_ellipse.py.exp b/tests/extmod/framebuf_ellipse.py.exp new file mode 100644 index 000000000000..ae6ad1ee7e48 --- /dev/null +++ b/tests/extmod/framebuf_ellipse.py.exp @@ -0,0 +1,704 @@ +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000ffffffffffffffffff00000000000000000000 +0000000000000000ffffff000000000000000000ffffff00000000000000 +000000000000ffff000000000000000000000000000000ffff0000000000 +0000000000ff00000000000000000000000000000000000000ff00000000 +00000000ff000000000000000000000000000000000000000000ff000000 +000000ff0000000000000000000000000000000000000000000000ff0000 +000000ff0000000000000000000000000000000000000000000000ff0000 +000000ff0000000000000000000000000000000000000000000000ff0000 +00000000ff000000000000000000000000000000000000000000ff000000 +0000000000ff00000000000000000000000000000000000000ff00000000 +000000000000ffff000000000000000000000000000000ffff0000000000 +0000000000000000ffffff000000000000000000ffffff00000000000000 +0000000000000000000000ffffffffffffffffff00000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000aaaaaa00000000000000000000000000 +00000000000000000000000000aaaaaaaaaa000000000000000000000000 +000000000000000000000000aaaaaaaaaaaaaa0000000000000000000000 +0000000000000000000000aaaaaaaaaaaaaaaaaa00000000000000000000 +0000000000000000000000aaaaaaaaaaaaaaaaaa00000000000000000000 +00000000000000000000aaaaaaaaaaaaaaaaaaaaaa000000000000000000 +00000000000000000000aaaaaaaaaaaaaaaaaaaaaa000000000000000000 +00000000000000000000aaaaaaaaaaaaaaaaaaaaaa000000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +00000000000000000000aaaaaaaaaaaaaaaaaaaaaa000000000000000000 +00000000000000000000aaaaaaaaaaaaaaaaaaaaaa000000000000000000 +00000000000000000000aaaaaaaaaaaaaaaaaaaaaa000000000000000000 +0000000000000000000000aaaaaaaaaaaaaaaaaa00000000000000000000 +0000000000000000000000aaaaaaaaaaaaaaaaaa00000000000000000000 +000000000000000000000000aaaaaaaaaaaaaa0000000000000000000000 +00000000000000000000000000aaaaaaaaaa000000000000000000000000 +0000000000000000000000000000aaaaaa00000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000aaaa00000000000000000000000000 +0000000000000000000000000000000000aa000000000000000000000000 +000000000000000000000000000000000000aa0000000000000000000000 +00000000000000000000000000000000000000aa00000000000000000000 +00000000000000000000000000000000000000aa00000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000aaaa00000000000000000000000000 +000000000000000000000000000000aaaaaa000000000000000000000000 +000000000000000000000000000000aaaaaaaa0000000000000000000000 +000000000000000000000000000000aaaaaaaaaa00000000000000000000 +000000000000000000000000000000aaaaaaaaaa00000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000aaaa0000000000000000000000000000 +00000000000000000000000000aa00000000000000000000000000000000 +000000000000000000000000aa0000000000000000000000000000000000 +0000000000000000000000aa000000000000000000000000000000000000 +0000000000000000000000aa000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000aaaa0000000000000000000000000000 +00000000000000000000000000aaaaaa0000000000000000000000000000 +000000000000000000000000aaaaaaaa0000000000000000000000000000 +0000000000000000000000aaaaaaaaaa0000000000000000000000000000 +0000000000000000000000aaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +0000000000000000000000aa000000000000000000000000000000000000 +0000000000000000000000aa000000000000000000000000000000000000 +000000000000000000000000aa0000000000000000000000000000000000 +00000000000000000000000000aa00000000000000000000000000000000 +0000000000000000000000000000aaaa0000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +0000000000000000000000aaaaaaaaaa0000000000000000000000000000 +0000000000000000000000aaaaaaaaaa0000000000000000000000000000 +000000000000000000000000aaaaaaaa0000000000000000000000000000 +00000000000000000000000000aaaaaa0000000000000000000000000000 +0000000000000000000000000000aaaa0000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +00000000000000000000000000000000000000aa00000000000000000000 +00000000000000000000000000000000000000aa00000000000000000000 +000000000000000000000000000000000000aa0000000000000000000000 +0000000000000000000000000000000000aa000000000000000000000000 +000000000000000000000000000000aaaa00000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaa00000000000000000000 +000000000000000000000000000000aaaaaaaaaa00000000000000000000 +000000000000000000000000000000aaaaaaaa0000000000000000000000 +000000000000000000000000000000aaaaaa000000000000000000000000 +000000000000000000000000000000aaaa00000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000aaaa0000000000000000000000000000 +00000000000000000000000000aa00000000000000000000000000000000 +000000000000000000000000aa0000000000000000000000000000000000 +0000000000000000000000aa000000000000000000000000000000000000 +0000000000000000000000aa000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +00000000000000000000000000000000000000aa00000000000000000000 +00000000000000000000000000000000000000aa00000000000000000000 +000000000000000000000000000000000000aa0000000000000000000000 +0000000000000000000000000000000000aa000000000000000000000000 +000000000000000000000000000000aaaa00000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000aaaa0000000000000000000000000000 +00000000000000000000000000aaaaaa0000000000000000000000000000 +000000000000000000000000aaaaaaaa0000000000000000000000000000 +0000000000000000000000aaaaaaaaaa0000000000000000000000000000 +0000000000000000000000aaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +00000000000000000000aaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaa0000000000000000000000000000 +000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaaaa0000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaaaa000000000000000000 +000000000000000000000000000000aaaaaaaaaa00000000000000000000 +000000000000000000000000000000aaaaaaaaaa00000000000000000000 +000000000000000000000000000000aaaaaaaa0000000000000000000000 +000000000000000000000000000000aaaaaa000000000000000000000000 +000000000000000000000000000000aaaa00000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +aa00000000000000aa000000000000000000000000000000000000000000 +aa00000000000000aa000000000000000000000000000000000000000000 +00aa0000000000aa00000000000000000000000000000000000000000000 +0000aa000000aa0000000000000000000000000000000000000000000000 +000000aaaaaa000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000 +00aaaaaaaaaaaaaa00000000000000000000000000000000000000000000 +0000aaaaaaaaaa0000000000000000000000000000000000000000000000 +000000aaaaaa000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +00000000000000000000000000000000000000000000aa00000000000000 +00000000000000000000000000000000000000000000aa00000000000000 +0000000000000000000000000000000000000000000000aa0000000000aa +000000000000000000000000000000000000000000000000aa000000aa00 +00000000000000000000000000000000000000000000000000aaaaaa0000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaa +000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaa +000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaa +00000000000000000000000000000000000000000000aaaaaaaaaaaaaaaa +00000000000000000000000000000000000000000000aaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000000000aaaaaaaaaaaaaa +000000000000000000000000000000000000000000000000aaaaaaaaaa00 +00000000000000000000000000000000000000000000000000aaaaaa0000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000aaaaaa0000 +000000000000000000000000000000000000000000000000aa000000aa00 +0000000000000000000000000000000000000000000000aa0000000000aa +00000000000000000000000000000000000000000000aa00000000000000 +00000000000000000000000000000000000000000000aa00000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +000000000000000000000000000000000000000000aa0000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +0000000000000000000000000000000000000000aa000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000aaaaaa0000 +000000000000000000000000000000000000000000000000aaaaaaaaaa00 +0000000000000000000000000000000000000000000000aaaaaaaaaaaaaa +00000000000000000000000000000000000000000000aaaaaaaaaaaaaaaa +00000000000000000000000000000000000000000000aaaaaaaaaaaaaaaa +000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaa +000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaa +000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +0000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaa +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000aaaaaa000000000000000000000000000000000000000000000000 +0000aa000000aa0000000000000000000000000000000000000000000000 +00aa0000000000aa00000000000000000000000000000000000000000000 +aa00000000000000aa000000000000000000000000000000000000000000 +aa00000000000000aa000000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +000000000000000000aa0000000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +00000000000000000000aa00000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000aaaaaa000000000000000000000000000000000000000000000000 +0000aaaaaaaaaa0000000000000000000000000000000000000000000000 +00aaaaaaaaaaaaaa00000000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaa000000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000 +-->8-- From 04a655c74488128a2c1af9ba8f29fce5e5bbfef9 Mon Sep 17 00:00:00 2001 From: Mat Booth Date: Wed, 13 Jul 2022 21:09:51 +0100 Subject: [PATCH 1623/4290] extmod/modframebuf: Add polygon drawing methods. Add method for drawing polygons. For non-filled polygons, uses the existing line-drawing code to render arbitrary polygons using the given coords list, at the given x,y position, in the given colour. For filled polygons, arbitrary closed polygons are rendered using a fast point-in-polygon algorithm to determine where the edges of the polygon lie on each pixel row. Tests and documentation updates are also included. Signed-off-by: Mat Booth --- docs/library/framebuf.rst | 15 +- extmod/modframebuf.c | 114 ++++++ tests/extmod/framebuf_polygon.py | 222 ++++++++++ tests/extmod/framebuf_polygon.py.exp | 582 +++++++++++++++++++++++++++ 4 files changed, 931 insertions(+), 2 deletions(-) create mode 100644 tests/extmod/framebuf_polygon.py create mode 100644 tests/extmod/framebuf_polygon.py.exp diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index 1e23abd0f1b5..78ae0c1c346b 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -11,8 +11,8 @@ class FrameBuffer ----------------- The FrameBuffer class provides a pixel buffer which can be drawn upon with -pixels, lines, rectangles, ellipses, text and even other FrameBuffers. It is -useful when generating output for displays. +pixels, lines, rectangles, ellipses, polygons, text and even other +FrameBuffers. It is useful when generating output for displays. For example:: @@ -98,6 +98,17 @@ The following methods draw shapes onto the FrameBuffer. to be drawn, with bit 0 specifying Q1, b1 Q2, b2 Q3 and b3 Q4. Quadrants are numbered counterclockwise with Q1 being top right. +.. method:: FrameBuffer.poly(x, y, coords, c[, f]) + + Given a list of coordinates, draw an arbitrary (convex or concave) closed + polygon at the given x, y location using the given color. + + The *coords* must be specified as a :mod:`array` of integers, e.g. + ``array('h', [x0, y0, x1, y1, ... xn, yn])``. + + The optional *f* parameter can be set to ``True`` to fill the polygon. + Otherwise just a one pixel outline is drawn. + Drawing text ------------ diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 0fa91942c1a7..f17bea70b967 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -28,6 +28,7 @@ #include #include "py/runtime.h" +#include "py/binary.h" #if MICROPY_PY_FRAMEBUF @@ -563,6 +564,116 @@ STATIC mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_ellipse_obj, 6, 8, framebuf_ellipse); +#if MICROPY_PY_ARRAY && !MICROPY_ENABLE_DYNRUNTIME +// TODO: poly needs mp_binary_get_size & mp_binary_get_val_array which aren't +// available in dynruntime.h yet. + +STATIC mp_int_t poly_int(mp_buffer_info_t *bufinfo, size_t index) { + return mp_obj_get_int(mp_binary_get_val_array(bufinfo->typecode, bufinfo->buf, index)); +} + +STATIC mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + + mp_int_t x = mp_obj_get_int(args_in[1]); + mp_int_t y = mp_obj_get_int(args_in[2]); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args_in[3], &bufinfo, MP_BUFFER_READ); + // If an odd number of values was given, this rounds down to multiple of two. + int n_poly = bufinfo.len / (mp_binary_get_size('@', bufinfo.typecode, NULL) * 2); + + if (n_poly == 0) { + return mp_const_none; + } + + mp_int_t col = mp_obj_get_int(args_in[4]); + bool fill = n_args > 5 && mp_obj_is_true(args_in[5]); + + if (fill) { + // This implements an integer version of http://alienryderflex.com/polygon_fill/ + + // The idea is for each scan line, compute the sorted list of x + // coordinates where the scan line intersects the polygon edges, + // then fill between each resulting pair. + + // Restrict just to the scan lines that include the vertical extent of + // this polygon. + mp_int_t y_min = INT_MAX, y_max = INT_MIN; + for (int i = 0; i < n_poly; i++) { + mp_int_t py = poly_int(&bufinfo, i * 2 + 1); + y_min = MIN(y_min, py); + y_max = MAX(y_max, py); + } + + for (mp_int_t row = y_min; row <= y_max; row++) { + // Each node is the x coordinate where an edge crosses this scan line. + mp_int_t nodes[n_poly]; + int n_nodes = 0; + mp_int_t px1 = poly_int(&bufinfo, 0); + mp_int_t py1 = poly_int(&bufinfo, 1); + int i = n_poly * 2 - 1; + do { + mp_int_t py2 = poly_int(&bufinfo, i--); + mp_int_t px2 = poly_int(&bufinfo, i--); + + // Don't include the bottom pixel of a given edge to avoid + // duplicating the node with the start of the next edge. This + // will miss some pixels on the boundary, but we get them at + // the end when we unconditionally draw the outline. + if (py1 != py2 && ((py1 > row && py2 <= row) || (py1 <= row && py2 > row))) { + mp_int_t node = (32 * px1 + 32 * (px2 - px1) * (row - py1) / (py2 - py1) + 16) / 32; + nodes[n_nodes++] = node; + } + + px1 = px2; + py1 = py2; + } while (i >= 0); + + if (!n_nodes) { + continue; + } + + // Sort the nodes left-to-right (bubble-sort for code size). + i = 0; + while (i < n_nodes - 1) { + if (nodes[i] > nodes[i + 1]) { + mp_int_t swap = nodes[i]; + nodes[i] = nodes[i + 1]; + nodes[i + 1] = swap; + if (i) { + i--; + } + } else { + i++; + } + } + + // Fill between each pair of nodes. + for (i = 0; i < n_nodes; i += 2) { + fill_rect(self, x + nodes[i], y + row, (nodes[i + 1] - nodes[i]) + 1, 1, col); + } + } + } + + // Always draw the outline (either because fill=False, or to fix the + // boundary pixels for a fill, see above). + mp_int_t px1 = poly_int(&bufinfo, 0); + mp_int_t py1 = poly_int(&bufinfo, 1); + int i = n_poly * 2 - 1; + do { + mp_int_t py2 = poly_int(&bufinfo, i--); + mp_int_t px2 = poly_int(&bufinfo, i--); + line(self, x + px1, y + py1, x + px2, y + py2, col); + px1 = px2; + py1 = py2; + } while (i >= 0); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_poly_obj, 5, 6, framebuf_poly); +#endif // MICROPY_PY_ARRAY && !MICROPY_ENABLE_DYNRUNTIME + STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); mp_obj_t source_in = mp_obj_cast_to_native_base(args_in[1], MP_OBJ_FROM_PTR(&mp_type_framebuf)); @@ -698,6 +809,9 @@ STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&framebuf_rect_obj) }, { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&framebuf_line_obj) }, { MP_ROM_QSTR(MP_QSTR_ellipse), MP_ROM_PTR(&framebuf_ellipse_obj) }, + #if MICROPY_PY_ARRAY + { MP_ROM_QSTR(MP_QSTR_poly), MP_ROM_PTR(&framebuf_poly_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&framebuf_blit_obj) }, { MP_ROM_QSTR(MP_QSTR_scroll), MP_ROM_PTR(&framebuf_scroll_obj) }, { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&framebuf_text_obj) }, diff --git a/tests/extmod/framebuf_polygon.py b/tests/extmod/framebuf_polygon.py new file mode 100644 index 000000000000..03130b3bf0fa --- /dev/null +++ b/tests/extmod/framebuf_polygon.py @@ -0,0 +1,222 @@ +import sys + +try: + import framebuf + from array import array +except ImportError: + print("SKIP") + raise SystemExit + + +# TODO: poly needs functions that aren't in dynruntime.h yet. +if not hasattr(framebuf.FrameBuffer, "poly"): + print("SKIP") + raise SystemExit + + +def print_buffer(buffer, width, height): + for row in range(height): + for col in range(width): + val = buffer[(row * width) + col] + sys.stdout.write(" {:02x}".format(val) if val else " ··") + sys.stdout.write("\n") + + +buf = bytearray(70 * 70) + +w = 30 +h = 25 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) +col = 0xFF +col_fill = 0x99 + +# This describes a arbitrary polygon (this happens to be a concave polygon in +# the shape of an upper-case letter 'M'). +poly = array( + "h", + ( + 0, + 20, + 3, + 20, + 3, + 10, + 6, + 17, + 9, + 10, + 9, + 20, + 12, + 20, + 12, + 3, + 9, + 3, + 6, + 10, + 3, + 3, + 0, + 3, + ), +) +# This describes the same polygon, but the points are in reverse order +# (it shouldn't matter if the polygon has clockwise or anti-clockwise +# winding). Also defined as a bytes instead of array. +poly_reversed = bytes( + ( + 0, + 3, + 3, + 3, + 6, + 10, + 9, + 3, + 12, + 3, + 12, + 20, + 9, + 20, + 9, + 10, + 6, + 17, + 3, + 10, + 3, + 20, + 0, + 20, + ) +) + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col) +fbuf.poly(15, -2, poly_reversed, col) +print_buffer(buf, w, h) +print() + +# Same but filled. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col_fill, True) +fbuf.poly(15, -2, poly_reversed, col_fill, True) +print_buffer(buf, w, h) +print() + +# Draw the fill then the outline to ensure that no fill goes outside the outline. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col_fill, True) +fbuf.poly(0, 0, poly, col) +fbuf.poly(15, -2, poly, col_fill, True) +fbuf.poly(15, -2, poly, col) +print_buffer(buf, w, h) +print() + +# Draw the outline then the fill to ensure the fill completely covers the outline. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col) +fbuf.poly(0, 0, poly, col_fill, True) +fbuf.poly(15, -2, poly, col) +fbuf.poly(15, -2, poly, col_fill, True) +print_buffer(buf, w, h) +print() + +# Draw polygons that will go out of bounds at each of the edges. +for x, y in ( + ( + -8, + -8, + ), + ( + 24, + -6, + ), + ( + 20, + 12, + ), + ( + -2, + 10, + ), +): + fbuf.fill(0) + fbuf.poly(x, y, poly, col) + print_buffer(buf, w, h) + print() + fbuf.fill(0) + fbuf.poly(x, y, poly_reversed, col, True) + print_buffer(buf, w, h) + print() + +# Edge cases: These two lists describe self-intersecting polygons +poly_hourglass = array("h", (0, 0, 9, 0, 0, 19, 9, 19)) +poly_star = array("h", (7, 0, 3, 18, 14, 5, 0, 5, 11, 18)) + +# As before, fill then outline. +fbuf.fill(0) +fbuf.poly(0, 2, poly_hourglass, col_fill, True) +fbuf.poly(0, 2, poly_hourglass, col) +fbuf.poly(12, 2, poly_star, col_fill, True) +fbuf.poly(12, 2, poly_star, col) +print_buffer(buf, w, h) +print() + +# Outline then fill. +fbuf.fill(0) +fbuf.poly(0, 2, poly_hourglass, col) +fbuf.poly(0, 2, poly_hourglass, col_fill, True) +fbuf.poly(12, 2, poly_star, col) +fbuf.poly(12, 2, poly_star, col_fill, True) +print_buffer(buf, w, h) +print() + +# Edge cases: These are "degenerate" polygons. +poly_empty = array("h") # Will draw nothing at all. +poly_one = array("h", (20, 20)) # Will draw a single point. +poly_two = array("h", (10, 10, 5, 5)) # Will draw a single line. +poly_wrong_length = array("h", (2, 2, 4)) # Will round down to one point. + +fbuf.fill(0) +fbuf.poly(0, 0, poly_empty, col) +fbuf.poly(0, 0, poly_one, col) +fbuf.poly(0, 0, poly_two, col) +fbuf.poly(0, 0, poly_wrong_length, col) +print_buffer(buf, w, h) +print() + +# A shape with a horizontal overhang. +poly_overhang = array("h", (0, 0, 0, 5, 5, 5, 5, 10, 10, 10, 10, 0)) + +fbuf.fill(0) +fbuf.poly(0, 0, poly_overhang, col) +fbuf.poly(0, 0, poly_overhang, col_fill, True) +print_buffer(buf, w, h) +print() + +fbuf.fill(0) +fbuf.poly(0, 0, poly_overhang, col_fill, True) +fbuf.poly(0, 0, poly_overhang, col) +print_buffer(buf, w, h) +print() + +# Triangles +w = 70 +h = 70 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) +t1 = array("h", [40, 0, 20, 68, 62, 40]) +t2 = array("h", [40, 0, 0, 16, 20, 68]) + +fbuf.fill(0) +fbuf.poly(0, 0, t1, 0xFF, False) +fbuf.poly(0, 0, t2, 0xFF, False) +print_buffer(buf, w, h) + +fbuf.fill(0) +fbuf.poly(0, 0, t1, 0xFF, True) +fbuf.poly(0, 0, t2, 0xFF, True) +print_buffer(buf, w, h) diff --git a/tests/extmod/framebuf_polygon.py.exp b/tests/extmod/framebuf_polygon.py.exp new file mode 100644 index 000000000000..05cd4264ea8b --- /dev/null +++ b/tests/extmod/framebuf_polygon.py.exp @@ -0,0 +1,582 @@ + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· + ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ff ·· ff ·· ·· ·· ·· ff ·· ·· + ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ff ·· ff ·· ·· ·· ·· ff ·· ·· + ff ·· ·· ·· ·· ff ·· ff ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· + ff ·· ·· ·· ·· ff ·· ff ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ff ·· ·· ·· ff ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ff ·· ·· ·· ff ff ·· ·· ff ·· ·· + ff ·· ·· ff ff ·· ·· ·· ff ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ff ·· ff ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ff ·· ·· ·· ff ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ff ·· ff ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ff ·· ff ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ff ·· ff ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· + 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ff 99 99 99 ff ·· ·· ·· ff 99 99 99 ff ·· ·· + ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ff 99 99 99 ff ·· ·· ·· ff 99 99 99 ff ·· ·· + ff 99 99 99 ff ·· ·· ·· ff 99 99 99 ff ·· ·· ff 99 99 99 99 ff ·· ff 99 99 99 99 ff ·· ·· + ff 99 99 99 ff ·· ·· ·· ff 99 99 99 ff ·· ·· ff 99 99 99 99 ff ·· ff 99 99 99 99 ff ·· ·· + ff 99 99 99 99 ff ·· ff 99 99 99 99 ff ·· ·· ff 99 99 99 99 99 ff 99 99 99 99 99 ff ·· ·· + ff 99 99 99 99 ff ·· ff 99 99 99 99 ff ·· ·· ff 99 99 ff 99 99 ff 99 99 ff 99 99 ff ·· ·· + ff 99 99 99 99 99 ff 99 99 99 99 99 ff ·· ·· ff 99 99 ff 99 99 99 99 99 ff 99 99 ff ·· ·· + ff 99 99 ff 99 99 ff 99 99 ff 99 99 ff ·· ·· ff 99 99 ff ff 99 99 99 ff ff 99 99 ff ·· ·· + ff 99 99 ff 99 99 99 99 99 ff 99 99 ff ·· ·· ff 99 99 ff ff 99 99 99 ff ff 99 99 ff ·· ·· + ff 99 99 ff ff 99 99 99 ff ff 99 99 ff ·· ·· ff 99 99 ff ·· ff 99 ff ·· ff 99 99 ff ·· ·· + ff 99 99 ff ff 99 99 99 ff ff 99 99 ff ·· ·· ff 99 99 ff ·· ff 99 ff ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ff 99 ff ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ff ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ff 99 ff ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ff ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ·· ff ·· ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ·· ff ·· ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· + 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 ·· ·· ·· 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· 99 99 99 ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· 99 ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ff ·· ·· ·· ff ff + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ·· ·· ·· ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ·· ·· ·· ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ·· ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ·· ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ·· ff ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ·· ff ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ·· ·· ·· ff ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ·· ·· ·· ff ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ff ·· ff ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ·· ·· ·· ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ·· ·· ·· ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ·· ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ·· ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ff ff ff ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· + ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ff 99 99 99 99 ff ·· ·· ·· ·· + ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ·· ·· ff 99 ff ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ·· ·· ff 99 ff ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ff 99 ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 99 ff 99 99 ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ff 99 ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ff 99 ff ·· ff 99 ff ·· ·· ·· ·· ·· ·· ·· + ·· ff 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ff 99 ff ·· ·· ·· ff 99 ff ·· ·· ·· ·· ·· ·· + ·· ff 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· + ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· 99 99 99 99 99 99 ·· 99 99 99 99 99 99 ·· ·· ·· ·· + ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· 99 99 99 99 ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· + ·· ·· ·· ·· 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· ·· ·· 99 99 99 ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· ·· ·· 99 99 99 ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 ·· ·· ·· 99 99 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 ·· ·· ·· 99 ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· 99 99 99 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· + ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· 99 99 99 ·· ·· ·· ·· ·· ·· ·· + ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· 99 99 99 ·· 99 99 99 ·· ·· ·· ·· ·· ·· ·· + ·· 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· 99 99 99 ·· ·· ·· 99 99 99 ·· ·· ·· ·· ·· ·· + ·· 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· 99 99 ·· ·· ·· ·· ·· 99 99 ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· 99 ·· ·· ·· ·· ·· ·· ·· 99 ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 99 99 99 99 99 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 99 99 99 99 99 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ff ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ff ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ff ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· From c616721b1afe176c8d760afc15a93621d411c1dc Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 15 Aug 2022 09:56:26 +1000 Subject: [PATCH 1624/4290] extmod/modframebuf: Improve poly-fill boundary pixels. Rather than drawing the entire boundary to catch missing pixels, just detect the cases where boundary pixels are skipped during node calculation and pre-emptively draw them then. This adds 72 bytes on PYBV11, but makes filled poly() 20% faster. Signed-off-by: Jim Mussared --- extmod/modframebuf.c | 65 ++++++++++++++++------------ tests/extmod/framebuf_polygon.py.exp | 32 +++++++------- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index f17bea70b967..bb1f4f631077 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -241,11 +241,17 @@ STATIC mp_framebuf_p_t formats[] = { [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect}, }; -static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { +STATIC inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { formats[fb->format].setpixel(fb, x, y, col); } -static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { +STATIC void setpixel_checked(const mp_obj_framebuf_t *fb, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask) { + if (mask && 0 <= x && x < fb->width && 0 <= y && y < fb->height) { + setpixel(fb, x, y, col); + } +} + +STATIC inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { return formats[fb->format].getpixel(fb, x, y); } @@ -470,12 +476,6 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line); -STATIC void ellipse_pixel(const mp_obj_framebuf_t *fb, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask) { - if (mask && 0 <= x && x < fb->width && 0 <= y && y < fb->height) { - setpixel(fb, x, y, col); - } -} - // Q2 Q1 // Q3 Q4 #define ELLIPSE_MASK_FILL (0x10) @@ -500,10 +500,10 @@ STATIC void draw_ellipse_points(const mp_obj_framebuf_t *fb, mp_int_t cx, mp_int fill_rect(fb, cx, cy + y, x + 1, 1, col); } } else { - ellipse_pixel(fb, cx + x, cy - y, col, mask & ELLIPSE_MASK_Q1); - ellipse_pixel(fb, cx - x, cy - y, col, mask & ELLIPSE_MASK_Q2); - ellipse_pixel(fb, cx - x, cy + y, col, mask & ELLIPSE_MASK_Q3); - ellipse_pixel(fb, cx + x, cy + y, col, mask & ELLIPSE_MASK_Q4); + setpixel_checked(fb, cx + x, cy - y, col, mask & ELLIPSE_MASK_Q1); + setpixel_checked(fb, cx - x, cy - y, col, mask & ELLIPSE_MASK_Q2); + setpixel_checked(fb, cx - x, cy + y, col, mask & ELLIPSE_MASK_Q3); + setpixel_checked(fb, cx + x, cy + y, col, mask & ELLIPSE_MASK_Q4); } } @@ -619,11 +619,23 @@ STATIC mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { // Don't include the bottom pixel of a given edge to avoid // duplicating the node with the start of the next edge. This - // will miss some pixels on the boundary, but we get them at - // the end when we unconditionally draw the outline. + // will miss some pixels on the boundary, and in particular + // at a local minima or inflection point. if (py1 != py2 && ((py1 > row && py2 <= row) || (py1 <= row && py2 > row))) { mp_int_t node = (32 * px1 + 32 * (px2 - px1) * (row - py1) / (py2 - py1) + 16) / 32; nodes[n_nodes++] = node; + } else if (row == MAX(py1, py2)) { + // At local-minima, try and manually fill in the pixels that get missed above. + if (py1 < py2) { + setpixel_checked(self, x + px2, y + py2, col, 1); + } else if (py2 < py1) { + setpixel_checked(self, x + px1, y + py1, col, 1); + } else { + // Even though this is a hline and would be faster to + // use fill_rect, use line() because it handles x2 < + // x1. + line(self, x + px1, y + py1, x + px2, y + py2, col); + } } px1 = px2; @@ -654,21 +666,20 @@ STATIC mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { fill_rect(self, x + nodes[i], y + row, (nodes[i + 1] - nodes[i]) + 1, 1, col); } } + } else { + // Outline only. + mp_int_t px1 = poly_int(&bufinfo, 0); + mp_int_t py1 = poly_int(&bufinfo, 1); + int i = n_poly * 2 - 1; + do { + mp_int_t py2 = poly_int(&bufinfo, i--); + mp_int_t px2 = poly_int(&bufinfo, i--); + line(self, x + px1, y + py1, x + px2, y + py2, col); + px1 = px2; + py1 = py2; + } while (i >= 0); } - // Always draw the outline (either because fill=False, or to fix the - // boundary pixels for a fill, see above). - mp_int_t px1 = poly_int(&bufinfo, 0); - mp_int_t py1 = poly_int(&bufinfo, 1); - int i = n_poly * 2 - 1; - do { - mp_int_t py2 = poly_int(&bufinfo, i--); - mp_int_t px2 = poly_int(&bufinfo, i--); - line(self, x + px1, y + py1, x + px2, y + py2, col); - px1 = px2; - py1 = py2; - } while (i >= 0); - return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_poly_obj, 5, 6, framebuf_poly); diff --git a/tests/extmod/framebuf_polygon.py.exp b/tests/extmod/framebuf_polygon.py.exp index 05cd4264ea8b..9b4801c788a5 100644 --- a/tests/extmod/framebuf_polygon.py.exp +++ b/tests/extmod/framebuf_polygon.py.exp @@ -510,22 +510,22 @@ ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· - ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· From af54d2ce9f923eba06b19bddb784a1c9da228347 Mon Sep 17 00:00:00 2001 From: "Nicholas H.Tollervey" Date: Fri, 19 Aug 2022 14:58:58 +0100 Subject: [PATCH 1625/4290] javascript: Rename this port to 'webassembly'. --- ...ports_javascript.yml => ports_webassembly.yml} | 10 +++++----- ports/{javascript => webassembly}/Makefile | 2 +- ports/{javascript => webassembly}/README.md | 15 ++++++++++----- ports/{javascript => webassembly}/library.h | 0 ports/{javascript => webassembly}/library.js | 0 ports/{javascript => webassembly}/main.c | 0 ports/{javascript => webassembly}/modutime.c | 0 ports/{javascript => webassembly}/mpconfigport.h | 2 +- ports/{javascript => webassembly}/mphalport.c | 0 ports/{javascript => webassembly}/mphalport.h | 0 ports/{javascript => webassembly}/node_run.sh | 0 ports/{javascript => webassembly}/qstrdefsport.h | 0 ports/{javascript => webassembly}/wrapper.js | 0 tools/ci.sh | 12 ++++++------ 14 files changed, 23 insertions(+), 18 deletions(-) rename .github/workflows/{ports_javascript.yml => ports_webassembly.yml} (57%) rename ports/{javascript => webassembly}/Makefile (93%) rename ports/{javascript => webassembly}/README.md (84%) rename ports/{javascript => webassembly}/library.h (100%) rename ports/{javascript => webassembly}/library.js (100%) rename ports/{javascript => webassembly}/main.c (100%) rename ports/{javascript => webassembly}/modutime.c (100%) rename ports/{javascript => webassembly}/mpconfigport.h (99%) rename ports/{javascript => webassembly}/mphalport.c (100%) rename ports/{javascript => webassembly}/mphalport.h (100%) rename ports/{javascript => webassembly}/node_run.sh (100%) rename ports/{javascript => webassembly}/qstrdefsport.h (100%) rename ports/{javascript => webassembly}/wrapper.js (100%) diff --git a/.github/workflows/ports_javascript.yml b/.github/workflows/ports_webassembly.yml similarity index 57% rename from .github/workflows/ports_javascript.yml rename to .github/workflows/ports_webassembly.yml index 244dc966aa6d..861039c0fcff 100644 --- a/.github/workflows/ports_javascript.yml +++ b/.github/workflows/ports_webassembly.yml @@ -1,4 +1,4 @@ -name: javascript port +name: webassembly port on: push: @@ -9,7 +9,7 @@ on: - 'py/**' - 'extmod/**' - 'lib/**' - - 'ports/javascript/**' + - 'ports/webassembly/**' jobs: build: @@ -17,8 +17,8 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install packages - run: source tools/ci.sh && ci_javascript_setup + run: source tools/ci.sh && ci_webassembly_setup - name: Build - run: source tools/ci.sh && ci_javascript_build + run: source tools/ci.sh && ci_webassembly_build - name: Run tests - run: source tools/ci.sh && ci_javascript_run_tests + run: source tools/ci.sh && ci_webassembly_run_tests diff --git a/ports/javascript/Makefile b/ports/webassembly/Makefile similarity index 93% rename from ports/javascript/Makefile rename to ports/webassembly/Makefile index 93c7b5609b23..db3f36ad8eb1 100644 --- a/ports/javascript/Makefile +++ b/ports/webassembly/Makefile @@ -51,6 +51,6 @@ min: $(BUILD)/micropython.js test: $(BUILD)/micropython.js $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../ports/javascript/node_run.sh ./run-tests.py -j1 + cd $(TOP)/tests && MICROPY_MICROPYTHON=../ports/webassembly/node_run.sh ./run-tests.py -j1 include $(TOP)/py/mkrules.mk diff --git a/ports/javascript/README.md b/ports/webassembly/README.md similarity index 84% rename from ports/javascript/README.md rename to ports/webassembly/README.md index 39808943b104..3b577233fffe 100644 --- a/ports/javascript/README.md +++ b/ports/webassembly/README.md @@ -1,13 +1,18 @@ -MicroPython.js -============== +MicroPython WebAssembly +======================= -MicroPython transmuted into Javascript by Emscripten. +MicroPython for [WebAssembly](https://webassembly.org/). Dependencies ------------ -Building micropython.js bears the same requirements as the standard MicroPython -ports with the addition of Emscripten (and uglify-js for the minified file). +Building webassembly port bears the same requirements as the standard +MicroPython ports with the addition of Emscripten (and uglify-js for the +minified file). + +The output includes `micropython.js` (a JavaScript wrapper for the +MicroPython runtime) and `firmware.wasm` (actual MicroPython compiled to +WASM). Build instructions ------------------ diff --git a/ports/javascript/library.h b/ports/webassembly/library.h similarity index 100% rename from ports/javascript/library.h rename to ports/webassembly/library.h diff --git a/ports/javascript/library.js b/ports/webassembly/library.js similarity index 100% rename from ports/javascript/library.js rename to ports/webassembly/library.js diff --git a/ports/javascript/main.c b/ports/webassembly/main.c similarity index 100% rename from ports/javascript/main.c rename to ports/webassembly/main.c diff --git a/ports/javascript/modutime.c b/ports/webassembly/modutime.c similarity index 100% rename from ports/javascript/modutime.c rename to ports/webassembly/modutime.c diff --git a/ports/javascript/mpconfigport.h b/ports/webassembly/mpconfigport.h similarity index 99% rename from ports/javascript/mpconfigport.h rename to ports/webassembly/mpconfigport.h index 6c86d816bd4f..4fbd922e1564 100644 --- a/ports/javascript/mpconfigport.h +++ b/ports/webassembly/mpconfigport.h @@ -105,7 +105,7 @@ #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) -#define MICROPY_PY_SYS_PLATFORM "javascript" +#define MICROPY_PY_SYS_PLATFORM "webassembly" #define MICROPY_PY_UERRNO (1) #define MICROPY_PY_UCTYPES (1) #define MICROPY_PY_UZLIB (1) diff --git a/ports/javascript/mphalport.c b/ports/webassembly/mphalport.c similarity index 100% rename from ports/javascript/mphalport.c rename to ports/webassembly/mphalport.c diff --git a/ports/javascript/mphalport.h b/ports/webassembly/mphalport.h similarity index 100% rename from ports/javascript/mphalport.h rename to ports/webassembly/mphalport.h diff --git a/ports/javascript/node_run.sh b/ports/webassembly/node_run.sh similarity index 100% rename from ports/javascript/node_run.sh rename to ports/webassembly/node_run.sh diff --git a/ports/javascript/qstrdefsport.h b/ports/webassembly/qstrdefsport.h similarity index 100% rename from ports/javascript/qstrdefsport.h rename to ports/webassembly/qstrdefsport.h diff --git a/ports/javascript/wrapper.js b/ports/webassembly/wrapper.js similarity index 100% rename from ports/javascript/wrapper.js rename to ports/webassembly/wrapper.js diff --git a/tools/ci.sh b/tools/ci.sh index e3203f8bfb9f..dc2ccf775b15 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -172,21 +172,21 @@ function ci_esp8266_build { } ######################################################################################## -# ports/javascript +# ports/webassembly -function ci_javascript_setup { +function ci_webassembly_setup { git clone https://github.com/emscripten-core/emsdk.git (cd emsdk && ./emsdk install latest && ./emsdk activate latest) } -function ci_javascript_build { +function ci_webassembly_build { source emsdk/emsdk_env.sh - make ${MAKEOPTS} -C ports/javascript + make ${MAKEOPTS} -C ports/webassembly } -function ci_javascript_run_tests { +function ci_webassembly_run_tests { # This port is very slow at running, so only run a few of the tests. - (cd tests && MICROPY_MICROPYTHON=../ports/javascript/node_run.sh ./run-tests.py -j1 basics/builtin_*.py) + (cd tests && MICROPY_MICROPYTHON=../ports/webassembly/node_run.sh ./run-tests.py -j1 basics/builtin_*.py) } ######################################################################################## From 7c8ec85fa34279950e44072b22ac26fe41b91886 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 23 Aug 2022 13:02:40 +1000 Subject: [PATCH 1626/4290] shared/runtime/sys_stdio_mphal: Make func static and remove some TODOs. stdio_obj_print is private to this file so can be made static. The __del__ method does nothing so can be removed (it's only called by the GC if it exists, so if it doesn't exist it won't be called). And FileIO doesn't support a constructor in MicroPython at this stage. Signed-off-by: Damien George --- shared/runtime/sys_stdio_mphal.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/shared/runtime/sys_stdio_mphal.c b/shared/runtime/sys_stdio_mphal.c index e72facb981d9..24f528b0c4f8 100644 --- a/shared/runtime/sys_stdio_mphal.c +++ b/shared/runtime/sys_stdio_mphal.c @@ -52,7 +52,7 @@ typedef struct _sys_stdio_obj_t { STATIC const sys_stdio_obj_t stdio_buffer_obj; #endif -void stdio_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void stdio_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { sys_stdio_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "", self->fd); } @@ -100,8 +100,6 @@ STATIC mp_obj_t stdio_obj___exit__(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stdio_obj___exit___obj, 4, 4, stdio_obj___exit__); -// TODO gc hook to close the file if not already closed - STATIC const mp_rom_map_elem_t stdio_locals_dict_table[] = { #if MICROPY_PY_SYS_STDIO_BUFFER { MP_ROM_QSTR(MP_QSTR_buffer), MP_ROM_PTR(&stdio_buffer_obj) }, @@ -112,7 +110,6 @@ STATIC const mp_rom_map_elem_t stdio_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)}, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_identity_obj) }, - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_identity_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&stdio_obj___exit___obj) }, }; @@ -129,7 +126,6 @@ STATIC const mp_stream_p_t stdio_obj_stream_p = { STATIC const mp_obj_type_t stdio_obj_type = { { &mp_type_type }, .name = MP_QSTR_FileIO, - // TODO .make_new? .print = stdio_obj_print, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, From 3d65101a8a55550bdbaa4df4e216edba238fa299 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 23 Aug 2022 13:09:57 +1000 Subject: [PATCH 1627/4290] py: Clean up formatting of union definitions. Signed-off-by: Damien George --- py/binary.c | 22 +++++++++++++--------- py/obj.h | 8 +++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/py/binary.c b/py/binary.c index f59e89ca4822..4c8b6ffcdc49 100644 --- a/py/binary.c +++ b/py/binary.c @@ -241,13 +241,15 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte *p_base, byte * return mp_obj_new_str(s_val, strlen(s_val)); #if MICROPY_PY_BUILTINS_FLOAT } else if (val_type == 'f') { - union { uint32_t i; - float f; + union { + uint32_t i; + float f; } fpu = {val}; return mp_obj_new_float_from_f(fpu.f); } else if (val_type == 'd') { - union { uint64_t i; - double f; + union { + uint64_t i; + double f; } fpu = {val}; return mp_obj_new_float_from_d(fpu.f); #endif @@ -308,17 +310,19 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte *p break; #if MICROPY_PY_BUILTINS_FLOAT case 'f': { - union { uint32_t i; - float f; + union { + uint32_t i; + float f; } fp_sp; fp_sp.f = mp_obj_get_float_to_f(val_in); val = fp_sp.i; break; } case 'd': { - union { uint64_t i64; - uint32_t i32[2]; - double f; + union { + uint64_t i64; + uint32_t i32[2]; + double f; } fp_dp; fp_dp.f = mp_obj_get_float_to_d(val_in); if (MP_BYTES_PER_OBJ_WORD == 8) { diff --git a/py/obj.h b/py/obj.h index 598d6508da73..645fae79f566 100644 --- a/py/obj.h +++ b/py/obj.h @@ -283,9 +283,11 @@ static inline bool mp_obj_is_obj(mp_const_obj_t o) { #define MP_OBJ_FROM_PTR(p) ((mp_obj_t)((uintptr_t)(p))) // rom object storage needs special handling to widen 32-bit pointer to 64-bits -typedef union _mp_rom_obj_t { uint64_t u64; - struct { const void *lo, *hi; - } u32; +typedef union _mp_rom_obj_t { + uint64_t u64; + struct { + const void *lo, *hi; + } u32; } mp_rom_obj_t; #define MP_ROM_INT(i) {MP_OBJ_NEW_SMALL_INT(i)} #define MP_ROM_QSTR(q) {MP_OBJ_NEW_QSTR(q)} From d8ad87843ab38dcc74e7e86354849fff585e1ba8 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Fri, 19 Aug 2022 16:40:28 +0200 Subject: [PATCH 1628/4290] py/builtinimport: Allow overriding of mp_builtin___import__. This allows ports to override mp_builtin___import__. This can be useful in MicroPython applications where MICROPY_ENABLE_EXTERNAL_IMPORT has to be disabled due to its impact on build size (2% to 2.5% of the minimal port). By overriding the otherwise very minimal mp_builtin___import__, ports can still allow limited forms of application-specific imports. Signed-off-by: Laurens Valk --- py/builtin.h | 6 ++++++ py/builtinimport.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/py/builtin.h b/py/builtin.h index fb1162784122..7232142b77be 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -64,7 +64,13 @@ MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj); #endif +// A port can provide its own import handler by defining mp_builtin___import__. +#ifndef mp_builtin___import__ +#define mp_builtin___import__ mp_builtin___import___default +#endif mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args); +mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args); + mp_obj_t mp_micropython_mem_info(size_t n_args, const mp_obj_t *args); MP_DECLARE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj); diff --git a/py/builtinimport.c b/py/builtinimport.c index 36cdac07675e..a578d4ad2732 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -467,7 +467,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, return module_obj; } -mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { +mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) { #if DEBUG_PRINT DEBUG_printf("__import__:\n"); for (size_t i = 0; i < n_args; i++) { @@ -566,7 +566,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #else // MICROPY_ENABLE_EXTERNAL_IMPORT -mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { +mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) { // Check that it's not a relative import if (n_args >= 5 && MP_OBJ_SMALL_INT_VALUE(args[4]) != 0) { mp_raise_NotImplementedError(MP_ERROR_TEXT("relative import")); From b1efc1340af122499e5cf1d7214d51e034d45a20 Mon Sep 17 00:00:00 2001 From: Chris Waggoner Date: Sun, 21 Aug 2022 06:57:12 -0400 Subject: [PATCH 1629/4290] mpy-cross,unix: Include alloca.h for NetBSD. --- mpy-cross/mpconfigport.h | 2 +- ports/unix/mpconfigport.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index 9d455c0af1f3..4304c552bc45 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -119,7 +119,7 @@ typedef long mp_off_t; #define MP_PLAT_PRINT_STRN(str, len) (void)0 // We need to provide a declaration/definition of alloca() -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) #include #elif defined(_WIN32) #include diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 03b8ceb1f6f9..dd73f61e24ba 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -294,7 +294,7 @@ static inline unsigned long mp_urandom_seed_init(void) { // We need to provide a declaration/definition of alloca() // unless support for it is disabled. #if !defined(MICROPY_NO_ALLOCA) || MICROPY_NO_ALLOCA == 0 -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) #include #else #include From 717924001d8da40032fd56aa3ba2207059f550d2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 3 Aug 2022 18:01:11 +0200 Subject: [PATCH 1630/4290] stm32: Switch Wiznet to use lib/wiznet5k and extmod/network_wiznet5k. Instead of the old Wiznet driver in drivers/wiznet5k. --- ports/stm32/Makefile | 17 +- ports/stm32/modnwwiznet5k.c | 513 --------------------------------- ports/stm32/network_wiznet5k.c | 465 ------------------------------ 3 files changed, 10 insertions(+), 985 deletions(-) delete mode 100644 ports/stm32/modnwwiznet5k.c delete mode 100644 ports/stm32/network_wiznet5k.c diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 14a93a5aa765..7c912f4f0b23 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -460,19 +460,22 @@ LIBS += $(TOP)/drivers/cyw43/libcyw43.a endif ifneq ($(MICROPY_PY_NETWORK_WIZNET5K),0) -WIZNET5K_DIR=drivers/wiznet5k -INC += -I$(TOP)/$(WIZNET5K_DIR) +WIZNET5K_DIR=lib/wiznet5k +GIT_SUBMODULES += lib/wiznet5k +INC += -I$(TOP)/$(WIZNET5K_DIR) -I$(TOP)/$(WIZNET5K_DIR)/Ethernet CFLAGS_MOD += -DMICROPY_PY_NETWORK_WIZNET5K=$(MICROPY_PY_NETWORK_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_NETWORK_WIZNET5K) +CFLAGS_MOD += -DWIZCHIP_PREFIXED_EXPORTS=1 ifeq ($(MICROPY_PY_LWIP),1) # When using MACRAW mode (with lwIP), maximum buffer space must be used for the raw socket CFLAGS_MOD += -DWIZCHIP_USE_MAX_BUFFER endif -SRC_MOD += network_wiznet5k.c modnwwiznet5k.c +SRC_MOD += extmod/network_wiznet5k.c SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ - ethernet/w$(MICROPY_PY_NETWORK_WIZNET5K)/w$(MICROPY_PY_NETWORK_WIZNET5K).c \ - ethernet/wizchip_conf.c \ - ethernet/socket.c \ - internet/dns/dns.c \ + Ethernet/W$(MICROPY_PY_NETWORK_WIZNET5K)/w$(MICROPY_PY_NETWORK_WIZNET5K).c \ + Ethernet/wizchip_conf.c \ + Ethernet/socket.c \ + Internet/DNS/dns.c \ + Internet/DHCP/dhcp.c \ ) endif diff --git a/ports/stm32/modnwwiznet5k.c b/ports/stm32/modnwwiznet5k.c deleted file mode 100644 index 2d5044d5246b..000000000000 --- a/ports/stm32/modnwwiznet5k.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - -#include "py/objlist.h" -#include "py/runtime.h" -#include "py/stream.h" -#include "py/mperrno.h" -#include "py/mphal.h" -#include "shared/netutils/netutils.h" -#include "extmod/modnetwork.h" -#include "pin.h" -#include "spi.h" - -#if MICROPY_PY_NETWORK_WIZNET5K && !MICROPY_PY_LWIP - -#include "ethernet/wizchip_conf.h" -#include "ethernet/socket.h" -#include "internet/dns/dns.h" - -/// \moduleref network - -typedef struct _wiznet5k_obj_t { - mp_obj_base_t base; - mp_uint_t cris_state; - const spi_t *spi; - const pin_obj_t *cs; - const pin_obj_t *rst; - uint8_t socket_used; -} wiznet5k_obj_t; - -STATIC wiznet5k_obj_t wiznet5k_obj; - -STATIC void wiz_cris_enter(void) { - wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); -} - -STATIC void wiz_cris_exit(void) { - MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); -} - -STATIC void wiz_cs_select(void) { - mp_hal_pin_low(wiznet5k_obj.cs); -} - -STATIC void wiz_cs_deselect(void) { - mp_hal_pin_high(wiznet5k_obj.cs); -} - -STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { - HAL_StatusTypeDef status = HAL_SPI_Receive(wiznet5k_obj.spi->spi, buf, len, 5000); - (void)status; -} - -STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { - HAL_StatusTypeDef status = HAL_SPI_Transmit(wiznet5k_obj.spi->spi, (uint8_t *)buf, len, 5000); - (void)status; -} - -STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { - uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; - uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); - DNS_init(0, buf); - mp_int_t ret = DNS_run(dns_ip, (uint8_t *)name, out_ip); - m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); - if (ret == 1) { - // success - return 0; - } else { - // failure - return -2; - } -} - -STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { - if (socket->domain != MOD_NETWORK_AF_INET) { - *_errno = MP_EAFNOSUPPORT; - return -1; - } - - switch (socket->type) { - case MOD_NETWORK_SOCK_STREAM: - socket->type = Sn_MR_TCP; - break; - case MOD_NETWORK_SOCK_DGRAM: - socket->type = Sn_MR_UDP; - break; - default: - *_errno = MP_EINVAL; - return -1; - } - - if (socket->fileno == -1) { - // get first unused socket number - for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { - if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { - wiznet5k_obj.socket_used |= (1 << sn); - socket->fileno = sn; - break; - } - } - if (socket->fileno == -1) { - // too many open sockets - *_errno = MP_EMFILE; - return -1; - } - } - - // WIZNET does not have a concept of pure "open socket". You need to know - // if it's a server or client at the time of creation of the socket. - // So, we defer the open until we know what kind of socket we want. - - // use "domain" to indicate that this socket has not yet been opened - socket->domain = 0; - - return 0; -} - -STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { - uint8_t sn = (uint8_t)socket->fileno; - if (sn < _WIZCHIP_SOCK_NUM_) { - wiznet5k_obj.socket_used &= ~(1 << sn); - WIZCHIP_EXPORT(close)(sn); - } -} - -STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - // open the socket in server mode (if port != 0) - mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->fileno, socket->type, port, 0); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - - // indicate that this socket has been opened - socket->domain = 1; - - // success - return 0; -} - -STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { - mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->fileno); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return 0; -} - -STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { - for (;;) { - int sr = getSn_SR((uint8_t)socket->fileno); - if (sr == SOCK_ESTABLISHED) { - socket2->domain = socket->domain; - socket2->type = socket->type; - socket2->fileno = socket->fileno; - getSn_DIPR((uint8_t)socket2->fileno, ip); - *port = getSn_PORT(socket2->fileno); - - // WIZnet turns the listening socket into the client socket, so we - // need to re-bind and re-listen on another socket for the server. - // TODO handle errors, especially no-more-sockets error - socket->domain = MOD_NETWORK_AF_INET; - socket->fileno = -1; - int _errno2; - if (wiznet5k_socket_socket(socket, &_errno2) != 0) { - // printf("(bad resocket %d)\n", _errno2); - } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { - // printf("(bad rebind %d)\n", _errno2); - } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { - // printf("(bad relisten %d)\n", _errno2); - } - - return 0; - } - if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { - wiznet5k_socket_close(socket); - *_errno = MP_ENOTCONN; // ?? - return -1; - } - mp_hal_delay_ms(1); - } -} - -STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - // use "bind" function to open the socket in client mode - if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { - return -1; - } - - // now connect - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->fileno, ip, port); - MP_THREAD_GIL_ENTER(); - - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - - // success - return 0; -} - -STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(send)(socket->fileno, (byte *)buf, len); - MP_THREAD_GIL_ENTER(); - - // TODO convert Wiz errno's to POSIX ones - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->fileno, buf, len); - MP_THREAD_GIL_ENTER(); - - // TODO convert Wiz errno's to POSIX ones - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { - if (socket->domain == 0) { - // socket not opened; use "bind" function to open the socket in client mode - if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { - return -1; - } - } - - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->fileno, (byte *)buf, len, ip, port); - MP_THREAD_GIL_ENTER(); - - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { - uint16_t port2; - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->fileno, buf, len, ip, &port2); - MP_THREAD_GIL_ENTER(); - *port = port2; - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; -} - -STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; - - /* - if (timeout_ms == 0) { - // set non-blocking mode - uint8_t arg = SOCK_IO_NONBLOCK; - WIZCHIP_EXPORT(ctlsocket)(socket->fileno, CS_SET_IOMODE, &arg); - } - */ -} - -STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { - if (request == MP_STREAM_POLL) { - int ret = 0; - if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->fileno) != 0) { - ret |= MP_STREAM_POLL_RD; - } - if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->fileno) != 0) { - ret |= MP_STREAM_POLL_WR; - } - return ret; - } else { - *_errno = MP_EINVAL; - return MP_STREAM_ERROR; - } -} - -#if 0 -STATIC void wiznet5k_socket_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - wiznet5k_socket_obj_t *self = self_in; - print(env, "", self->sn, getSn_MR(self->sn)); -} - -STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { - mp_int_t ret = WIZCHIP_EXPORT(disconnect)(self->sn); - return 0; -} -#endif - -/******************************************************************************/ -// MicroPython bindings - -/// \classmethod \constructor(spi, pin_cs, pin_rst) -/// Create and return a WIZNET5K object. -STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 3, 3, false); - - // init the wiznet5k object - wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k; - wiznet5k_obj.cris_state = 0; - wiznet5k_obj.spi = spi_from_mp_obj(args[0]); - wiznet5k_obj.cs = pin_find(args[1]); - wiznet5k_obj.rst = pin_find(args[2]); - wiznet5k_obj.socket_used = 0; - - /*!< SPI configuration */ - SPI_InitTypeDef *init = &wiznet5k_obj.spi->spi->Init; - init->Mode = SPI_MODE_MASTER; - init->Direction = SPI_DIRECTION_2LINES; - init->DataSize = SPI_DATASIZE_8BIT; - init->CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle - init->CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle - init->NSS = SPI_NSS_SOFT; - init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz - init->FirstBit = SPI_FIRSTBIT_MSB; - init->TIMode = SPI_TIMODE_DISABLED; - init->CRCCalculation = SPI_CRCCALCULATION_DISABLED; - init->CRCPolynomial = 7; // unused - spi_init(wiznet5k_obj.spi, false); - - mp_hal_pin_output(wiznet5k_obj.cs); - mp_hal_pin_output(wiznet5k_obj.rst); - - mp_hal_pin_low(wiznet5k_obj.rst); - mp_hal_delay_ms(1); // datasheet says 2us - mp_hal_pin_high(wiznet5k_obj.rst); - mp_hal_delay_ms(160); // datasheet says 150ms - - reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); - reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); - reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); - - uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 2k buffer for each socket - ctlwizchip(CW_INIT_WIZCHIP, sn_size); - - // set some sensible default values; they are configurable using ifconfig method - wiz_NetInfo netinfo = { - .mac = {0x00, 0x08, 0xdc, 0xab, 0xcd, 0xef}, - .ip = {192, 168, 0, 18}, - .sn = {255, 255, 255, 0}, - .gw = {192, 168, 0, 1}, - .dns = {8, 8, 8, 8}, // Google public DNS - .dhcp = NETINFO_STATIC, - }; - ctlnetwork(CN_SET_NETINFO, (void *)&netinfo); - - // seems we need a small delay after init - mp_hal_delay_ms(250); - - // register with network module - mod_network_register_nic(&wiznet5k_obj); - - // return wiznet5k object - return &wiznet5k_obj; -} - -/// \method regs() -/// Dump WIZNET5K registers. -STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { - // wiznet5k_obj_t *self = self_in; - printf("Wiz CREG:"); - for (int i = 0; i < 0x50; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_NETWORK_WIZNET5K == 5200 - uint32_t reg = i; - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - for (int sn = 0; sn < 4; ++sn) { - printf("\nWiz SREG[%d]:", sn); - for (int i = 0; i < 0x30; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_NETWORK_WIZNET5K == 5200 - uint32_t reg = WIZCHIP_SREG_ADDR(sn, i); - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - } - printf("\n"); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); - -STATIC mp_obj_t wiznet5k_isconnected(mp_obj_t self_in) { - (void)self_in; - return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_isconnected_obj, wiznet5k_isconnected); - -/// \method ifconfig([(ip, subnet, gateway, dns)]) -/// Get/set IP address, subnet mask, gateway and DNS. -STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { - wiz_NetInfo netinfo; - ctlnetwork(CN_GET_NETINFO, &netinfo); - if (n_args == 1) { - // get - mp_obj_t tuple[4] = { - netutils_format_ipv4_addr(netinfo.ip, NETUTILS_BIG), - netutils_format_ipv4_addr(netinfo.sn, NETUTILS_BIG), - netutils_format_ipv4_addr(netinfo.gw, NETUTILS_BIG), - netutils_format_ipv4_addr(netinfo.dns, NETUTILS_BIG), - }; - return mp_obj_new_tuple(4, tuple); - } else { - // set - mp_obj_t *items; - mp_obj_get_array_fixed_n(args[1], 4, &items); - netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[1], netinfo.sn, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[2], netinfo.gw, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[3], netinfo.dns, NETUTILS_BIG); - ctlnetwork(CN_SET_NETINFO, &netinfo); - return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); - -STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); - -const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_WIZNET5K, - .make_new = wiznet5k_make_new, - .locals_dict = (mp_obj_dict_t *)&wiznet5k_locals_dict, - }, - .gethostbyname = wiznet5k_gethostbyname, - .socket = wiznet5k_socket_socket, - .close = wiznet5k_socket_close, - .bind = wiznet5k_socket_bind, - .listen = wiznet5k_socket_listen, - .accept = wiznet5k_socket_accept, - .connect = wiznet5k_socket_connect, - .send = wiznet5k_socket_send, - .recv = wiznet5k_socket_recv, - .sendto = wiznet5k_socket_sendto, - .recvfrom = wiznet5k_socket_recvfrom, - .setsockopt = wiznet5k_socket_setsockopt, - .settimeout = wiznet5k_socket_settimeout, - .ioctl = wiznet5k_socket_ioctl, -}; - -#endif // MICROPY_PY_NETWORK_WIZNET5K && !MICROPY_PY_LWIP diff --git a/ports/stm32/network_wiznet5k.c b/ports/stm32/network_wiznet5k.c deleted file mode 100644 index 4675f3c2c2a1..000000000000 --- a/ports/stm32/network_wiznet5k.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "py/runtime.h" -#include "py/mphal.h" -#include "extmod/modnetwork.h" -#include "spi.h" - -#if MICROPY_PY_NETWORK_WIZNET5K && MICROPY_PY_LWIP - -#include "shared/netutils/netutils.h" -#include "drivers/wiznet5k/ethernet/socket.h" -#include "lwip/err.h" -#include "lwip/dns.h" -#include "lwip/dhcp.h" -#include "netif/etharp.h" - -#define TRACE_ETH_TX (0x0002) -#define TRACE_ETH_RX (0x0004) - -/*******************************************************************************/ -// Wiznet5k Ethernet driver in MACRAW mode - -typedef struct _wiznet5k_obj_t { - mp_obj_base_t base; - mp_uint_t cris_state; - const spi_t *spi; - mp_hal_pin_obj_t cs; - mp_hal_pin_obj_t rst; - uint8_t eth_frame[1514]; - uint32_t trace_flags; - struct netif netif; - struct dhcp dhcp_struct; -} wiznet5k_obj_t; - -// Global object holding the Wiznet5k state -STATIC wiznet5k_obj_t wiznet5k_obj; - -STATIC void wiznet5k_lwip_init(wiznet5k_obj_t *self); - -STATIC void wiz_cris_enter(void) { - wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); -} - -STATIC void wiz_cris_exit(void) { - MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); -} - -STATIC void wiz_cs_select(void) { - mp_hal_pin_low(wiznet5k_obj.cs); -} - -STATIC void wiz_cs_deselect(void) { - mp_hal_pin_high(wiznet5k_obj.cs); -} - -STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { - HAL_StatusTypeDef status = HAL_SPI_Receive(wiznet5k_obj.spi->spi, buf, len, 5000); - (void)status; -} - -STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { - HAL_StatusTypeDef status = HAL_SPI_Transmit(wiznet5k_obj.spi->spi, (uint8_t *)buf, len, 5000); - (void)status; -} - -STATIC void wiznet5k_init(void) { - // SPI configuration - SPI_InitTypeDef *init = &wiznet5k_obj.spi->spi->Init; - init->Mode = SPI_MODE_MASTER; - init->Direction = SPI_DIRECTION_2LINES; - init->DataSize = SPI_DATASIZE_8BIT; - init->CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle - init->CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle - init->NSS = SPI_NSS_SOFT; - init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz - init->FirstBit = SPI_FIRSTBIT_MSB; - init->TIMode = SPI_TIMODE_DISABLED; - init->CRCCalculation = SPI_CRCCALCULATION_DISABLED; - init->CRCPolynomial = 7; // unused - spi_init(wiznet5k_obj.spi, false); - - mp_hal_pin_output(wiznet5k_obj.cs); - mp_hal_pin_output(wiznet5k_obj.rst); - - // Reset the chip - mp_hal_pin_low(wiznet5k_obj.rst); - mp_hal_delay_ms(1); // datasheet says 2us - mp_hal_pin_high(wiznet5k_obj.rst); - mp_hal_delay_ms(150); // datasheet says 150ms - - // Set physical interface callbacks - reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); - reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); - reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); - - // Configure 16k buffers for fast MACRAW - uint8_t sn_size[16] = {16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0}; - ctlwizchip(CW_INIT_WIZCHIP, sn_size); - - // Seems we need a small delay after init - mp_hal_delay_ms(250); - - // If the device doesn't have a MAC address then set one - uint8_t mac[6]; - getSHAR(mac); - if ((mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]) == 0) { - mp_hal_get_mac(MP_HAL_MAC_ETH0, mac); - setSHAR(mac); - } - - // Hook the Wiznet into lwIP - wiznet5k_lwip_init(&wiznet5k_obj); -} - -STATIC void wiznet5k_deinit(void) { - for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { - if (netif == &wiznet5k_obj.netif) { - netif_remove(netif); - netif->flags = 0; - break; - } - } -} - -STATIC void wiznet5k_get_mac_address(wiznet5k_obj_t *self, uint8_t mac[6]) { - (void)self; - getSHAR(mac); -} - -STATIC void wiznet5k_send_ethernet(wiznet5k_obj_t *self, size_t len, const uint8_t *buf) { - uint8_t ip[4] = {1, 1, 1, 1}; // dummy - int ret = WIZCHIP_EXPORT(sendto)(0, (byte *)buf, len, ip, 11); // dummy port - if (ret != len) { - printf("wiznet5k_send_ethernet: fatal error %d\n", ret); - netif_set_link_down(&self->netif); - netif_set_down(&self->netif); - } -} - -// Stores the frame in self->eth_frame and returns number of bytes in the frame, 0 for no frame -STATIC uint16_t wiznet5k_recv_ethernet(wiznet5k_obj_t *self) { - uint16_t len = getSn_RX_RSR(0); - if (len == 0) { - return 0; - } - - byte ip[4]; - uint16_t port; - int ret = WIZCHIP_EXPORT(recvfrom)(0, self->eth_frame, 1514, ip, &port); - if (ret <= 0) { - printf("wiznet5k_poll: fatal error len=%u ret=%d\n", len, ret); - netif_set_link_down(&self->netif); - netif_set_down(&self->netif); - return 0; - } - - return ret; -} - -/*******************************************************************************/ -// Wiznet5k lwIP interface - -STATIC err_t wiznet5k_netif_output(struct netif *netif, struct pbuf *p) { - wiznet5k_obj_t *self = netif->state; - pbuf_copy_partial(p, self->eth_frame, p->tot_len, 0); - if (self->trace_flags & TRACE_ETH_TX) { - netutils_ethernet_trace(MP_PYTHON_PRINTER, p->tot_len, self->eth_frame, NETUTILS_TRACE_IS_TX | NETUTILS_TRACE_NEWLINE); - } - wiznet5k_send_ethernet(self, p->tot_len, self->eth_frame); - return ERR_OK; -} - -STATIC err_t wiznet5k_netif_init(struct netif *netif) { - netif->linkoutput = wiznet5k_netif_output; - netif->output = etharp_output; - netif->mtu = 1500; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; - wiznet5k_get_mac_address(netif->state, netif->hwaddr); - netif->hwaddr_len = sizeof(netif->hwaddr); - int ret = WIZCHIP_EXPORT(socket)(0, Sn_MR_MACRAW, 0, 0); - if (ret != 0) { - printf("WIZNET fatal error in netifinit: %d\n", ret); - return ERR_IF; - } - - // Enable MAC filtering so we only get frames destined for us, to reduce load on lwIP - setSn_MR(0, getSn_MR(0) | Sn_MR_MFEN); - - return ERR_OK; -} - -STATIC void wiznet5k_lwip_init(wiznet5k_obj_t *self) { - ip_addr_t ipconfig[4]; - ipconfig[0].addr = 0; - ipconfig[1].addr = 0; - ipconfig[2].addr = 0; - ipconfig[3].addr = 0; - netif_add(&self->netif, &ipconfig[0], &ipconfig[1], &ipconfig[2], self, wiznet5k_netif_init, ethernet_input); - self->netif.name[0] = 'e'; - self->netif.name[1] = '0'; - netif_set_default(&self->netif); - dns_setserver(0, &ipconfig[3]); - dhcp_set_struct(&self->netif, &self->dhcp_struct); - // Setting NETIF_FLAG_UP then clearing it is a workaround for dhcp_start and the - // LWIP_DHCP_CHECK_LINK_UP option, so that the DHCP client schedules itself to - // automatically start when the interface later goes up. - self->netif.flags |= NETIF_FLAG_UP; - dhcp_start(&self->netif); - self->netif.flags &= ~NETIF_FLAG_UP; -} - -void wiznet5k_poll(void) { - wiznet5k_obj_t *self = &wiznet5k_obj; - if (!(self->netif.flags & NETIF_FLAG_LINK_UP)) { - return; - } - uint16_t len; - while ((len = wiznet5k_recv_ethernet(self)) > 0) { - if (self->trace_flags & TRACE_ETH_RX) { - netutils_ethernet_trace(MP_PYTHON_PRINTER, len, self->eth_frame, NETUTILS_TRACE_NEWLINE); - } - struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if (p != NULL) { - pbuf_take(p, self->eth_frame, len); - if (self->netif.input(p, &self->netif) != ERR_OK) { - pbuf_free(p); - } - } - } -} - -/*******************************************************************************/ -// MicroPython bindings - -// WIZNET5K([spi, pin_cs, pin_rst]) -STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 3, 3, false); - - const spi_t *spi = spi_from_mp_obj(args[0]); - mp_hal_pin_obj_t cs = pin_find(args[1]); - mp_hal_pin_obj_t rst = pin_find(args[2]); - - // Access the existing object, if it has been constructed with the same hardware interface - if (wiznet5k_obj.base.type == (mp_obj_type_t *)&mod_network_nic_type_wiznet5k) { - if (!(wiznet5k_obj.spi == spi && wiznet5k_obj.cs == cs && wiznet5k_obj.rst == rst - && wiznet5k_obj.netif.flags != 0)) { - wiznet5k_deinit(); - } - } - - // Init the wiznet5k object - wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k; - wiznet5k_obj.cris_state = 0; - wiznet5k_obj.spi = spi; - wiznet5k_obj.cs = cs; - wiznet5k_obj.rst = rst; - wiznet5k_obj.trace_flags = 0; - - // Return wiznet5k object - return MP_OBJ_FROM_PTR(&wiznet5k_obj); -} - -STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { - (void)self_in; - printf("Wiz CREG:"); - for (int i = 0; i < 0x50; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_NETWORK_WIZNET5K == 5200 - uint32_t reg = i; - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - for (int sn = 0; sn < 4; ++sn) { - printf("\nWiz SREG[%d]:", sn); - for (int i = 0; i < 0x30; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_NETWORK_WIZNET5K == 5200 - uint32_t reg = WIZCHIP_SREG_ADDR(sn, i); - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - } - printf("\n"); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); - -STATIC mp_obj_t wiznet5k_isconnected(mp_obj_t self_in) { - wiznet5k_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool( - wizphy_getphylink() == PHY_LINK_ON - && (self->netif.flags & NETIF_FLAG_UP) - && self->netif.ip_addr.addr != 0 - ); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_isconnected_obj, wiznet5k_isconnected); - -STATIC mp_obj_t wiznet5k_active(size_t n_args, const mp_obj_t *args) { - wiznet5k_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (n_args == 1) { - return mp_obj_new_bool(self->netif.flags & NETIF_FLAG_UP); - } else { - if (mp_obj_is_true(args[1])) { - if (!(self->netif.flags & NETIF_FLAG_UP)) { - wiznet5k_init(); - netif_set_link_up(&self->netif); - netif_set_up(&self->netif); - } - } else { - if (self->netif.flags & NETIF_FLAG_UP) { - netif_set_down(&self->netif); - netif_set_link_down(&self->netif); - wiznet5k_deinit(); - } - } - return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_active_obj, 1, 2, wiznet5k_active); - -STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { - wiznet5k_obj_t *self = MP_OBJ_TO_PTR(args[0]); - return mod_network_nic_ifconfig(&self->netif, n_args - 1, args + 1); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); - -STATIC mp_obj_t wiznet5k_status(size_t n_args, const mp_obj_t *args) { - wiznet5k_obj_t *self = MP_OBJ_TO_PTR(args[0]); - (void)self; - - if (n_args == 1) { - // No arguments: return link status - if (self->netif.flags && wizphy_getphylink() == PHY_LINK_ON) { - if ((self->netif.flags & NETIF_FLAG_UP) && self->netif.ip_addr.addr != 0) { - return MP_OBJ_NEW_SMALL_INT(2); - } else { - return MP_OBJ_NEW_SMALL_INT(1); - } - } else { - return MP_OBJ_NEW_SMALL_INT(0); - } - } - - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_status_obj, 1, 2, wiznet5k_status); - -STATIC mp_obj_t wiznet5k_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - wiznet5k_obj_t *self = MP_OBJ_TO_PTR(args[0]); - - if (kwargs->used == 0) { - // Get config value - if (n_args != 2) { - mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); - } - - switch (mp_obj_str_get_qstr(args[1])) { - case MP_QSTR_mac: { - uint8_t buf[6]; - wiznet5k_get_mac_address(self, buf); - return mp_obj_new_bytes(buf, 6); - } - default: - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); - } - } else { - // Set config value(s) - if (n_args != 1) { - mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); - } - - for (size_t i = 0; i < kwargs->alloc; ++i) { - if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { - mp_map_elem_t *e = &kwargs->table[i]; - switch (mp_obj_str_get_qstr(e->key)) { - case MP_QSTR_mac: { - mp_buffer_info_t buf; - mp_get_buffer_raise(e->value, &buf, MP_BUFFER_READ); - if (buf.len != 6) { - mp_raise_ValueError(NULL); - } - setSHAR(buf.buf); - memcpy(self->netif.hwaddr, buf.buf, 6); - break; - } - case MP_QSTR_trace: { - self->trace_flags = mp_obj_get_int(e->value); - break; - } - default: - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); - } - } - } - - return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wiznet5k_config_obj, 1, wiznet5k_config); - -STATIC mp_obj_t send_ethernet_wrapper(mp_obj_t self_in, mp_obj_t buf_in) { - wiznet5k_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_buffer_info_t buf; - mp_get_buffer_raise(buf_in, &buf, MP_BUFFER_READ); - wiznet5k_send_ethernet(self, buf.len, buf.buf); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(send_ethernet_obj, send_ethernet_wrapper); - -STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) }, - { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&wiznet5k_active_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&wiznet5k_status_obj) }, - { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&wiznet5k_config_obj) }, - - { MP_ROM_QSTR(MP_QSTR_send_ethernet), MP_ROM_PTR(&send_ethernet_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); - -const mp_obj_type_t mod_network_nic_type_wiznet5k = { - { &mp_type_type }, - .name = MP_QSTR_WIZNET5K, - .make_new = wiznet5k_make_new, - .locals_dict = (mp_obj_dict_t *)&wiznet5k_locals_dict, -}; - -#endif // MICROPY_PY_NETWORK_WIZNET5K && MICROPY_PY_LWIP From c3305c49e422369119ab211dc8fb2366aa6d7d53 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 4 Aug 2022 20:19:57 +0200 Subject: [PATCH 1631/4290] stm32: Add definitions required for lwIP version of Wiznet NIC. --- ports/stm32/mphalport.h | 8 ++++++++ ports/stm32/mpnetworkport.c | 5 +++++ ports/stm32/pendsv.h | 3 +++ 3 files changed, 16 insertions(+) diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index 47bb1f8c8441..8028782a90c4 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -96,11 +96,19 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { #define mp_hal_pin_od_high(p) mp_hal_pin_high(p) #define mp_hal_pin_read(p) (((p)->gpio->IDR >> (p)->pin) & 1) #define mp_hal_pin_write(p, v) ((v) ? mp_hal_pin_high(p) : mp_hal_pin_low(p)) +#define mp_hal_pin_interrupt(pin, handler, trigger, hard) extint_register_pin(pin, trigger, hard, handler) + +enum mp_hal_pin_interrupt_trigger { + MP_HAL_PIN_TRIGGER_NONE, + MP_HAL_PIN_TRIGGER_FALL = GPIO_MODE_IT_FALLING, + MP_HAL_PIN_TRIGGER_RISE = GPIO_MODE_IT_RISING, +}; void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio); void mp_hal_pin_config(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, uint32_t alt); bool mp_hal_pin_config_alt(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, uint8_t fn, uint8_t unit); void mp_hal_pin_config_speed(mp_hal_pin_obj_t pin_obj, uint32_t speed); +void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_obj_t callback_obj); enum { MP_HAL_MAC_WLAN0 = 0, diff --git a/ports/stm32/mpnetworkport.c b/ports/stm32/mpnetworkport.c index 2f49328e110e..1ce758e7dd78 100644 --- a/ports/stm32/mpnetworkport.c +++ b/ports/stm32/mpnetworkport.c @@ -50,6 +50,11 @@ #if MICROPY_PY_NETWORK_WIZNET5K void wiznet5k_poll(void); +void wiznet5k_deinit(void); + +void wiznet5k_try_poll(void) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_WIZNET, wiznet5k_poll); +} #endif u32_t sys_now(void) { diff --git a/ports/stm32/pendsv.h b/ports/stm32/pendsv.h index 0733d355d311..f97581e99a30 100644 --- a/ports/stm32/pendsv.h +++ b/ports/stm32/pendsv.h @@ -35,6 +35,9 @@ enum { #if MICROPY_PY_NETWORK_CYW43 PENDSV_DISPATCH_CYW43, #endif + #if MICROPY_PY_NETWORK_WIZNET5K + PENDSV_DISPATCH_WIZNET, + #endif #endif #if MICROPY_PY_BLUETOOTH && !MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS PENDSV_DISPATCH_BLUETOOTH_HCI, From 54eaa8c8a6c854e13f3c1b646ef44d0888628353 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 10 Aug 2022 11:04:09 +0200 Subject: [PATCH 1632/4290] stm32/mphalport: Add mp_hal_get_spi_obj() helper function. The function spi_from_mp_obj() is kept since it is used by the cc3k driver. --- ports/stm32/mphalport.h | 2 ++ ports/stm32/spi.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index 8028782a90c4..358d9cd25d0d 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -110,6 +110,8 @@ bool mp_hal_pin_config_alt(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, u void mp_hal_pin_config_speed(mp_hal_pin_obj_t pin_obj, uint32_t speed); void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_obj_t callback_obj); +mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t spi_in); + enum { MP_HAL_MAC_WLAN0 = 0, MP_HAL_MAC_WLAN1, diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 188376ec06d5..9c031cad2e28 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -30,6 +30,7 @@ #include "py/runtime.h" #include "py/mphal.h" #include "spi.h" +#include "extmod/machine_spi.h" // Possible DMA configurations for SPI buses: // SPI1_TX: DMA2_Stream3.CHANNEL_3 or DMA2_Stream5.CHANNEL_3 @@ -685,6 +686,20 @@ const spi_t *spi_from_mp_obj(mp_obj_t o) { } } +mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t o) { + if (mp_obj_is_type(o, &machine_hard_spi_type)) { + return MP_OBJ_TO_PTR(o); + } + #if MICROPY_PY_MACHINE_SOFTSPI + else if (mp_obj_is_type(o, &mp_machine_soft_spi_type)) { + return MP_OBJ_TO_PTR(o); + } + #endif + else { + mp_raise_TypeError(MP_ERROR_TEXT("expecting an SPI object")); + } +} + /******************************************************************************/ // Implementation of low-level SPI C protocol From f6ec01d1da8d316e1cdfeaf20cdc0578f943e154 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 5 Aug 2022 16:49:15 +0200 Subject: [PATCH 1633/4290] tools/ci.sh: Split the stm32 builds for wiznet5k and cc3k. - Add lib/wiznet5k into the 'make submodules' step. - Split the stm32 builds for wiznet5k and cc3k. - Run 'make .... clean' after making the wiznet5k build. --- tools/ci.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/ci.sh b/tools/ci.sh index dc2ccf775b15..b7b20e3c7d65 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -309,10 +309,12 @@ function ci_stm32_setup { function ci_stm32_pyb_build { make ${MAKEOPTS} -C mpy-cross - make ${MAKEOPTS} -C ports/stm32 submodules + make ${MAKEOPTS} -C ports/stm32 MICROPY_PY_NETWORK_WIZNET5K=5200 submodules git submodule update --init lib/btstack git submodule update --init lib/mynewt-nimble - make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 MICROPY_PY_CC3K=1 USER_C_MODULES=../../examples/usercmodule + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 USER_C_MODULES=../../examples/usercmodule + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 clean + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_CC3K=1 make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2 make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1 make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBV10 CFLAGS_EXTRA='-DMBOOT_FSLOAD=1 -DMBOOT_VFS_LFS2=1' From 71dcb21e24064d1150094e66a904877402cdd157 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 10 Aug 2022 11:07:35 +0200 Subject: [PATCH 1634/4290] drivers/wiznet5k: Remove old Wiznet driver. It has been replaced by the submodule lib/wiznet5k. --- drivers/wiznet5k/README.md | 6 - drivers/wiznet5k/ethernet/socket.c | 725 -------- drivers/wiznet5k/ethernet/socket.h | 472 ----- drivers/wiznet5k/ethernet/w5200/w5200.c | 215 --- drivers/wiznet5k/ethernet/w5200/w5200.h | 2092 ---------------------- drivers/wiznet5k/ethernet/w5500/w5500.c | 247 --- drivers/wiznet5k/ethernet/w5500/w5500.h | 2057 --------------------- drivers/wiznet5k/ethernet/wizchip_conf.c | 662 ------- drivers/wiznet5k/ethernet/wizchip_conf.h | 554 ------ drivers/wiznet5k/internet/dhcp/dhcp.c | 978 ---------- drivers/wiznet5k/internet/dhcp/dhcp.h | 150 -- drivers/wiznet5k/internet/dns/dns.c | 566 ------ drivers/wiznet5k/internet/dns/dns.h | 96 - 13 files changed, 8820 deletions(-) delete mode 100644 drivers/wiznet5k/README.md delete mode 100644 drivers/wiznet5k/ethernet/socket.c delete mode 100644 drivers/wiznet5k/ethernet/socket.h delete mode 100644 drivers/wiznet5k/ethernet/w5200/w5200.c delete mode 100644 drivers/wiznet5k/ethernet/w5200/w5200.h delete mode 100644 drivers/wiznet5k/ethernet/w5500/w5500.c delete mode 100644 drivers/wiznet5k/ethernet/w5500/w5500.h delete mode 100644 drivers/wiznet5k/ethernet/wizchip_conf.c delete mode 100644 drivers/wiznet5k/ethernet/wizchip_conf.h delete mode 100644 drivers/wiznet5k/internet/dhcp/dhcp.c delete mode 100644 drivers/wiznet5k/internet/dhcp/dhcp.h delete mode 100644 drivers/wiznet5k/internet/dns/dns.c delete mode 100644 drivers/wiznet5k/internet/dns/dns.h diff --git a/drivers/wiznet5k/README.md b/drivers/wiznet5k/README.md deleted file mode 100644 index 88f25a2b8dbc..000000000000 --- a/drivers/wiznet5k/README.md +++ /dev/null @@ -1,6 +0,0 @@ -This is the driver for the WIZnet5x00 series of Ethernet controllers. - -Adapted for MicroPython. - -Original source: https://github.com/Wiznet/W5500_EVB/tree/master/ioLibrary -Taken on: 30 August 2014 diff --git a/drivers/wiznet5k/ethernet/socket.c b/drivers/wiznet5k/ethernet/socket.c deleted file mode 100644 index 3ffda3a722df..000000000000 --- a/drivers/wiznet5k/ethernet/socket.c +++ /dev/null @@ -1,725 +0,0 @@ -//***************************************************************************** -// -//! \file socket.c -//! \brief SOCKET APIs Implements file. -//! \details SOCKET APIs like as Berkeley Socket APIs. -//! \version 1.0.3 -//! \date 2013/10/21 -//! \par Revision history -//! <2014/05/01> V1.0.3. Refer to M20140501 -//! 1. Implicit type casting -> Explicit type casting. -//! 2. replace 0x01 with PACK_REMAINED in recvfrom() -//! 3. Validation a destination ip in connect() & sendto(): -//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address. -//! Copy 4 byte addr value into temporary uint32 variable and then compares it. -//! <2013/12/20> V1.0.2 Refer to M20131220 -//! Remove Warning. -//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". -//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT) -//! <2013/10/21> 1st Release -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#include - -#include "py/mpthread.h" -#include "socket.h" - -#define SOCK_ANY_PORT_NUM 0xC000; - -static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; -static uint16_t sock_io_mode = 0; -static uint16_t sock_is_sending = 0; -static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; -static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; - -#if _WIZCHIP_ == 5200 - static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; -#endif - -#define CHECK_SOCKNUM() \ - do{ \ - if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ - }while(0); \ - -#define CHECK_SOCKMODE(mode) \ - do{ \ - if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ - }while(0); \ - -#define CHECK_SOCKINIT() \ - do{ \ - if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ - }while(0); \ - -#define CHECK_SOCKDATA() \ - do{ \ - if(len == 0) return SOCKERR_DATALEN; \ - }while(0); \ - -void WIZCHIP_EXPORT(socket_reset)(void) { - sock_any_port = SOCK_ANY_PORT_NUM; - sock_io_mode = 0; - sock_is_sending = 0; - /* - memset(sock_remained_size, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t)); - memset(sock_pack_info, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint8_t)); - */ - -#if _WIZCHIP_ == 5200 - memset(sock_next_rd, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t)); -#endif -} - -int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) -{ - CHECK_SOCKNUM(); - switch(protocol) - { - case Sn_MR_TCP : - case Sn_MR_UDP : - case Sn_MR_MACRAW : - break; - #if ( _WIZCHIP_ < 5200 ) - case Sn_MR_IPRAW : - case Sn_MR_PPPoE : - break; - #endif - default : - return SOCKERR_SOCKMODE; - } - if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; -#if _WIZCHIP_ == 5200 - if(flag & 0x10) return SOCKERR_SOCKFLAG; -#endif - - if(flag != 0) - { - switch(protocol) - { - case Sn_MR_TCP: - if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; - break; - case Sn_MR_UDP: - if(flag & SF_IGMP_VER2) - { - if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; - } - #if _WIZCHIP_ == 5500 - if(flag & SF_UNI_BLOCK) - { - if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; - } - #endif - break; - default: - break; - } - } - WIZCHIP_EXPORT(close)(sn); - setSn_MR(sn, (protocol | (flag & 0xF0))); - if(!port) - { - port = sock_any_port++; - if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; - } - setSn_PORT(sn,port); - setSn_CR(sn,Sn_CR_OPEN); - while(getSn_CR(sn)); - sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); - sock_is_sending &= ~(1< freesize) len = freesize; // check size not to exceed MAX size. - while(1) - { - freesize = getSn_TX_FSR(sn); - tmp = getSn_SR(sn); - if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) - { - WIZCHIP_EXPORT(close)(sn); - return SOCKERR_SOCKSTATUS; - } - if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY; - if(len <= freesize) break; - MICROPY_THREAD_YIELD(); - } - wiz_send_data(sn, buf, len); - #if _WIZCHIP_ == 5200 - sock_next_rd[sn] = getSn_TX_RD(sn) + len; - #endif - setSn_CR(sn,Sn_CR_SEND); - /* wait to process the command... */ - while(getSn_CR(sn)); - sock_is_sending |= (1 << sn); - return len; -} - - -int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len) -{ - uint8_t tmp = 0; - uint16_t recvsize = 0; - CHECK_SOCKNUM(); - CHECK_SOCKMODE(Sn_MR_TCP); - CHECK_SOCKDATA(); - - recvsize = getSn_RxMAX(sn); - if(recvsize < len) len = recvsize; - while(1) - { - recvsize = getSn_RX_RSR(sn); - tmp = getSn_SR(sn); - if (tmp != SOCK_ESTABLISHED) - { - if(tmp == SOCK_CLOSE_WAIT) - { - if(recvsize != 0) break; - else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) - { - // dpgeorge: Getting here seems to be an orderly shutdown of the - // socket, and trying to get POSIX behaviour we return 0 because: - // "If no messages are available to be received and the peer has per†- // formed an orderly shutdown, recv() shall return 0". - // TODO this return value clashes with SOCK_BUSY in non-blocking mode. - WIZCHIP_EXPORT(close)(sn); - return 0; - } - } - else - { - WIZCHIP_EXPORT(close)(sn); - return SOCKERR_SOCKSTATUS; - } - } - if((sock_io_mode & (1< freesize) len = freesize; // check size not to exceed MAX size. - while(1) - { - freesize = getSn_TX_FSR(sn); - if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; - if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY; - if(len <= freesize) break; - MICROPY_THREAD_YIELD(); - }; - wiz_send_data(sn, buf, len); - - #if _WIZCHIP_ == 5200 // for W5200 ARP errata - setSUBR(wizchip_getsubn()); - #endif - - setSn_CR(sn,Sn_CR_SEND); - /* wait to process the command... */ - while(getSn_CR(sn)); - while(1) - { - tmp = getSn_IR(sn); - if(tmp & Sn_IR_SENDOK) - { - setSn_IR(sn, Sn_IR_SENDOK); - break; - } - //M:20131104 - //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; - else if(tmp & Sn_IR_TIMEOUT) - { - setSn_IR(sn, Sn_IR_TIMEOUT); - #if _WIZCHIP_ == 5200 // for W5200 ARP errata - setSUBR((uint8_t*)"\x00\x00\x00\x00"); - #endif - return SOCKERR_TIMEOUT; - } - //////////// - MICROPY_THREAD_YIELD(); - } - #if _WIZCHIP_ == 5200 // for W5200 ARP errata - setSUBR((uint8_t*)"\x00\x00\x00\x00"); - #endif - return len; -} - - - -int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) -{ - uint8_t mr; - uint8_t head[8]; - uint16_t pack_len=0; - - CHECK_SOCKNUM(); - //CHECK_SOCKMODE(Sn_MR_UDP); - switch((mr=getSn_MR(sn)) & 0x0F) - { - case Sn_MR_UDP: - case Sn_MR_MACRAW: - break; - #if ( _WIZCHIP_ < 5200 ) - case Sn_MR_IPRAW: - case Sn_MR_PPPoE: - break; - #endif - default: - return SOCKERR_SOCKMODE; - } - CHECK_SOCKDATA(); - if(sock_remained_size[sn] == 0) - { - while(1) - { - pack_len = getSn_RX_RSR(sn); - if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; - if( (sock_io_mode & (1< 1514) - { - WIZCHIP_EXPORT(close)(sn); - return SOCKFATAL_PACKLEN; - } - sock_pack_info[sn] = PACK_FIRST; - } - if(len < sock_remained_size[sn]) pack_len = len; - else pack_len = sock_remained_size[sn]; - wiz_recv_data(sn,buf,pack_len); - break; - #if ( _WIZCHIP_ < 5200 ) - case Sn_MR_IPRAW: - if(sock_remained_size[sn] == 0) - { - wiz_recv_data(sn, head, 6); - setSn_CR(sn,Sn_CR_RECV); - while(getSn_CR(sn)); - addr[0] = head[0]; - addr[1] = head[1]; - addr[2] = head[2]; - addr[3] = head[3]; - sock_remained_size[sn] = head[4]; - sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; - sock_pack_info[sn] = PACK_FIRST; - } - // - // Need to packet length check - // - if(len < sock_remained_size[sn]) pack_len = len; - else pack_len = sock_remained_size[sn]; - wiz_recv_data(sn, buf, pack_len); // data copy. - break; - #endif - default: - wiz_recv_ignore(sn, pack_len); // data copy. - sock_remained_size[sn] = pack_len; - break; - } - setSn_CR(sn,Sn_CR_RECV); - /* wait to process the command... */ - while(getSn_CR(sn)) ; - sock_remained_size[sn] -= pack_len; - //M20140501 : replace 0x01 with PACK_REMAINED - //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; - if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED; - // - return pack_len; -} - - -int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg) -{ - uint8_t tmp = 0; - CHECK_SOCKNUM(); - switch(cstype) - { - case CS_SET_IOMODE: - tmp = *((uint8_t*)arg); - if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1< explict type casting - //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; - *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); - // - break; - case CS_GET_MAXTXBUF: - *((uint16_t*)arg) = getSn_TxMAX(sn); - break; - case CS_GET_MAXRXBUF: - *((uint16_t*)arg) = getSn_RxMAX(sn); - break; - case CS_CLR_INTERRUPT: - if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; - setSn_IR(sn,*(uint8_t*)arg); - break; - case CS_GET_INTERRUPT: - *((uint8_t*)arg) = getSn_IR(sn); - break; - case CS_SET_INTMASK: - if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; - setSn_IMR(sn,*(uint8_t*)arg); - break; - case CS_GET_INTMASK: - *((uint8_t*)arg) = getSn_IMR(sn); - default: - return SOCKERR_ARG; - } - return SOCK_OK; -} - -int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg) -{ - // M20131220 : Remove warning - //uint8_t tmp; - CHECK_SOCKNUM(); - switch(sotype) - { - case SO_TTL: - setSn_TTL(sn,*(uint8_t*)arg); - break; - case SO_TOS: - setSn_TOS(sn,*(uint8_t*)arg); - break; - case SO_MSS: - setSn_MSSR(sn,*(uint16_t*)arg); - break; - case SO_DESTIP: - setSn_DIPR(sn, (uint8_t*)arg); - break; - case SO_DESTPORT: - setSn_DPORT(sn, *(uint16_t*)arg); - break; -#if _WIZCHIP_ != 5100 - case SO_KEEPALIVESEND: - CHECK_SOCKMODE(Sn_MR_TCP); - #if _WIZCHIP_ > 5200 - if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; - #endif - setSn_CR(sn,Sn_CR_SEND_KEEP); - while(getSn_CR(sn) != 0) - { - // M20131220 - //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) - if (getSn_IR(sn) & Sn_IR_TIMEOUT) - { - setSn_IR(sn, Sn_IR_TIMEOUT); - return SOCKERR_TIMEOUT; - } - } - break; - #if _WIZCHIP_ > 5200 - case SO_KEEPALIVEAUTO: - CHECK_SOCKMODE(Sn_MR_TCP); - setSn_KPALVTR(sn,*(uint8_t*)arg); - break; - #endif -#endif - default: - return SOCKERR_ARG; - } - return SOCK_OK; -} - -int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg) -{ - CHECK_SOCKNUM(); - switch(sotype) - { - case SO_FLAG: - *(uint8_t*)arg = getSn_MR(sn) & 0xF0; - break; - case SO_TTL: - *(uint8_t*) arg = getSn_TTL(sn); - break; - case SO_TOS: - *(uint8_t*) arg = getSn_TOS(sn); - break; - case SO_MSS: - *(uint8_t*) arg = getSn_MSSR(sn); - case SO_DESTIP: - getSn_DIPR(sn, (uint8_t*)arg); - break; - case SO_DESTPORT: - *(uint16_t*) arg = getSn_DPORT(sn); - break; - #if _WIZCHIP_ > 5200 - case SO_KEEPALIVEAUTO: - CHECK_SOCKMODE(Sn_MR_TCP); - *(uint16_t*) arg = getSn_KPALVTR(sn); - break; - #endif - case SO_SENDBUF: - *(uint16_t*) arg = getSn_TX_FSR(sn); - case SO_RECVBUF: - *(uint16_t*) arg = getSn_RX_RSR(sn); - case SO_STATUS: - *(uint8_t*) arg = getSn_SR(sn); - break; - case SO_REMAINSIZE: - if(getSn_MR(sn) == Sn_MR_TCP) - *(uint16_t*)arg = getSn_RX_RSR(sn); - else - *(uint16_t*)arg = sock_remained_size[sn]; - break; - case SO_PACKINFO: - CHECK_SOCKMODE(Sn_MR_TCP); - *(uint8_t*)arg = sock_pack_info[sn]; - break; - default: - return SOCKERR_SOCKOPT; - } - return SOCK_OK; -} diff --git a/drivers/wiznet5k/ethernet/socket.h b/drivers/wiznet5k/ethernet/socket.h deleted file mode 100644 index 2f03a34eba01..000000000000 --- a/drivers/wiznet5k/ethernet/socket.h +++ /dev/null @@ -1,472 +0,0 @@ -//***************************************************************************** -// -//! \file socket.h -//! \brief SOCKET APIs Header file. -//! \details SOCKET APIs like as berkeley socket api. -//! \version 1.0.2 -//! \date 2013/10/21 -//! \par Revision history -//! <2014/05/01> V1.0.2. Refer to M20140501 -//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED -//! 2. Add the comment as zero byte udp data reception in getsockopt(). -//! <2013/10/21> 1st Release -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** -/** - * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs - * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface. - * But there is a little bit of difference. - * @details - * Comparison between WIZnet and Berkeley SOCKET APIs - * - * - * - * - * - * - * - * - * - * - * - * - *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
- * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, - * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, - * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n - * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. - * When the listen SOCKET accepts a connection request from a client, it keeps listening. - * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n - * Following figure shows network flow diagram by Berkeley SOCKET API. - * @image html Berkeley_SOCKET.jpg "" - * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n - * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, - * it is changed in order to communicate with the client. - * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n - * If there're many listen SOCKET with same listen port number and a client requests a connection, - * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n - * Following figure shows network flow diagram by WIZnet SOCKET API. - * @image html WIZnet_SOCKET.jpg "" - */ -#ifndef _WIZCHIP_SOCKET_H_ -#define _WIZCHIP_SOCKET_H_ - -// use this macro for exported names to avoid name clashes -#define WIZCHIP_EXPORT(name) wizchip_ ## name - -#include "wizchip_conf.h" - -#define SOCKET uint8_t ///< SOCKET type define for legacy driver - -#define SOCK_OK 1 ///< Result is OK about socket process. -#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode. -#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. - -#define SOCK_ERROR 0 -#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number -#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option -#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized -#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. -#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. -#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag -#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. -#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. -#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero -#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address -#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred -#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. -#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. - -#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. - -/* - * SOCKET FLAG - */ -#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet -#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. -#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack. -#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode. - -#if _WIZCHIP_ == 5500 - #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 - #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 - #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 - #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 -#endif - -#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). - -/* - * UDP & MACRAW Packet Infomation - */ -#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. -#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. -#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. - -// resets all global state associated with the socket interface -void WIZCHIP_EXPORT(socket_reset)(void); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Open a socket. - * @details Initializes the socket with 'sn' passed as parameter and open. - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. - * @param port Port number to be bined. - * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n - * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. - * @sa Sn_MR - * - * @return @b Success : The socket number @b 'sn' passed as parameter\n - * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n - * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n - * @ref SOCKERR_SOCKFLAG - Invaild socket flag. - */ -int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Close a socket. - * @details It closes the socket with @b'sn' passed as parameter. - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * - * @return @b Success : @ref SOCK_OK \n - * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number - */ -int8_t WIZCHIP_EXPORT(close)(uint8_t sn); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Listen to a connection request from a client. - * @details It is listening to a connection request from a client. - * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @return @b Success : @ref SOCK_OK \n - * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n - * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. - */ -int8_t WIZCHIP_EXPORT(listen)(uint8_t sn); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Try to connect a server. - * @details It requests connection to the server with destination IP address and port number passed as parameter.\n - * @note It is valid only in TCP client mode. - * In block io mode, it does not return until connection is completed. - * In Non-block io mode, it return @ref SOCK_BUSY immediately. - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. - * @param port Destination port number. - * - * @return @b Success : @ref SOCK_OK \n - * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n - * @ref SOCKERR_SOCKMODE - Invalid socket mode\n - * @ref SOCKERR_SOCKINIT - Socket is not initialized\n - * @ref SOCKERR_IPINVALID - Wrong server IP address\n - * @ref SOCKERR_PORTZERO - Server port zero\n - * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n - * @ref SOCK_BUSY - In non-block io mode, it returned immediately\n - */ -int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Try to disconnect a connection socket. - * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. - * @note It is valid only in TCP server or client mode. \n - * In block io mode, it does not return until disconnection is completed. \n - * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n - - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @return @b Success : @ref SOCK_OK \n - * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n - * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n - * @ref SOCKERR_TIMEOUT - Timeout occurred \n - * @ref SOCK_BUSY - Socket is busy. - */ -int8_t WIZCHIP_EXPORT(disconnect)(uint8_t sn); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Send data to the connected peer in TCP socket. - * @details It is used to send outgoing data to the connected socket. - * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n - * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n - * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @param buf Pointer buffer containing data to be sent. - * @param len The byte length of data in buf. - * @return @b Success : The sent data size \n - * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n - * @ref SOCKERR_TIMEOUT - Timeout occurred \n - * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n - * @ref SOCKERR_SOCKNUM - Invalid socket number \n - * @ref SOCKERR_DATALEN - zero data length \n - * @ref SOCK_BUSY - Socket is busy. - */ -int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Receive data from the connected peer. - * @details It is used to read incoming data from the connected socket.\n - * It waits for data as much as the application wants to receive. - * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n - * In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer. \n - * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. \n - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @param buf Pointer buffer to read incoming data. - * @param len The max data length of data in buf. - * @return @b Success : The real received data size \n - * @b Fail :\n - * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n - * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n - * @ref SOCKERR_SOCKNUM - Invalid socket number \n - * @ref SOCKERR_DATALEN - zero data length \n - * @ref SOCK_BUSY - Socket is busy. - */ -int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Sends datagram to the peer with destination IP address and port number passed as parameter. - * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n - * Even if the connectionless socket has been previously connected to a specific address, - * the address and port number parameters override the destination address for that particular datagram only. - * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than len. - * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @param buf Pointer buffer to send outgoing data. - * @param len The byte length of data in buf. - * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. - * @param port Destination port number. - * - * @return @b Success : The sent data size \n - * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n - * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n - * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n - * @ref SOCKERR_DATALEN - zero data length \n - * @ref SOCKERR_IPINVALID - Wrong server IP address\n - * @ref SOCKERR_PORTZERO - Server port zero\n - * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n - * @ref SOCKERR_TIMEOUT - Timeout occurred \n - * @ref SOCK_BUSY - Socket is busy. - */ -int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); - -/** - * @ingroup WIZnet_socket_APIs - * @brief Receive datagram of UDP or MACRAW - * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n - * This function is used to receive UDP and MAC_RAW mode, and handle the header as well. - * This function can divide to received the packet data. - * On the MACRAW SOCKET, the addr and port parameters are ignored. - * @note In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer - * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. - * - * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. - * @param buf Pointer buffer to read incoming data. - * @param len The max data length of data in buf. - * When the received packet size <= len, receives data as packet sized. - * When others, receives data as len. - * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. - * It is valid only when the first call recvfrom for receiving the packet. - * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). - * @param port Pointer variable of destination port number. - * It is valid only when the first call recvform for receiving the packet. -* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). - * - * @return @b Success : This function return real received data size for success.\n - * @b Fail : @ref SOCKERR_DATALEN - zero data length \n - * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n - * @ref SOCKERR_SOCKNUM - Invalid socket number \n - * @ref SOCKBUSY - Socket is busy. - */ -int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); - - -///////////////////////////// -// SOCKET CONTROL & OPTION // -///////////////////////////// -#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). -#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). - -/** - * @defgroup DATA_TYPE DATA TYPE - */ - -/** - * @ingroup DATA_TYPE - * @brief The kind of Socket Interrupt. - * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() - */ -typedef enum -{ - SIK_CONNECTED = (1 << 0), ///< connected - SIK_DISCONNECTED = (1 << 1), ///< disconnected - SIK_RECEIVED = (1 << 2), ///< data received - SIK_TIMEOUT = (1 << 3), ///< timeout occurred - SIK_SENT = (1 << 4), ///< send ok - SIK_ALL = 0x1F, ///< all interrupt -}sockint_kind; - -/** - * @ingroup DATA_TYPE - * @brief The type of @ref ctlsocket(). - */ -typedef enum -{ - CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK - CS_GET_IOMODE, ///< get socket IO mode - CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory - CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory - CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind - CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind - CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind - CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind -}ctlsock_type; - - -/** - * @ingroup DATA_TYPE - * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() - */ -typedef enum -{ - SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to flag in @ref socket(). - SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) - SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) - SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) - SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) - SO_DESTPORT, ///< Set/Get the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) -#if _WIZCHIP_ != 5100 - SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode - #if _WIZCHIP_ > 5200 - SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode - #endif -#endif - SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() - SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() - SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR() - SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode. - SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode. -}sockopt_type; - -/** - * @ingroup WIZnet_socket_APIs - * @brief Control socket. - * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. - * Refer to @ref ctlsock_type. - * @param sn socket number - * @param cstype type of control socket. refer to @ref ctlsock_type. - * @param arg Data type and value is determined according to @ref ctlsock_type. \n - * - * - * - * - * - *
@b cstype @b data type@b value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
@ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind @ref SIK_CONNECTED, etc.
- * @return @b Success @ref SOCK_OK \n - * @b fail @ref SOCKERR_ARG - Invalid argument\n - */ -int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg); - -/** - * @ingroup WIZnet_socket_APIs - * @brief set socket options - * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. - * - * @param sn socket number - * @param sotype socket option type. refer to @ref sockopt_type - * @param arg Data type and value is determined according to sotype. \n - * - * - * - * - * - * - * - * - * - *
@b sotype @b data type@b value
@ref SO_TTL uint8_t 0 ~ 255
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ 65535
@ref SO_KEEPALIVESEND null null
@ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
- * @return - * - @b Success : @ref SOCK_OK \n - * - @b Fail - * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n - * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n - * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n - * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n - */ -int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg); - -/** - * @ingroup WIZnet_socket_APIs - * @brief get socket options - * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type - * @param sn socket number - * @param sotype socket option type. refer to @ref sockopt_type - * @param arg Data type and value is determined according to sotype. \n - * - * - * - * - * - * - * - * - * - * - * - * - * - *
@b sotype @b data type@b value
@ref SO_FLAG uint8_t @ref SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t
@ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
@ref SO_SENDBUF uint16_t 0 ~ 65535
@ref SO_RECVBUF uint16_t 0 ~ 65535
@ref SO_STATUS uint8_t @ref SOCK_ESTABLISHED, etc..
@ref SO_REMAINSIZE uint16_t 0~ 65535
@ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc...
- * @return - * - @b Success : @ref SOCK_OK \n - * - @b Fail - * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n - * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n - * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n - * @note - * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n - * When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, - * This means the zero byte UDP data(UDP Header only) received. - */ -int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg); - -#endif // _WIZCHIP_SOCKET_H_ diff --git a/drivers/wiznet5k/ethernet/w5200/w5200.c b/drivers/wiznet5k/ethernet/w5200/w5200.c deleted file mode 100644 index a84d3c9fa7bc..000000000000 --- a/drivers/wiznet5k/ethernet/w5200/w5200.c +++ /dev/null @@ -1,215 +0,0 @@ -// dpgeorge: this file taken from w5500/w5500.c and adapted to W5200 - -//***************************************************************************** -// -//! \file w5500.c -//! \brief W5500 HAL Interface. -//! \version 1.0.1 -//! \date 2013/10/21 -//! \par Revision history -//! <2014/05/01> V1.0.2 -//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 -//! Fixed the problem on porting into under 32bit MCU -//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh -//! Thank for your interesting and serious advices. -//! <2013/10/21> 1st Release -//! <2013/12/20> V1.0.1 -//! 1. Remove warning -//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ -//! for loop optimized(removed). refer to M20131220 -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#include "w5200.h" - -#if WIZCHIP_USE_MAX_BUFFER -// This option is intended to be used when MACRAW mode is enabled, to allow -// the single raw socket to use all the available buffer space. -#define SMASK (16 * 1024 - 1) /* tx buffer mask */ -#define RMASK (16 * 1024 - 1) /* rx buffer mask */ -#define SSIZE (16 * 1024) /* max tx buffer size */ -#define RSIZE (16 * 1024) /* max rx buffer size */ -#else -#define SMASK (0x7ff) /* tx buffer mask */ -#define RMASK (0x7ff) /* rx buffer mask */ -#define SSIZE (2048) /* max tx buffer size */ -#define RSIZE (2048) /* max rx buffer size */ -#endif - -#define TXBUF_BASE (0x8000) -#define RXBUF_BASE (0xc000) -#define SBASE(sn) (TXBUF_BASE + SSIZE * (sn)) /* tx buffer base for socket sn */ -#define RBASE(sn) (RXBUF_BASE + RSIZE * (sn)) /* rx buffer base for socket sn */ - -uint8_t WIZCHIP_READ(uint32_t AddrSel) { - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - uint8_t spi_data[4] = { - AddrSel >> 8, - AddrSel, - 0x00, - 0x01, - }; - WIZCHIP.IF.SPI._write_bytes(spi_data, 4); - uint8_t ret; - WIZCHIP.IF.SPI._read_bytes(&ret, 1); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); - - return ret; -} - -void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - uint8_t spi_data[5] = { - AddrSel >> 8, - AddrSel, - 0x80, - 0x01, - wb, - }; - WIZCHIP.IF.SPI._write_bytes(spi_data, 5); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); -} - -void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) { - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - uint8_t spi_data[4] = { - AddrSel >> 8, - AddrSel, - 0x00 | ((len >> 8) & 0x7f), - len & 0xff, - }; - WIZCHIP.IF.SPI._write_bytes(spi_data, 4); - WIZCHIP.IF.SPI._read_bytes(pBuf, len); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); -} - -void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) { - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - uint8_t spi_data[4] = { - AddrSel >> 8, - AddrSel, - 0x80 | ((len >> 8) & 0x7f), - len & 0xff, - }; - WIZCHIP.IF.SPI._write_bytes(spi_data, 4); - WIZCHIP.IF.SPI._write_bytes(pBuf, len); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); -} - -uint16_t getSn_TX_FSR(uint8_t sn) { - uint16_t val = 0, val1 = 0; - do { - val1 = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1); - if (val1 != 0) { - val = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1); - } - } while (val != val1); - return val; -} - -uint16_t getSn_RX_RSR(uint8_t sn) { - uint16_t val = 0, val1 = 0; - do { - val1 = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1); - if (val1 != 0) { - val = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1); - } - } while (val != val1); - return val; -} - -void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { - if (len == 0) { - return; - } - - uint16_t ptr = getSn_TX_WR(sn); - uint16_t offset = ptr & SMASK; - uint32_t addr = offset + SBASE(sn); - - if (offset + len > SSIZE) { - // implement wrap-around circular buffer - uint16_t size = SSIZE - offset; - WIZCHIP_WRITE_BUF(addr, wizdata, size); - WIZCHIP_WRITE_BUF(SBASE(sn), wizdata + size, len - size); - } else { - WIZCHIP_WRITE_BUF(addr, wizdata, len); - } - - ptr += len; - setSn_TX_WR(sn, ptr); -} - -void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { - if (len == 0) { - return; - } - - uint16_t ptr = getSn_RX_RD(sn); - uint16_t offset = ptr & RMASK; - uint16_t addr = RBASE(sn) + offset; - - if (offset + len > RSIZE) { - // implement wrap-around circular buffer - uint16_t size = RSIZE - offset; - WIZCHIP_READ_BUF(addr, wizdata, size); - WIZCHIP_READ_BUF(RBASE(sn), wizdata + size, len - size); - } else { - WIZCHIP_READ_BUF(addr, wizdata, len); - } - - ptr += len; - setSn_RX_RD(sn, ptr); -} - -void wiz_recv_ignore(uint8_t sn, uint16_t len) { - uint16_t ptr = getSn_RX_RD(sn); - ptr += len; - setSn_RX_RD(sn, ptr); -} diff --git a/drivers/wiznet5k/ethernet/w5200/w5200.h b/drivers/wiznet5k/ethernet/w5200/w5200.h deleted file mode 100644 index 63561940f8b5..000000000000 --- a/drivers/wiznet5k/ethernet/w5200/w5200.h +++ /dev/null @@ -1,2092 +0,0 @@ -// dpgeorge: this file taken from w5500/w5500.h and adapted to W5200 - -//***************************************************************************** -// -//! \file w5500.h -//! \brief W5500 HAL Header File. -//! \version 1.0.0 -//! \date 2013/10/21 -//! \par Revision history -//! <2013/10/21> 1st Release -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#ifndef _W5200_H_ -#define _W5200_H_ - -#include -#include "../wizchip_conf.h" -//#include "board.h" - -#define _W5200_IO_BASE_ 0x00000000 - -#define WIZCHIP_CREG_ADDR(addr) (_W5200_IO_BASE_ + (addr)) - -#define WIZCHIP_CH_BASE (0x4000) -#define WIZCHIP_CH_SIZE (0x100) -#define WIZCHIP_SREG_ADDR(sn, addr) (_W5200_IO_BASE_ + WIZCHIP_CH_BASE + (sn) * WIZCHIP_CH_SIZE + (addr)) - -////////////////////////////// -//-------------------------- defgroup --------------------------------- -/** - * @defgroup W5500 W5500 - * - * @brief WHIZCHIP register defines and I/O functions of @b W5500. - * - * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group - * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function - */ - - -/** - * @defgroup WIZCHIP_register WIZCHIP register - * @ingroup W5500 - * - * @brief WHIZCHIP register defines register group of @b W5500. - * - * - @ref Common_register_group : Common register group - * - @ref Socket_register_group : \c SOCKET n register group - */ - - -/** - * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions - * @ingroup W5500 - * - * @brief This supports the basic I/O functions for @ref WIZCHIP_register. - * - * - Basic I/O function \n - * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n - * - * - @ref Common_register_group access functions \n - * -# @b Mode \n - * getMR(), setMR() - * -# @b Interrupt \n - * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() - * -# Network Information \n - * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() - * -# @b Retransmission \n - * getRCR(), setRCR(), getRTR(), setRTR() - * -# @b PPPoE \n - * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() - * -# ICMP packet \n - * getUIPR(), getUPORTR() - * -# @b etc. \n - * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n - * - * - \ref Socket_register_group access functions \n - * -# SOCKET control \n - * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() - * -# SOCKET information \n - * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() - * getSn_MSSR(), setSn_MSSR() - * -# SOCKET communication \n - * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n - * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n - * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n - * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() - * -# IP header field \n - * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n - * getSn_TTL(), setSn_TTL() - */ - - - -/** - * @defgroup Common_register_group Common register - * @ingroup WIZCHIP_register - * - * @brief Common register group\n - * It set the basic for the networking\n - * It set the configuration such as interrupt, network information, ICMP, etc. - * @details - * @sa MR : Mode register. - * @sa GAR, SUBR, SHAR, SIPR - * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. - * @sa RTR, RCR : Data retransmission. - * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. - * @sa UIPR, UPORTR : ICMP message. - * @sa PHYCFGR, VERSIONR : etc. - */ - - - -/** - * @defgroup Socket_register_group Socket register - * @ingroup WIZCHIP_register - * - * @brief Socket register group.\n - * Socket register configures and control SOCKETn which is necessary to data communication. - * @details - * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control - * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information - * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. - * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication - */ - - - - /** - * @defgroup Basic_IO_function Basic I/O function - * @ingroup WIZCHIP_IO_Functions - * @brief These are basic input/output functions to read values from register or write values to register. - */ - -/** - * @defgroup Common_register_access_function Common register access functions - * @ingroup WIZCHIP_IO_Functions - * @brief These are functions to access common registers. - */ - -/** - * @defgroup Socket_register_access_function Socket register access functions - * @ingroup WIZCHIP_IO_Functions - * @brief These are functions to access socket registers. - */ - -//------------------------------- defgroup end -------------------------------------------- -//----------------------------- W5500 Common Registers IOMAP ----------------------------- -/** - * @ingroup Common_register_group - * @brief Mode Register address(R/W)\n - * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. - * @details Each bit of @ref MR defined as follows. - * - * - * - *
7 6 5 4 3 2 1 0
RST Reserved WOL PB PPPoE Reserved FARP Reserved
- * - \ref MR_RST : Reset - * - \ref MR_WOL : Wake on LAN - * - \ref MR_PB : Ping block - * - \ref MR_PPPOE : PPPoE mode - * - \ref MR_FARP : Force ARP mode - */ -#define MR WIZCHIP_CREG_ADDR(0x0000) - -/** - * @ingroup Common_register_group - * @brief Gateway IP Register address(R/W) - * @details @ref GAR configures the default gateway address. - */ -#define GAR WIZCHIP_CREG_ADDR(0x0001) - -/** - * @ingroup Common_register_group - * @brief Subnet mask Register address(R/W) - * @details @ref SUBR configures the subnet mask address. - */ -#define SUBR WIZCHIP_CREG_ADDR(0x0005) - -/** - * @ingroup Common_register_group - * @brief Source MAC Register address(R/W) - * @details @ref SHAR configures the source hardware address. - */ -#define SHAR WIZCHIP_CREG_ADDR(0x0009) - -/** - * @ingroup Common_register_group - * @brief Source IP Register address(R/W) - * @details @ref SIPR configures the source IP address. - */ -#define SIPR WIZCHIP_CREG_ADDR(0x000f) - -/** - * @ingroup Common_register_group - * @brief Set Interrupt low level timer register address(R/W) - * @details @ref INTLEVEL configures the Interrupt Assert Time. - */ -//#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Interrupt Register(R/W) - * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. - * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n - * Each bit of @ref IR defined as follows. - * - * - * - *
7 6 5 4 3 2 1 0
CONFLICT UNREACH PPPoE MP Reserved Reserved Reserved Reserved
- * - \ref IR_CONFLICT : IP conflict - * - \ref IR_UNREACH : Destination unreachable - * - \ref IR_PPPoE : PPPoE connection close - * - \ref IR_MP : Magic packet - */ -#define IR WIZCHIP_CREG_ADDR(0x0015) - -/** - * @ingroup Common_register_group - * @brief Interrupt mask register(R/W) - * @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. - * When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, - * if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n - * Each bit of @ref IMR defined as the following. - * - * - * - *
7 6 5 4 3 2 1 0
IM_IR7 IM_IR6 IM_IR5 IM_IR4 Reserved Reserved Reserved Reserved
- * - \ref IM_IR7 : IP Conflict Interrupt Mask - * - \ref IM_IR6 : Destination unreachable Interrupt Mask - * - \ref IM_IR5 : PPPoE Close Interrupt Mask - * - \ref IM_IR4 : Magic Packet Interrupt Mask - */ -#define IMR WIZCHIP_CREG_ADDR(0x0016) - -/** - * @ingroup Common_register_group - * @brief Socket Interrupt Register(R/W) - * @details @ref SIR indicates the interrupt status of Socket.\n - * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n - * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ -//#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Socket Interrupt Mask Register(R/W) - * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. - * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. - * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is - */ -//#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Timeout register address( 1 is 100us )(R/W) - * @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 - * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response - * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). - * If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. - */ -#define RTR WIZCHIP_CREG_ADDR(0x0017) - -/** - * @ingroup Common_register_group - * @brief Retry count register(R/W) - * @details @ref RCR configures the number of time of retransmission. - * When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . - */ -#define RCR WIZCHIP_CREG_ADDR(0x0019) - -/** - * @ingroup Common_register_group - * @brief PPP LCP Request Timer register in PPPoE mode(R/W) - * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. - */ -#define PTIMER WIZCHIP_CREG_ADDR(0x0028) - -/** - * @ingroup Common_register_group - * @brief PPP LCP Magic number register in PPPoE mode(R/W) - * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. - */ -#define PMAGIC WIZCHIP_CREG_ADDR(0x0029) - -/** - * @ingroup Common_register_group - * @brief PPP Destination MAC Register address(R/W) - * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. - */ -//#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP Session Identification Register(R/W) - * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. - */ -//#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP Maximum Segment Size(MSS) register(R/W) - * @details @ref PMRU configures the maximum receive unit of PPPoE. - */ -//#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Unreachable IP register address in UDP mode(R) - * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number - * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates - * the destination IP address & port number respectively. - */ -//#define UIPR (_W5500_IO_BASE_ + (0x002a << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Unreachable Port register address in UDP mode(R) - * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number - * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR - * indicates the destination IP address & port number respectively. - */ -//#define UPORTR (_W5500_IO_BASE_ + (0x002e << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PHY Status Register(R/W) - * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. - */ -//#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) -#define PHYSTATUS WIZCHIP_CREG_ADDR(0x0035) - -// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief chip version register address(R) - * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. - */ -//#define VERSIONR (_W5200_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - - -//----------------------------- W5500 Socket Registers IOMAP ----------------------------- -/** - * @ingroup Socket_register_group - * @brief socket Mode register(R/W) - * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n - * Each bit of @ref Sn_MR defined as the following. - * - * - * - *
7 6 5 4 3 2 1 0
MULTI/MFEN BCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3] Protocol[2] Protocol[1] Protocol[0]
- * - @ref Sn_MR_MULTI : Support UDP Multicasting - * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting - * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag - * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting - * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode - * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating - * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode - * - Protocol - * - * - * - * - * - * - *
Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0 MACRAW
- * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n - * - @ref Sn_MR_UDP : UDP - * - @ref Sn_MR_TCP : TCP - * - @ref Sn_MR_CLOSE : Unused socket - * @note MACRAW mode should be only used in Socket 0. - */ -#define Sn_MR(N) WIZCHIP_SREG_ADDR(N, 0x0000) - -/** - * @ingroup Socket_register_group - * @brief Socket command register(R/W) - * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n - * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. - * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n - * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. - * - @ref Sn_CR_OPEN : Initialize or open socket. - * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) - * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) - * - @ref Sn_CR_DISCON : Send closing request in TCP mode. - * - @ref Sn_CR_CLOSE : Close socket. - * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. - * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. - * - @ref Sn_CR_SEND_KEEP : Send keep alive message. - * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. - */ -#define Sn_CR(N) WIZCHIP_SREG_ADDR(N, 0x0001) - -/** - * @ingroup Socket_register_group - * @brief Socket interrupt register(R) - * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n - * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n - * In order to clear the @ref Sn_IR bit, the host should write the bit to \n - * - * - * - *
7 6 5 4 3 2 1 0
Reserved Reserved Reserved SEND_OK TIMEOUT RECV DISCON CON
- * - \ref Sn_IR_SENDOK : SEND_OK Interrupt - * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt - * - \ref Sn_IR_RECV : RECV Interrupt - * - \ref Sn_IR_DISCON : DISCON Interrupt - * - \ref Sn_IR_CON : CON Interrupt - */ -#define Sn_IR(N) WIZCHIP_SREG_ADDR(N, 0x0002) - -/** - * @ingroup Socket_register_group - * @brief Socket status register(R) - * @details @ref Sn_SR indicates the status of Socket n.\n - * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. - * @par Normal status - * - @ref SOCK_CLOSED : Closed - * - @ref SOCK_INIT : Initiate state - * - @ref SOCK_LISTEN : Listen state - * - @ref SOCK_ESTABLISHED : Success to connect - * - @ref SOCK_CLOSE_WAIT : Closing state - * - @ref SOCK_UDP : UDP socket - * - @ref SOCK_MACRAW : MAC raw mode socket - *@par Temporary status during changing the status of Socket n. - * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. - * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. - * - @ref SOCK_FIN_WAIT : Connection state - * - @ref SOCK_CLOSING : Closing state - * - @ref SOCK_TIME_WAIT : Closing state - * - @ref SOCK_LAST_ACK : Closing state - */ -#define Sn_SR(N) WIZCHIP_SREG_ADDR(N, 0x0003) - -/** - * @ingroup Socket_register_group - * @brief source port register(R/W) - * @details @ref Sn_PORT configures the source port number of Socket n. - * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. - */ -#define Sn_PORT(N) WIZCHIP_SREG_ADDR(N, 0x0004) - -/** - * @ingroup Socket_register_group - * @brief Peer MAC register address(R/W) - * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or - * it indicates that it is acquired in ARP-process by CONNECT/SEND command. - */ -#define Sn_DHAR(N) WIZCHIP_SREG_ADDR(N, 0x0006) - -/** - * @ingroup Socket_register_group - * @brief Peer IP register address(R/W) - * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. - * In TCP client mode, it configures an IP address of �TCP serverbefore CONNECT command. - * In TCP server mode, it indicates an IP address of �TCP clientafter successfully establishing connection. - * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. - */ -#define Sn_DIPR(N) WIZCHIP_SREG_ADDR(N, 0x000c) - -/** - * @ingroup Socket_register_group - * @brief Peer port register address(R/W) - * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. - * In �TCP clientmode, it configures the listen port number of �TCP serverbefore CONNECT command. - * In �TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. - * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. - */ -#define Sn_DPORT(N) WIZCHIP_SREG_ADDR(N, 0x0010) - -/** - * @ingroup Socket_register_group - * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) - * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. - */ -#define Sn_MSSR(N) WIZCHIP_SREG_ADDR(N, 0x0012) - -// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief IP Type of Service(TOS) Register(R/W) - * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. - * It is set before OPEN command. - */ -#define Sn_TOS(N) WIZCHIP_SREG_ADDR(N, 0x0015) -/** - * @ingroup Socket_register_group - * @brief IP Time to live(TTL) Register(R/W) - * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. - * It is set before OPEN command. - */ -#define Sn_TTL(N) WIZCHIP_SREG_ADDR(N, 0x0016) -// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Receive memory size register(R/W) - * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. - * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. - * If a different size is configured, the data cannot be normally received from a peer. - * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, - * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. - * When exceeded, the data reception error is occurred. - */ -#define Sn_RXBUF_SIZE(N) WIZCHIP_SREG_ADDR(N, 0x001e) - -/** - * @ingroup Socket_register_group - * @brief Transmit memory size register(R/W) - * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. - * If a different size is configured, the data can�t be normally transmitted to a peer. - * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, - * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. - * When exceeded, the data transmission error is occurred. - */ -#define Sn_TXBUF_SIZE(N) WIZCHIP_SREG_ADDR(N, 0x001f) - -/** - * @ingroup Socket_register_group - * @brief Transmit free memory size register(R) - * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. - * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. - * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, - * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, - * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. - */ -#define Sn_TX_FSR(N) WIZCHIP_SREG_ADDR(N, 0x0020) - -/** - * @ingroup Socket_register_group - * @brief Transmit memory read pointer register address(R) - * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. - * After its initialization, it is auto-increased by SEND command. - * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. - * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. - * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), - * then the carry bit is ignored and will automatically update with the lower 16bits value. - */ -#define Sn_TX_RD(N) WIZCHIP_SREG_ADDR(N, 0x0022) - -/** - * @ingroup Socket_register_group - * @brief Transmit memory write pointer register address(R/W) - * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n - * It should be read or be updated like as follows.\n - * 1. Read the starting address for saving the transmitting data.\n - * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n - * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. - * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), - * then the carry bit is ignored and will automatically update with the lower 16bits value.\n - * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command - */ -#define Sn_TX_WR(N) WIZCHIP_SREG_ADDR(N, 0x0024) - -/** - * @ingroup Socket_register_group - * @brief Received data size register(R) - * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. - * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between - * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD) - */ -#define Sn_RX_RSR(N) WIZCHIP_SREG_ADDR(N, 0x0026) - -/** - * @ingroup Socket_register_group - * @brief Read point of Receive memory(R/W) - * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n - * 1. Read the starting save address of the received data.\n - * 2. Read data from the starting address of Socket n RX Buffer.\n - * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. - * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, - * update with the lower 16bits value ignored the carry bit.\n - * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. - */ -#define Sn_RX_RD(N) WIZCHIP_SREG_ADDR(N, 0x0028) - -/** - * @ingroup Socket_register_group - * @brief Write point of Receive memory(R) - * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. - * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), - * then the carry bit is ignored and will automatically update with the lower 16bits value. - */ -#define Sn_RX_WR(N) WIZCHIP_SREG_ADDR(N, 0x002a) - -/** - * @ingroup Socket_register_group - * @brief socket interrupt mask register(R) - * @details @ref Sn_IMR masks the interrupt of Socket n. - * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is - * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is - * Host is interrupted by asserted INTn PIN to low. - */ -//#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Fragment field value in IP header register(R/W) - * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). - */ -//#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Keep Alive Timer register(R/W) - * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, - * and ignored in other modes. The time unit is 5s. - * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. - * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). - * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, - * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). - * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. - */ -//#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - - -//----------------------------- W5500 Register values ----------------------------- - -/* MODE register values */ -/** - * @brief Reset - * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. - */ -#define MR_RST 0x80 - -/** - * @brief Wake on LAN - * @details 0 : Disable WOL mode\n - * 1 : Enable WOL mode\n - * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. - * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) - * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and - * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. - */ -#define MR_WOL 0x20 - -/** - * @brief Ping block - * @details 0 : Disable Ping block\n - * 1 : Enable Ping block\n - * If the bit is it blocks the response to a ping request. - */ -#define MR_PB 0x10 - -/** - * @brief Enable PPPoE - * @details 0 : DisablePPPoE mode\n - * 1 : EnablePPPoE mode\n - * If you use ADSL, this bit should be - */ -#define MR_PPPOE 0x08 - -/** - * @brief Enable UDP_FORCE_ARP CHECHK - * @details 0 : Disable Force ARP mode\n - * 1 : Enable Force ARP mode\n - * In Force ARP mode, It forces on sending ARP Request whenever data is sent. - */ -#define MR_FARP 0x02 - -/* IR register values */ -/** - * @brief Check IP conflict. - * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. - */ -#define IR_CONFLICT 0x80 - -/** - * @brief Get the destination unreachable message in UDP sending. - * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as - * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. - */ -#define IR_UNREACH 0x40 - -/** - * @brief Get the PPPoE close message. - * @details When PPPoE is disconnected during PPPoE mode, this bit is set. - */ -#define IR_PPPoE 0x20 - -/** - * @brief Get the magic packet interrupt. - * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. - */ -#define IR_MP 0x10 - - -/* PHYCFGR register value */ -#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. -#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value -#define PHYCFGR_OPMDC_ALLA (7<<3) -#define PHYCFGR_OPMDC_PDOWN (6<<3) -#define PHYCFGR_OPMDC_NA (5<<3) -#define PHYCFGR_OPMDC_100FA (4<<3) -#define PHYCFGR_OPMDC_100F (3<<3) -#define PHYCFGR_OPMDC_100H (2<<3) -#define PHYCFGR_OPMDC_10F (1<<3) -#define PHYCFGR_OPMDC_10H (0<<3) -#define PHYCFGR_DPX_FULL (1<<2) -#define PHYCFGR_DPX_HALF (0<<2) -#define PHYCFGR_SPD_100 (1<<1) -#define PHYCFGR_SPD_10 (0<<1) -#define PHYCFGR_LNK_ON (1<<0) -#define PHYCFGR_LNK_OFF (0<<0) - -// PHYSTATUS register -#define PHYSTATUS_POWERDOWN (0x08) -#define PHYSTATUS_LINK (0x20) - -/* IMR register values */ -/** - * @brief IP Conflict Interrupt Mask. - * @details 0: Disable IP Conflict Interrupt\n - * 1: Enable IP Conflict Interrupt - */ -#define IM_IR7 0x80 - -/** - * @brief Destination unreachable Interrupt Mask. - * @details 0: Disable Destination unreachable Interrupt\n - * 1: Enable Destination unreachable Interrupt - */ -#define IM_IR6 0x40 - -/** - * @brief PPPoE Close Interrupt Mask. - * @details 0: Disable PPPoE Close Interrupt\n - * 1: Enable PPPoE Close Interrupt - */ -#define IM_IR5 0x20 - -/** - * @brief Magic Packet Interrupt Mask. - * @details 0: Disable Magic Packet Interrupt\n - * 1: Enable Magic Packet Interrupt - */ -#define IM_IR4 0x10 - -/* Sn_MR Default values */ -/** - * @brief Support UDP Multicasting - * @details 0 : disable Multicasting\n - * 1 : enable Multicasting\n - * This bit is applied only during UDP mode(P[3:0] = 010.\n - * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number - * before Socket n is opened by OPEN command of @ref Sn_CR. - */ -#define Sn_MR_MULTI 0x80 - -/** - * @brief Broadcast block in UDP Multicasting. - * @details 0 : disable Broadcast Blocking\n - * 1 : enable Broadcast Blocking\n - * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m - * In addition, This bit does when MACRAW mode(P[3:0] = 100 - */ -//#define Sn_MR_BCASTB 0x40 - -/** - * @brief No Delayed Ack(TCP), Multicast flag - * @details 0 : Disable No Delayed ACK option\n - * 1 : Enable No Delayed ACK option\n - * This bit is applied only during TCP mode (P[3:0] = 001.\n - * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n - * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. - */ -#define Sn_MR_ND 0x20 - -/** - * @brief Unicast Block in UDP Multicasting - * @details 0 : disable Unicast Blocking\n - * 1 : enable Unicast Blocking\n - * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = - */ -//#define Sn_MR_UCASTB 0x10 - -/** - * @brief MAC LAYER RAW SOCK - * @details This configures the protocol mode of Socket n. - * @note MACRAW mode should be only used in Socket 0. - */ -#define Sn_MR_MACRAW 0x04 - -#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ - -/** - * @brief UDP - * @details This configures the protocol mode of Socket n. - */ -#define Sn_MR_UDP 0x02 - -/** - * @brief TCP - * @details This configures the protocol mode of Socket n. - */ -#define Sn_MR_TCP 0x01 - -/** - * @brief Unused socket - * @details This configures the protocol mode of Socket n. - */ -#define Sn_MR_CLOSE 0x00 - -/* Sn_MR values used with Sn_MR_MACRAW */ -/** - * @brief MAC filter enable in @ref Sn_MR_MACRAW mode - * @details 0 : disable MAC Filtering\n - * 1 : enable MAC Filtering\n - * This bit is applied only during MACRAW mode(P[3:0] = 100.\n - * When set as W5500 can only receive broadcasting packet or packet sent to itself. - * When this bit is W5500 can receive all packets on Ethernet. - * If user wants to implement Hybrid TCP/IP stack, - * it is recommended that this bit is set as for reducing host overhead to process the all received packets. - */ -#define Sn_MR_MFEN Sn_MR_MULTI - -/** - * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode - * @details 0 : using IGMP version 2\n - * 1 : using IGMP version 1\n - * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = - * It configures the version for IGMP messages (Join/Leave/Report). - */ -#define Sn_MR_MMB Sn_MR_ND - -/** - * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode - * @details 0 : disable IPv6 Blocking\n - * 1 : enable IPv6 Blocking\n - * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. - */ -#define Sn_MR_MIP6B Sn_MR_UCASTB - -/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ -/** - * @brief IGMP version used in UDP mulitcasting - * @details 0 : disable Multicast Blocking\n - * 1 : enable Multicast Blocking\n - * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. - */ -#define Sn_MR_MC Sn_MR_ND - -/* Sn_MR alternate values */ -/** - * @brief For Berkeley Socket API - */ -#define SOCK_STREAM Sn_MR_TCP - -/** - * @brief For Berkeley Socket API - */ -#define SOCK_DGRAM Sn_MR_UDP - - -/* Sn_CR values */ -/** - * @brief Initialize or open socket - * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). - * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n - * - * - * - * - * - * - *
\b Sn_MR (P[3:0]) \b Sn_SR
Sn_MR_CLOSE (000
Sn_MR_TCP (001 SOCK_INIT (0x13)
Sn_MR_UDP (010 SOCK_UDP (0x22)
S0_MR_MACRAW (100 SOCK_MACRAW (0x02)
- */ -#define Sn_CR_OPEN 0x01 - -/** - * @brief Wait connection request in TCP mode(Server mode) - * @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). - * In this mode, Socket n operates as a �TCP serverand waits for connection-request (SYN packet) from any �TCP client - * The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. - * When a �TCP clientconnection request is successfully established, - * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes - * But when a �TCP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. - */ -#define Sn_CR_LISTEN 0x02 - -/** - * @brief Send connection request in TCP mode(Client mode) - * @details To connect, a connect-request (SYN packet) is sent to b>TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). - * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n - * The connect-request fails in the following three cases.\n - * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n - * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n - * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. - * @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client - */ -#define Sn_CR_CONNECT 0x04 - -/** - * @brief Send closing request in TCP mode - * @details Regardless of b>TCP serveror b>TCP client the DISCON command processes the disconnect-process (b>Active closeor b>Passive close.\n - * @par Active close - * it transmits disconnect-request(FIN packet) to the connected peer\n - * @par Passive close - * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n - * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n - * Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. - * @note Valid only in TCP mode. - */ -#define Sn_CR_DISCON 0x08 - -/** - * @brief Close socket - * @details Sn_SR is changed to @ref SOCK_CLOSED. - */ -#define Sn_CR_CLOSE 0x10 - -/** - * @brief Update TX buffer pointer and send data - * @details SEND transmits all the data in the Socket n TX buffer.\n - * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, - * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). - */ -#define Sn_CR_SEND 0x20 - -/** - * @brief Send data with MAC address, so without ARP process - * @details The basic operation is same as SEND.\n - * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n - * But SEND_MAC transmits data without the automatic ARP-process.\n - * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. - * @note Valid only in UDP mode. - */ -#define Sn_CR_SEND_MAC 0x21 - -/** - * @brief Send keep alive message - * @details It checks the connection status by sending 1byte keep-alive packet.\n - * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. - * @note Valid only in TCP mode. - */ -#define Sn_CR_SEND_KEEP 0x22 - -/** - * @brief Update RX buffer pointer and receive data - * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n - * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), - * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). - */ -#define Sn_CR_RECV 0x40 - -/* Sn_IR values */ -/** - * @brief SEND_OK Interrupt - * @details This is issued when SEND command is completed. - */ -#define Sn_IR_SENDOK 0x10 - -/** - * @brief TIMEOUT Interrupt - * @details This is issued when ARPTO or TCPTO occurs. - */ -#define Sn_IR_TIMEOUT 0x08 - -/** - * @brief RECV Interrupt - * @details This is issued whenever data is received from a peer. - */ -#define Sn_IR_RECV 0x04 - -/** - * @brief DISCON Interrupt - * @details This is issued when FIN or FIN/ACK packet is received from a peer. - */ -#define Sn_IR_DISCON 0x02 - -/** - * @brief CON Interrupt - * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. - */ -#define Sn_IR_CON 0x01 - -/* Sn_SR values */ -/** - * @brief Closed - * @details This indicates that Socket n is released.\N - * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. - */ -#define SOCK_CLOSED 0x00 - -/** - * @brief Initiate state - * @details This indicates Socket n is opened with TCP mode.\N - * It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N - * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. - */ -#define SOCK_INIT 0x13 - -/** - * @brief Listen state - * @details This indicates Socket n is operating as b>TCP servermode and waiting for connection-request (SYN packet) from a peer (b>TCP client.\n - * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n - * Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . - */ -#define SOCK_LISTEN 0x14 - -/** - * @brief Connection state - * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n - * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n - * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n - * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. - */ -#define SOCK_SYNSENT 0x15 - -/** - * @brief Connection state - * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n - * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n - * If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . - */ -#define SOCK_SYNRECV 0x16 - -/** - * @brief Success to connect - * @details This indicates the status of the connection of Socket n.\n - * It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVERprocessed the SYN packet from the b>TCP CLIENTduring @ref SOCK_LISTEN, or - * when the CONNECT command is successful.\n - * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. - */ -#define SOCK_ESTABLISHED 0x17 - -/** - * @brief Closing state - * @details These indicate Socket n is closing.\n - * These are shown in disconnect-process such as active-close and passive-close.\n - * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. - */ -#define SOCK_FIN_WAIT 0x18 - -/** - * @brief Closing state - * @details These indicate Socket n is closing.\n - * These are shown in disconnect-process such as active-close and passive-close.\n - * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. - */ -#define SOCK_CLOSING 0x1A - -/** - * @brief Closing state - * @details These indicate Socket n is closing.\n - * These are shown in disconnect-process such as active-close and passive-close.\n - * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. - */ -#define SOCK_TIME_WAIT 0x1B - -/** - * @brief Closing state - * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n - * This is half-closing status, and data can be transferred.\n - * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. - */ -#define SOCK_CLOSE_WAIT 0x1C - -/** - * @brief Closing state - * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n - * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . - */ -#define SOCK_LAST_ACK 0x1D - -/** - * @brief UDP socket - * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n - * It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n - * Unlike TCP mode, data can be transfered without the connection-process. - */ -#define SOCK_UDP 0x22 - -//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ - -/** - * @brief MAC raw mode socket - * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n - * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n - * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. - */ -#define SOCK_MACRAW 0x42 - -//#define SOCK_PPPOE 0x5F - -/* IP PROTOCOL */ -#define IPPROTO_IP 0 //< Dummy for IP -#define IPPROTO_ICMP 1 //< Control message protocol -#define IPPROTO_IGMP 2 //< Internet group management protocol -#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) -#define IPPROTO_TCP 6 //< TCP -#define IPPROTO_PUP 12 //< PUP -#define IPPROTO_UDP 17 //< UDP -#define IPPROTO_IDP 22 //< XNS idp -#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol -#define IPPROTO_RAW 255 //< Raw IP packet - - -/** - * @brief Enter a critical section - * - * @details It is provided to protect your shared code which are executed without distribution. \n \n - * - * In non-OS environment, It can be just implemented by disabling whole interrupt.\n - * In OS environment, You can replace it to critical section api supported by OS. - * - * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() - * \sa WIZCHIP_CRITICAL_EXIT() - */ -#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() - -/** - * @brief Exit a critical section - * - * @details It is provided to protect your shared code which are executed without distribution. \n\n - * - * In non-OS environment, It can be just implemented by disabling whole interrupt. \n - * In OS environment, You can replace it to critical section api supported by OS. - * - * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() - * @sa WIZCHIP_CRITICAL_ENTER() - */ -#ifdef _exit -#undef _exit -#endif -#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() - - - -//////////////////////// -// Basic I/O Function // -//////////////////////// - -/** - * @ingroup Basic_IO_function - * @brief It reads 1 byte value from a register. - * @param AddrSel Register address - * @return The value of register - */ -uint8_t WIZCHIP_READ (uint32_t AddrSel); - -/** - * @ingroup Basic_IO_function - * @brief It writes 1 byte value to a register. - * @param AddrSel Register address - * @param wb Write data - * @return void - */ -void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); - -/** - * @ingroup Basic_IO_function - * @brief It reads sequence data from registers. - * @param AddrSel Register address - * @param pBuf Pointer buffer to read data - * @param len Data length - */ -void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); - -/** - * @ingroup Basic_IO_function - * @brief It writes sequence data to registers. - * @param AddrSel Register address - * @param pBuf Pointer buffer to write data - * @param len Data length - */ -void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); - -///////////////////////////////// -// Common Register I/O function // -///////////////////////////////// -/** - * @ingroup Common_register_access_function - * @brief Set Mode Register - * @param (uint8_t)mr The value to be set. - * @sa getMR() - */ -#define setMR(mr) \ - WIZCHIP_WRITE(MR,mr) - - -/** - * @ingroup Common_register_access_function - * @brief Get Mode Register - * @return uint8_t. The value of Mode register. - * @sa setMR() - */ -#define getMR() \ - WIZCHIP_READ(MR) - -/** - * @ingroup Common_register_access_function - * @brief Set gateway IP address - * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. - * @sa getGAR() - */ -#define setGAR(gar) \ - WIZCHIP_WRITE_BUF(GAR,gar,4) - -/** - * @ingroup Common_register_access_function - * @brief Get gateway IP address - * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. - * @sa setGAR() - */ -#define getGAR(gar) \ - WIZCHIP_READ_BUF(GAR,gar,4) - -/** - * @ingroup Common_register_access_function - * @brief Set subnet mask address - * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. - * @sa getSUBR() - */ -#define setSUBR(subr) \ - WIZCHIP_WRITE_BUF(SUBR, subr,4) - - -/** - * @ingroup Common_register_access_function - * @brief Get subnet mask address - * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. - * @sa setSUBR() - */ -#define getSUBR(subr) \ - WIZCHIP_READ_BUF(SUBR, subr, 4) - -/** - * @ingroup Common_register_access_function - * @brief Set local MAC address - * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. - * @sa getSHAR() - */ -#define setSHAR(shar) \ - WIZCHIP_WRITE_BUF(SHAR, shar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Get local MAC address - * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. - * @sa setSHAR() - */ -#define getSHAR(shar) \ - WIZCHIP_READ_BUF(SHAR, shar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Set local IP address - * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. - * @sa getSIPR() - */ -#define setSIPR(sipr) \ - WIZCHIP_WRITE_BUF(SIPR, sipr, 4) - -/** - * @ingroup Common_register_access_function - * @brief Get local IP address - * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. - * @sa setSIPR() - */ -#define getSIPR(sipr) \ - WIZCHIP_READ_BUF(SIPR, sipr, 4) - -/** - * @ingroup Common_register_access_function - * @brief Set INTLEVEL register - * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. - * @sa getINTLEVEL() - */ -// dpgeorge: not yet implemented -#define setINTLEVEL(intlevel) (void)intlevel -#if 0 -#define setINTLEVEL(intlevel) {\ - WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ - } -#endif - - -/** - * @ingroup Common_register_access_function - * @brief Get INTLEVEL register - * @return uint16_t. Value of @ref INTLEVEL register. - * @sa setINTLEVEL() - */ -// dpgeorge: not yet implemented -#define getINTLEVEL() (0) -#if 0 -#define getINTLEVEL() \ - ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) -#endif - -/** - * @ingroup Common_register_access_function - * @brief Set @ref IR register - * @param (uint8_t)ir Value to set @ref IR register. - * @sa getIR() - */ -#define setIR(ir) \ - WIZCHIP_WRITE(IR, (ir & 0xF0)) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref IR register - * @return uint8_t. Value of @ref IR register. - * @sa setIR() - */ -#define getIR() \ - (WIZCHIP_READ(IR) & 0xF0) -/** - * @ingroup Common_register_access_function - * @brief Set @ref IMR register - * @param (uint8_t)imr Value to set @ref IMR register. - * @sa getIMR() - */ -#define setIMR(imr) \ - WIZCHIP_WRITE(IMR, imr) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref IMR register - * @return uint8_t. Value of @ref IMR register. - * @sa setIMR() - */ -#define getIMR() \ - WIZCHIP_READ(IMR) - - -/** - * @ingroup Common_register_access_function - * @brief Set @ref SIR register - * @param (uint8_t)sir Value to set @ref SIR register. - * @sa getSIR() - */ -// dpgeorge: not yet implemented -#define setSIR(sir) ((void)sir) -#if 0 -#define setSIR(sir) \ - WIZCHIP_WRITE(SIR, sir) -#endif - -/** - * @ingroup Common_register_access_function - * @brief Get @ref SIR register - * @return uint8_t. Value of @ref SIR register. - * @sa setSIR() - */ -// dpgeorge: not yet implemented -#define getSIR() (0) -#if 0 -#define getSIR() \ - WIZCHIP_READ(SIR) -#endif - -/** - * @ingroup Common_register_access_function - * @brief Set @ref SIMR register - * @param (uint8_t)simr Value to set @ref SIMR register. - * @sa getSIMR() - */ -// dpgeorge: not yet implemented -#define setSIMR(simr) ((void)simr) -#if 0 -#define setSIMR(simr) \ - WIZCHIP_WRITE(SIMR, simr) -#endif - -/** - * @ingroup Common_register_access_function - * @brief Get @ref SIMR register - * @return uint8_t. Value of @ref SIMR register. - * @sa setSIMR() - */ -// dpgeorge: not yet implemented -#define getSIMR() (0) -#if 0 -#define getSIMR() \ - WIZCHIP_READ(SIMR) -#endif - -/** - * @ingroup Common_register_access_function - * @brief Set @ref RTR register - * @param (uint16_t)rtr Value to set @ref RTR register. - * @sa getRTR() - */ -#define setRTR(rtr) {\ - WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ - WIZCHIP_WRITE(RTR + 1, (uint8_t) rtr); \ - } - -/** - * @ingroup Common_register_access_function - * @brief Get @ref RTR register - * @return uint16_t. Value of @ref RTR register. - * @sa setRTR() - */ -#define getRTR() \ - ((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(RTR + 1)) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref RCR register - * @param (uint8_t)rcr Value to set @ref RCR register. - * @sa getRCR() - */ -#define setRCR(rcr) \ - WIZCHIP_WRITE(RCR, rcr) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref RCR register - * @return uint8_t. Value of @ref RCR register. - * @sa setRCR() - */ -#define getRCR() \ - WIZCHIP_READ(RCR) - -//================================================== test done =========================================================== - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PTIMER register - * @param (uint8_t)ptimer Value to set @ref PTIMER register. - * @sa getPTIMER() - */ -#define setPTIMER(ptimer) \ - WIZCHIP_WRITE(PTIMER, ptimer) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PTIMER register - * @return uint8_t. Value of @ref PTIMER register. - * @sa setPTIMER() - */ -#define getPTIMER() \ - WIZCHIP_READ(PTIMER) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PMAGIC register - * @param (uint8_t)pmagic Value to set @ref PMAGIC register. - * @sa getPMAGIC() - */ -#define setPMAGIC(pmagic) \ - WIZCHIP_WRITE(PMAGIC, pmagic) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PMAGIC register - * @return uint8_t. Value of @ref PMAGIC register. - * @sa setPMAGIC() - */ -#define getPMAGIC() \ - WIZCHIP_READ(PMAGIC) - -/** - * @ingroup Common_register_access_function - * @brief Set PHAR address - * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. - * @sa getPHAR() - */ -#if 0 -#define setPHAR(phar) \ - WIZCHIP_WRITE_BUF(PHAR, phar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Get local IP address - * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. - * @sa setPHAR() - */ -#define getPHAR(phar) \ - WIZCHIP_READ_BUF(PHAR, phar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PSID register - * @param (uint16_t)psid Value to set @ref PSID register. - * @sa getPSID() - */ -#define setPSID(psid) {\ - WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ - } - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PSID register - * @return uint16_t. Value of @ref PSID register. - * @sa setPSID() - */ -//uint16_t getPSID(void); -#define getPSID() \ - ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PMRU register - * @param (uint16_t)pmru Value to set @ref PMRU register. - * @sa getPMRU() - */ -#define setPMRU(pmru) { \ - WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ - } - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PMRU register - * @return uint16_t. Value of @ref PMRU register. - * @sa setPMRU() - */ -#define getPMRU() \ - ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) - -/** - * @ingroup Common_register_access_function - * @brief Get unreachable IP address - * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. - */ -#define getUIPR(uipr) \ - WIZCHIP_READ_BUF(UIPR,uipr,6) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref UPORTR register - * @return uint16_t. Value of @ref UPORTR register. - */ -#define getUPORTR() \ - ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PHYCFGR register - * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. - * @sa getPHYCFGR() - */ -#define setPHYCFGR(phycfgr) \ - WIZCHIP_WRITE(PHYCFGR, phycfgr) -#endif - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PHYCFGR register - * @return uint8_t. Value of @ref PHYCFGR register. - * @sa setPHYCFGR() - */ -#define getPHYSTATUS() \ - WIZCHIP_READ(PHYSTATUS) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref VERSIONR register - * @return uint8_t. Value of @ref VERSIONR register. - */ -/* -#define getVERSIONR() \ - WIZCHIP_READ(VERSIONR) - */ -///////////////////////////////////// - -/////////////////////////////////// -// Socket N register I/O function // -/////////////////////////////////// -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_MR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)mr Value to set @ref Sn_MR - * @sa getSn_MR() - */ -#define setSn_MR(sn, mr) \ - WIZCHIP_WRITE(Sn_MR(sn),mr) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_MR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_MR. - * @sa setSn_MR() - */ -#define getSn_MR(sn) \ - WIZCHIP_READ(Sn_MR(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_CR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)cr Value to set @ref Sn_CR - * @sa getSn_CR() - */ -#define setSn_CR(sn, cr) \ - WIZCHIP_WRITE(Sn_CR(sn), cr) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_CR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_CR. - * @sa setSn_CR() - */ -#define getSn_CR(sn) \ - WIZCHIP_READ(Sn_CR(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_IR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)ir Value to set @ref Sn_IR - * @sa getSn_IR() - */ -#define setSn_IR(sn, ir) \ - WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_IR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_IR. - * @sa setSn_IR() - */ -#define getSn_IR(sn) \ - (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_IMR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)imr Value to set @ref Sn_IMR - * @sa getSn_IMR() - */ -// dpgeorge: not yet implemented -#define setSn_IMR(sn, imr) (void)sn; (void)imr -#if 0 -#define setSn_IMR(sn, imr) \ - WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) -#endif - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_IMR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_IMR. - * @sa setSn_IMR() - */ -// dpgeorge: not yet implemented -#define getSn_IMR(sn) (0) -#if 0 -#define getSn_IMR(sn) \ - (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) -#endif - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_SR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_SR. - */ -#define getSn_SR(sn) \ - WIZCHIP_READ(Sn_SR(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_PORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)port Value to set @ref Sn_PORT. - * @sa getSn_PORT() - */ -#define setSn_PORT(sn, port) { \ - WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ - WIZCHIP_WRITE(Sn_PORT(sn) + 1, (uint8_t) port); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_PORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_PORT. - * @sa setSn_PORT() - */ -#define getSn_PORT(sn) \ - ((WIZCHIP_READ(Sn_PORT(sn)) << 8) | WIZCHIP_READ(Sn_PORT(sn) + 1)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_DHAR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. - * @sa getSn_DHAR() - */ -#define setSn_DHAR(sn, dhar) \ - WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_MR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. - * @sa setSn_DHAR() - */ -#define getSn_DHAR(sn, dhar) \ - WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_DIPR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. - * @sa getSn_DIPR() - */ -#define setSn_DIPR(sn, dipr) \ - WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_DIPR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. - * @sa SetSn_DIPR() - */ -#define getSn_DIPR(sn, dipr) \ - WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_DPORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)dport Value to set @ref Sn_DPORT - * @sa getSn_DPORT() - */ -#define setSn_DPORT(sn, dport) { \ - WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ - WIZCHIP_WRITE(Sn_DPORT(sn) + 1, (uint8_t) dport); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_DPORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_DPORT. - * @sa setSn_DPORT() - */ -#define getSn_DPORT(sn) \ - ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ((Sn_DPORT(sn)+1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_MSSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)mss Value to set @ref Sn_MSSR - * @sa setSn_MSSR() - */ -#define setSn_MSSR(sn, mss) { \ - WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ - WIZCHIP_WRITE((Sn_MSSR(sn)+1), (uint8_t) mss); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_MSSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_MSSR. - * @sa setSn_MSSR() - */ -#define getSn_MSSR(sn) \ - ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ((Sn_MSSR(sn)+1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TOS register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)tos Value to set @ref Sn_TOS - * @sa getSn_TOS() - */ -#define setSn_TOS(sn, tos) \ - WIZCHIP_WRITE(Sn_TOS(sn), tos) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TOS register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of Sn_TOS. - * @sa setSn_TOS() - */ -#define getSn_TOS(sn) \ - WIZCHIP_READ(Sn_TOS(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TTL register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)ttl Value to set @ref Sn_TTL - * @sa getSn_TTL() - */ -#define setSn_TTL(sn, ttl) \ - WIZCHIP_WRITE(Sn_TTL(sn), ttl) - - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TTL register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_TTL. - * @sa setSn_TTL() - */ -#define getSn_TTL(sn) \ - WIZCHIP_READ(Sn_TTL(sn)) - - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_RXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE - * @sa getSn_RXBUF_SIZE() - */ -#define setSn_RXBUF_SIZE(sn, rxbufsize) \ - WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) - - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. - * @sa setSn_RXBUF_SIZE() - */ -#define getSn_RXBUF_SIZE(sn) \ - WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE - * @sa getSn_TXBUF_SIZE() - */ -#define setSn_TXBUF_SIZE(sn, txbufsize) \ - WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. - * @sa setSn_TXBUF_SIZE() - */ -#define getSn_TXBUF_SIZE(sn) \ - WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TX_FSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_TX_FSR. - */ -uint16_t getSn_TX_FSR(uint8_t sn); - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TX_RD register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_TX_RD. - */ -#define getSn_TX_RD(sn) \ - ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ((Sn_TX_RD(sn)+1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TX_WR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)txwr Value to set @ref Sn_TX_WR - * @sa GetSn_TX_WR() - */ -#define setSn_TX_WR(sn, txwr) { \ - WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ - WIZCHIP_WRITE((Sn_TX_WR(sn)+1), (uint8_t) txwr); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TX_WR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_TX_WR. - * @sa setSn_TX_WR() - */ -#define getSn_TX_WR(sn) \ - ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ((Sn_TX_WR(sn)+1))) - - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RX_RSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_RX_RSR. - */ -uint16_t getSn_RX_RSR(uint8_t sn); - - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_RX_RD register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD - * @sa getSn_RX_RD() - */ -#define setSn_RX_RD(sn, rxrd) { \ - WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ - WIZCHIP_WRITE((Sn_RX_RD(sn)+1), (uint8_t) rxrd); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RX_RD register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @regurn uint16_t. Value of @ref Sn_RX_RD. - * @sa setSn_RX_RD() - */ -#define getSn_RX_RD(sn) \ - ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ((Sn_RX_RD(sn)+1))) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RX_WR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_RX_WR. - */ -#define getSn_RX_WR(sn) \ - ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ((Sn_RX_WR(sn)+1))) - - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_FRAG register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)frag Value to set @ref Sn_FRAG - * @sa getSn_FRAD() - */ -#if 0 // dpgeorge -#define setSn_FRAG(sn, frag) { \ - WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_FRAG register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_FRAG. - * @sa setSn_FRAG() - */ -#define getSn_FRAG(sn) \ - ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_KPALVTR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR - * @sa getSn_KPALVTR() - */ -#define setSn_KPALVTR(sn, kpalvt) \ - WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_KPALVTR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_KPALVTR. - * @sa setSn_KPALVTR() - */ -#define getSn_KPALVTR(sn) \ - WIZCHIP_READ(Sn_KPALVTR(sn)) - -////////////////////////////////////// -#endif - -///////////////////////////////////// -// Sn_TXBUF & Sn_RXBUF IO function // -///////////////////////////////////// -/** - * @brief Gets the max buffer size of socket sn passed as parameter. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of Socket n RX max buffer size. - */ -#define getSn_RxMAX(sn) \ - (getSn_RXBUF_SIZE(sn) << 10) - -/** - * @brief Gets the max buffer size of socket sn passed as parameters. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of Socket n TX max buffer size. - */ -//uint16_t getSn_TxMAX(uint8_t sn); -#define getSn_TxMAX(sn) \ - (getSn_TXBUF_SIZE(sn) << 10) - -void wiz_init(void); - -/** - * @ingroup Basic_IO_function - * @brief It copies data to internal TX memory - * - * @details This function reads the Tx write pointer register and after that, - * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory - * and updates the Tx write pointer register. - * This function is being called by send() and sendto() function also. - * - * @note User should read upper byte first and lower byte later to get proper value. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param wizdata Pointer buffer to write data - * @param len Data length - * @sa wiz_recv_data() - */ -void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); - -/** - * @ingroup Basic_IO_function - * @brief It copies data to your buffer from internal RX memory - * - * @details This function read the Rx read pointer register and after that, - * it copies the received data from internal RX memory - * to wizdata(pointer variable) of the length of len(variable) bytes. - * This function is being called by recv() also. - * - * @note User should read upper byte first and lower byte later to get proper value. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param wizdata Pointer buffer to read data - * @param len Data length - * @sa wiz_send_data() - */ -void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); - -/** - * @ingroup Basic_IO_function - * @brief It discard the received data in RX memory. - * @details It discards the data of the length of len(variable) bytes in internal RX memory. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param len Data length - */ -void wiz_recv_ignore(uint8_t sn, uint16_t len); - -#endif // _W5500_H_ diff --git a/drivers/wiznet5k/ethernet/w5500/w5500.c b/drivers/wiznet5k/ethernet/w5500/w5500.c deleted file mode 100644 index 3107b1b71aa3..000000000000 --- a/drivers/wiznet5k/ethernet/w5500/w5500.c +++ /dev/null @@ -1,247 +0,0 @@ -//***************************************************************************** -// -//! \file w5500.c -//! \brief W5500 HAL Interface. -//! \version 1.0.1 -//! \date 2013/10/21 -//! \par Revision history -//! <2014/05/01> V1.0.2 -//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 -//! Fixed the problem on porting into under 32bit MCU -//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh -//! Thank for your interesting and serious advices. -//! <2013/10/21> 1st Release -//! <2013/12/20> V1.0.1 -//! 1. Remove warning -//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ -//! for loop optimized(removed). refer to M20131220 -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** -//#include -#include "w5500.h" - -#define _W5500_SPI_VDM_OP_ 0x00 -#define _W5500_SPI_FDM_OP_LEN1_ 0x01 -#define _W5500_SPI_FDM_OP_LEN2_ 0x02 -#define _W5500_SPI_FDM_OP_LEN4_ 0x03 - -//////////////////////////////////////////////////// - -#define LPC_SSP0 (0) - -static void Chip_SSP_ReadFrames_Blocking(int dummy, uint8_t *buf, uint32_t len) { - WIZCHIP.IF.SPI._read_bytes(buf, len); -} - -static void Chip_SSP_WriteFrames_Blocking(int dummy, const uint8_t *buf, uint32_t len) { - WIZCHIP.IF.SPI._write_bytes(buf, len); -} - -uint8_t WIZCHIP_READ(uint32_t AddrSel) -{ - uint8_t ret; - uint8_t spi_data[3]; - - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); - - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); - //ret = WIZCHIP.IF.SPI._read_byte(); - spi_data[0] = (AddrSel & 0x00FF0000) >> 16; - spi_data[1] = (AddrSel & 0x0000FF00) >> 8; - spi_data[2] = (AddrSel & 0x000000FF) >> 0; - Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3); - Chip_SSP_ReadFrames_Blocking(LPC_SSP0, &ret, 1); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); - return ret; -} - -void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) -{ - uint8_t spi_data[4]; - - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); - - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); - //WIZCHIP.IF.SPI._write_byte(wb); - spi_data[0] = (AddrSel & 0x00FF0000) >> 16; - spi_data[1] = (AddrSel & 0x0000FF00) >> 8; - spi_data[2] = (AddrSel & 0x000000FF) >> 0; - spi_data[3] = wb; - Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 4); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); -} - -void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) -{ - uint8_t spi_data[3]; - //uint16_t i; - - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); - - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); - //for(i = 0; i < len; i++) - // pBuf[i] = WIZCHIP.IF.SPI._read_byte(); - spi_data[0] = (AddrSel & 0x00FF0000) >> 16; - spi_data[1] = (AddrSel & 0x0000FF00) >> 8; - spi_data[2] = (AddrSel & 0x000000FF) >> 0; - Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3); - Chip_SSP_ReadFrames_Blocking(LPC_SSP0, pBuf, len); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); -} - -void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) -{ - uint8_t spi_data[3]; - //uint16_t i; - - WIZCHIP_CRITICAL_ENTER(); - WIZCHIP.CS._select(); - - AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); - - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); - //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); - //for(i = 0; i < len; i++) - // WIZCHIP.IF.SPI._write_byte(pBuf[i]); - spi_data[0] = (AddrSel & 0x00FF0000) >> 16; - spi_data[1] = (AddrSel & 0x0000FF00) >> 8; - spi_data[2] = (AddrSel & 0x000000FF) >> 0; - Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3); - Chip_SSP_WriteFrames_Blocking(LPC_SSP0, pBuf, len); - - WIZCHIP.CS._deselect(); - WIZCHIP_CRITICAL_EXIT(); -} - - -uint16_t getSn_TX_FSR(uint8_t sn) -{ - uint16_t val=0,val1=0; - - do - { - val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); - val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); - if (val1 != 0) - { - val = WIZCHIP_READ(Sn_TX_FSR(sn)); - val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); - } - }while (val != val1); - return val; -} - - -uint16_t getSn_RX_RSR(uint8_t sn) -{ - uint16_t val=0,val1=0; - - do - { - val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); - val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); - if (val1 != 0) - { - val = WIZCHIP_READ(Sn_RX_RSR(sn)); - val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); - } - }while (val != val1); - return val; -} - -void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) -{ - uint16_t ptr = 0; - uint32_t addrsel = 0; - - if(len == 0) return; - ptr = getSn_TX_WR(sn); - //M20140501 : implict type casting -> explict type casting - //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); - addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); - // - WIZCHIP_WRITE_BUF(addrsel,wizdata, len); - - ptr += len; - setSn_TX_WR(sn,ptr); -} - -void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) -{ - uint16_t ptr = 0; - uint32_t addrsel = 0; - - if(len == 0) return; - ptr = getSn_RX_RD(sn); - //M20140501 : implict type casting -> explict type casting - //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); - addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); - // - WIZCHIP_READ_BUF(addrsel, wizdata, len); - ptr += len; - - setSn_RX_RD(sn,ptr); -} - - -void wiz_recv_ignore(uint8_t sn, uint16_t len) -{ - uint16_t ptr = 0; - - ptr = getSn_RX_RD(sn); - ptr += len; - setSn_RX_RD(sn,ptr); -} - diff --git a/drivers/wiznet5k/ethernet/w5500/w5500.h b/drivers/wiznet5k/ethernet/w5500/w5500.h deleted file mode 100644 index c2afb180ebba..000000000000 --- a/drivers/wiznet5k/ethernet/w5500/w5500.h +++ /dev/null @@ -1,2057 +0,0 @@ -//***************************************************************************** -// -//! \file w5500.h -//! \brief W5500 HAL Header File. -//! \version 1.0.0 -//! \date 2013/10/21 -//! \par Revision history -//! <2013/10/21> 1st Release -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#ifndef _W5500_H_ -#define _W5500_H_ - -#include -#include "../wizchip_conf.h" - -#define _W5500_IO_BASE_ 0x00000000 - -#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase -#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase - -#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block -#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block -#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block -#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block - -#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address - - -/////////////////////////////////////// -// Definition For Legacy Chip Driver // -/////////////////////////////////////// -#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver -#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver -#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver -#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver - -////////////////////////////// -//-------------------------- defgroup --------------------------------- -/** - * @defgroup W5500 W5500 - * - * @brief WHIZCHIP register defines and I/O functions of @b W5500. - * - * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group - * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function - */ - - -/** - * @defgroup WIZCHIP_register WIZCHIP register - * @ingroup W5500 - * - * @brief WHIZCHIP register defines register group of @b W5500. - * - * - @ref Common_register_group : Common register group - * - @ref Socket_register_group : \c SOCKET n register group - */ - - -/** - * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions - * @ingroup W5500 - * - * @brief This supports the basic I/O functions for @ref WIZCHIP_register. - * - * - Basic I/O function \n - * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n - * - * - @ref Common_register_group access functions \n - * -# @b Mode \n - * getMR(), setMR() - * -# @b Interrupt \n - * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() - * -# Network Information \n - * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() - * -# @b Retransmission \n - * getRCR(), setRCR(), getRTR(), setRTR() - * -# @b PPPoE \n - * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() - * -# ICMP packet \n - * getUIPR(), getUPORTR() - * -# @b etc. \n - * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n - * - * - \ref Socket_register_group access functions \n - * -# SOCKET control \n - * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() - * -# SOCKET information \n - * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() - * getSn_MSSR(), setSn_MSSR() - * -# SOCKET communication \n - * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n - * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n - * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n - * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() - * -# IP header field \n - * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n - * getSn_TTL(), setSn_TTL() - */ - - - -/** - * @defgroup Common_register_group Common register - * @ingroup WIZCHIP_register - * - * @brief Common register group\n - * It set the basic for the networking\n - * It set the configuration such as interrupt, network information, ICMP, etc. - * @details - * @sa MR : Mode register. - * @sa GAR, SUBR, SHAR, SIPR - * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. - * @sa RTR, RCR : Data retransmission. - * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. - * @sa UIPR, UPORTR : ICMP message. - * @sa PHYCFGR, VERSIONR : etc. - */ - - - -/** - * @defgroup Socket_register_group Socket register - * @ingroup WIZCHIP_register - * - * @brief Socket register group.\n - * Socket register configures and control SOCKETn which is necessary to data communication. - * @details - * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control - * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information - * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. - * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication - */ - - - - /** - * @defgroup Basic_IO_function Basic I/O function - * @ingroup WIZCHIP_IO_Functions - * @brief These are basic input/output functions to read values from register or write values to register. - */ - -/** - * @defgroup Common_register_access_function Common register access functions - * @ingroup WIZCHIP_IO_Functions - * @brief These are functions to access common registers. - */ - -/** - * @defgroup Socket_register_access_function Socket register access functions - * @ingroup WIZCHIP_IO_Functions - * @brief These are functions to access socket registers. - */ - -//------------------------------- defgroup end -------------------------------------------- -//----------------------------- W5500 Common Registers IOMAP ----------------------------- -/** - * @ingroup Common_register_group - * @brief Mode Register address(R/W)\n - * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. - * @details Each bit of @ref MR defined as follows. - * - * - * - *
7 6 5 4 3 2 1 0
RST Reserved WOL PB PPPoE Reserved FARP Reserved
- * - \ref MR_RST : Reset - * - \ref MR_WOL : Wake on LAN - * - \ref MR_PB : Ping block - * - \ref MR_PPPOE : PPPoE mode - * - \ref MR_FARP : Force ARP mode - */ -#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Gateway IP Register address(R/W) - * @details @ref GAR configures the default gateway address. - */ -#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Subnet mask Register address(R/W) - * @details @ref SUBR configures the subnet mask address. - */ -#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Source MAC Register address(R/W) - * @details @ref SHAR configures the source hardware address. - */ -#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Source IP Register address(R/W) - * @details @ref SIPR configures the source IP address. - */ -#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Set Interrupt low level timer register address(R/W) - * @details @ref INTLEVEL configures the Interrupt Assert Time. - */ -#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Interrupt Register(R/W) - * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. - * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n - * Each bit of @ref IR defined as follows. - * - * - * - *
7 6 5 4 3 2 1 0
CONFLICT UNREACH PPPoE MP Reserved Reserved Reserved Reserved
- * - \ref IR_CONFLICT : IP conflict - * - \ref IR_UNREACH : Destination unreachable - * - \ref IR_PPPoE : PPPoE connection close - * - \ref IR_MP : Magic packet - */ -#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Interrupt mask register(R/W) - * @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. - * When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, - * if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n - * Each bit of @ref IMR defined as the following. - * - * - * - *
7 6 5 4 3 2 1 0
IM_IR7 IM_IR6 IM_IR5 IM_IR4 Reserved Reserved Reserved Reserved
- * - \ref IM_IR7 : IP Conflict Interrupt Mask - * - \ref IM_IR6 : Destination unreachable Interrupt Mask - * - \ref IM_IR5 : PPPoE Close Interrupt Mask - * - \ref IM_IR4 : Magic Packet Interrupt Mask - */ -#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Socket Interrupt Register(R/W) - * @details @ref SIR indicates the interrupt status of Socket.\n - * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n - * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ -#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Socket Interrupt Mask Register(R/W) - * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. - * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. - * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is - */ -#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Timeout register address( 1 is 100us )(R/W) - * @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 - * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response - * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). - * If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. - */ -#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Retry count register(R/W) - * @details @ref RCR configures the number of time of retransmission. - * When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . - */ -#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP LCP Request Timer register in PPPoE mode(R/W) - * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. - */ -#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP LCP Magic number register in PPPoE mode(R/W) - * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. - */ -#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP Destination MAC Register address(R/W) - * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. - */ -#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP Session Identification Register(R/W) - * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. - */ -#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PPP Maximum Segment Size(MSS) register(R/W) - * @details @ref PMRU configures the maximum receive unit of PPPoE. - */ -#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Unreachable IP register address in UDP mode(R) - * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number - * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates - * the destination IP address & port number respectively. - */ -#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief Unreachable Port register address in UDP mode(R) - * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number - * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR - * indicates the destination IP address & port number respectively. - */ -#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief PHY Status Register(R/W) - * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. - */ -#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - -/** - * @ingroup Common_register_group - * @brief chip version register address(R) - * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. - */ -#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) - - -//----------------------------- W5500 Socket Registers IOMAP ----------------------------- -/** - * @ingroup Socket_register_group - * @brief socket Mode register(R/W) - * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n - * Each bit of @ref Sn_MR defined as the following. - * - * - * - *
7 6 5 4 3 2 1 0
MULTI/MFEN BCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3] Protocol[2] Protocol[1] Protocol[0]
- * - @ref Sn_MR_MULTI : Support UDP Multicasting - * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting - * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag - * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting - * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode - * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating - * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode - * - Protocol - * - * - * - * - * - * - *
Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0 MACRAW
- * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n - * - @ref Sn_MR_UDP : UDP - * - @ref Sn_MR_TCP : TCP - * - @ref Sn_MR_CLOSE : Unused socket - * @note MACRAW mode should be only used in Socket 0. - */ -#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Socket command register(R/W) - * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n - * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. - * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n - * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. - * - @ref Sn_CR_OPEN : Initialize or open socket. - * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) - * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) - * - @ref Sn_CR_DISCON : Send closing request in TCP mode. - * - @ref Sn_CR_CLOSE : Close socket. - * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. - * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. - * - @ref Sn_CR_SEND_KEEP : Send keep alive message. - * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. - */ -#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Socket interrupt register(R) - * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n - * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n - * In order to clear the @ref Sn_IR bit, the host should write the bit to \n - * - * - * - *
7 6 5 4 3 2 1 0
Reserved Reserved Reserved SEND_OK TIMEOUT RECV DISCON CON
- * - \ref Sn_IR_SENDOK : SEND_OK Interrupt - * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt - * - \ref Sn_IR_RECV : RECV Interrupt - * - \ref Sn_IR_DISCON : DISCON Interrupt - * - \ref Sn_IR_CON : CON Interrupt - */ -#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Socket status register(R) - * @details @ref Sn_SR indicates the status of Socket n.\n - * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. - * @par Normal status - * - @ref SOCK_CLOSED : Closed - * - @ref SOCK_INIT : Initiate state - * - @ref SOCK_LISTEN : Listen state - * - @ref SOCK_ESTABLISHED : Success to connect - * - @ref SOCK_CLOSE_WAIT : Closing state - * - @ref SOCK_UDP : UDP socket - * - @ref SOCK_MACRAW : MAC raw mode socket - *@par Temporary status during changing the status of Socket n. - * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. - * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. - * - @ref SOCK_FIN_WAIT : Connection state - * - @ref SOCK_CLOSING : Closing state - * - @ref SOCK_TIME_WAIT : Closing state - * - @ref SOCK_LAST_ACK : Closing state - */ -#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief source port register(R/W) - * @details @ref Sn_PORT configures the source port number of Socket n. - * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. - */ -#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Peer MAC register address(R/W) - * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or - * it indicates that it is acquired in ARP-process by CONNECT/SEND command. - */ -#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Peer IP register address(R/W) - * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. - * In TCP client mode, it configures an IP address of �TCP serverbefore CONNECT command. - * In TCP server mode, it indicates an IP address of �TCP clientafter successfully establishing connection. - * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. - */ -#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Peer port register address(R/W) - * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. - * In �TCP clientmode, it configures the listen port number of �TCP serverbefore CONNECT command. - * In �TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. - * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. - */ -#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) - * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. - */ -#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief IP Type of Service(TOS) Register(R/W) - * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. - * It is set before OPEN command. - */ -#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -/** - * @ingroup Socket_register_group - * @brief IP Time to live(TTL) Register(R/W) - * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. - * It is set before OPEN command. - */ -#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) -// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Receive memory size register(R/W) - * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. - * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. - * If a different size is configured, the data cannot be normally received from a peer. - * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, - * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. - * When exceeded, the data reception error is occurred. - */ -#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Transmit memory size register(R/W) - * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. - * If a different size is configured, the data can�t be normally transmitted to a peer. - * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, - * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. - * When exceeded, the data transmission error is occurred. - */ -#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Transmit free memory size register(R) - * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. - * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. - * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, - * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, - * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. - */ -#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Transmit memory read pointer register address(R) - * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. - * After its initialization, it is auto-increased by SEND command. - * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. - * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. - * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), - * then the carry bit is ignored and will automatically update with the lower 16bits value. - */ -#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Transmit memory write pointer register address(R/W) - * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n - * It should be read or be updated like as follows.\n - * 1. Read the starting address for saving the transmitting data.\n - * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n - * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. - * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), - * then the carry bit is ignored and will automatically update with the lower 16bits value.\n - * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command - */ -#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Received data size register(R) - * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. - * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between - * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD) - */ -#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Read point of Receive memory(R/W) - * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n - * 1. Read the starting save address of the received data.\n - * 2. Read data from the starting address of Socket n RX Buffer.\n - * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. - * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, - * update with the lower 16bits value ignored the carry bit.\n - * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. - */ -#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Write point of Receive memory(R) - * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. - * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), - * then the carry bit is ignored and will automatically update with the lower 16bits value. - */ -#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief socket interrupt mask register(R) - * @details @ref Sn_IMR masks the interrupt of Socket n. - * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is - * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is - * Host is interrupted by asserted INTn PIN to low. - */ -#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Fragment field value in IP header register(R/W) - * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). - */ -#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -/** - * @ingroup Socket_register_group - * @brief Keep Alive Timer register(R/W) - * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, - * and ignored in other modes. The time unit is 5s. - * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. - * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). - * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, - * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). - * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. - */ -#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - -//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) - - -//----------------------------- W5500 Register values ----------------------------- - -/* MODE register values */ -/** - * @brief Reset - * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. - */ -#define MR_RST 0x80 - -/** - * @brief Wake on LAN - * @details 0 : Disable WOL mode\n - * 1 : Enable WOL mode\n - * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. - * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) - * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and - * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. - */ -#define MR_WOL 0x20 - -/** - * @brief Ping block - * @details 0 : Disable Ping block\n - * 1 : Enable Ping block\n - * If the bit is it blocks the response to a ping request. - */ -#define MR_PB 0x10 - -/** - * @brief Enable PPPoE - * @details 0 : DisablePPPoE mode\n - * 1 : EnablePPPoE mode\n - * If you use ADSL, this bit should be - */ -#define MR_PPPOE 0x08 - -/** - * @brief Enable UDP_FORCE_ARP CHECHK - * @details 0 : Disable Force ARP mode\n - * 1 : Enable Force ARP mode\n - * In Force ARP mode, It forces on sending ARP Request whenever data is sent. - */ -#define MR_FARP 0x02 - -/* IR register values */ -/** - * @brief Check IP conflict. - * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. - */ -#define IR_CONFLICT 0x80 - -/** - * @brief Get the destination unreachable message in UDP sending. - * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as - * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. - */ -#define IR_UNREACH 0x40 - -/** - * @brief Get the PPPoE close message. - * @details When PPPoE is disconnected during PPPoE mode, this bit is set. - */ -#define IR_PPPoE 0x20 - -/** - * @brief Get the magic packet interrupt. - * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. - */ -#define IR_MP 0x10 - - -/* PHYCFGR register value */ -#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. -#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value -#define PHYCFGR_OPMDC_ALLA (7<<3) -#define PHYCFGR_OPMDC_PDOWN (6<<3) -#define PHYCFGR_OPMDC_NA (5<<3) -#define PHYCFGR_OPMDC_100FA (4<<3) -#define PHYCFGR_OPMDC_100F (3<<3) -#define PHYCFGR_OPMDC_100H (2<<3) -#define PHYCFGR_OPMDC_10F (1<<3) -#define PHYCFGR_OPMDC_10H (0<<3) -#define PHYCFGR_DPX_FULL (1<<2) -#define PHYCFGR_DPX_HALF (0<<2) -#define PHYCFGR_SPD_100 (1<<1) -#define PHYCFGR_SPD_10 (0<<1) -#define PHYCFGR_LNK_ON (1<<0) -#define PHYCFGR_LNK_OFF (0<<0) - -/* IMR register values */ -/** - * @brief IP Conflict Interrupt Mask. - * @details 0: Disable IP Conflict Interrupt\n - * 1: Enable IP Conflict Interrupt - */ -#define IM_IR7 0x80 - -/** - * @brief Destination unreachable Interrupt Mask. - * @details 0: Disable Destination unreachable Interrupt\n - * 1: Enable Destination unreachable Interrupt - */ -#define IM_IR6 0x40 - -/** - * @brief PPPoE Close Interrupt Mask. - * @details 0: Disable PPPoE Close Interrupt\n - * 1: Enable PPPoE Close Interrupt - */ -#define IM_IR5 0x20 - -/** - * @brief Magic Packet Interrupt Mask. - * @details 0: Disable Magic Packet Interrupt\n - * 1: Enable Magic Packet Interrupt - */ -#define IM_IR4 0x10 - -/* Sn_MR Default values */ -/** - * @brief Support UDP Multicasting - * @details 0 : disable Multicasting\n - * 1 : enable Multicasting\n - * This bit is applied only during UDP mode(P[3:0] = 010.\n - * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number - * before Socket n is opened by OPEN command of @ref Sn_CR. - */ -#define Sn_MR_MULTI 0x80 - -/** - * @brief Broadcast block in UDP Multicasting. - * @details 0 : disable Broadcast Blocking\n - * 1 : enable Broadcast Blocking\n - * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m - * In addition, This bit does when MACRAW mode(P[3:0] = 100 - */ -#define Sn_MR_BCASTB 0x40 - -/** - * @brief No Delayed Ack(TCP), Multicast flag - * @details 0 : Disable No Delayed ACK option\n - * 1 : Enable No Delayed ACK option\n - * This bit is applied only during TCP mode (P[3:0] = 001.\n - * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n - * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. - */ -#define Sn_MR_ND 0x20 - -/** - * @brief Unicast Block in UDP Multicasting - * @details 0 : disable Unicast Blocking\n - * 1 : enable Unicast Blocking\n - * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = - */ -#define Sn_MR_UCASTB 0x10 - -/** - * @brief MAC LAYER RAW SOCK - * @details This configures the protocol mode of Socket n. - * @note MACRAW mode should be only used in Socket 0. - */ -#define Sn_MR_MACRAW 0x04 - -//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ - -/** - * @brief UDP - * @details This configures the protocol mode of Socket n. - */ -#define Sn_MR_UDP 0x02 - -/** - * @brief TCP - * @details This configures the protocol mode of Socket n. - */ -#define Sn_MR_TCP 0x01 - -/** - * @brief Unused socket - * @details This configures the protocol mode of Socket n. - */ -#define Sn_MR_CLOSE 0x00 - -/* Sn_MR values used with Sn_MR_MACRAW */ -/** - * @brief MAC filter enable in @ref Sn_MR_MACRAW mode - * @details 0 : disable MAC Filtering\n - * 1 : enable MAC Filtering\n - * This bit is applied only during MACRAW mode(P[3:0] = 100.\n - * When set as W5500 can only receive broadcasting packet or packet sent to itself. - * When this bit is W5500 can receive all packets on Ethernet. - * If user wants to implement Hybrid TCP/IP stack, - * it is recommended that this bit is set as for reducing host overhead to process the all received packets. - */ -#define Sn_MR_MFEN Sn_MR_MULTI - -/** - * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode - * @details 0 : using IGMP version 2\n - * 1 : using IGMP version 1\n - * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = - * It configures the version for IGMP messages (Join/Leave/Report). - */ -#define Sn_MR_MMB Sn_MR_ND - -/** - * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode - * @details 0 : disable IPv6 Blocking\n - * 1 : enable IPv6 Blocking\n - * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. - */ -#define Sn_MR_MIP6B Sn_MR_UCASTB - -/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ -/** - * @brief IGMP version used in UDP mulitcasting - * @details 0 : disable Multicast Blocking\n - * 1 : enable Multicast Blocking\n - * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. - */ -#define Sn_MR_MC Sn_MR_ND - -/* Sn_MR alternate values */ -/** - * @brief For Berkeley Socket API - */ -#define SOCK_STREAM Sn_MR_TCP - -/** - * @brief For Berkeley Socket API - */ -#define SOCK_DGRAM Sn_MR_UDP - - -/* Sn_CR values */ -/** - * @brief Initialize or open socket - * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). - * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n - * - * - * - * - * - * - *
\b Sn_MR (P[3:0]) \b Sn_SR
Sn_MR_CLOSE (000
Sn_MR_TCP (001 SOCK_INIT (0x13)
Sn_MR_UDP (010 SOCK_UDP (0x22)
S0_MR_MACRAW (100 SOCK_MACRAW (0x02)
- */ -#define Sn_CR_OPEN 0x01 - -/** - * @brief Wait connection request in TCP mode(Server mode) - * @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). - * In this mode, Socket n operates as a �TCP serverand waits for connection-request (SYN packet) from any �TCP client - * The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. - * When a �TCP clientconnection request is successfully established, - * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes - * But when a �TCP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. - */ -#define Sn_CR_LISTEN 0x02 - -/** - * @brief Send connection request in TCP mode(Client mode) - * @details To connect, a connect-request (SYN packet) is sent to b>TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). - * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n - * The connect-request fails in the following three cases.\n - * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n - * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n - * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. - * @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client - */ -#define Sn_CR_CONNECT 0x04 - -/** - * @brief Send closing request in TCP mode - * @details Regardless of b>TCP serveror b>TCP client the DISCON command processes the disconnect-process (b>Active closeor b>Passive close.\n - * @par Active close - * it transmits disconnect-request(FIN packet) to the connected peer\n - * @par Passive close - * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n - * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n - * Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. - * @note Valid only in TCP mode. - */ -#define Sn_CR_DISCON 0x08 - -/** - * @brief Close socket - * @details Sn_SR is changed to @ref SOCK_CLOSED. - */ -#define Sn_CR_CLOSE 0x10 - -/** - * @brief Update TX buffer pointer and send data - * @details SEND transmits all the data in the Socket n TX buffer.\n - * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, - * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). - */ -#define Sn_CR_SEND 0x20 - -/** - * @brief Send data with MAC address, so without ARP process - * @details The basic operation is same as SEND.\n - * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n - * But SEND_MAC transmits data without the automatic ARP-process.\n - * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. - * @note Valid only in UDP mode. - */ -#define Sn_CR_SEND_MAC 0x21 - -/** - * @brief Send keep alive message - * @details It checks the connection status by sending 1byte keep-alive packet.\n - * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. - * @note Valid only in TCP mode. - */ -#define Sn_CR_SEND_KEEP 0x22 - -/** - * @brief Update RX buffer pointer and receive data - * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n - * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), - * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). - */ -#define Sn_CR_RECV 0x40 - -/* Sn_IR values */ -/** - * @brief SEND_OK Interrupt - * @details This is issued when SEND command is completed. - */ -#define Sn_IR_SENDOK 0x10 - -/** - * @brief TIMEOUT Interrupt - * @details This is issued when ARPTO or TCPTO occurs. - */ -#define Sn_IR_TIMEOUT 0x08 - -/** - * @brief RECV Interrupt - * @details This is issued whenever data is received from a peer. - */ -#define Sn_IR_RECV 0x04 - -/** - * @brief DISCON Interrupt - * @details This is issued when FIN or FIN/ACK packet is received from a peer. - */ -#define Sn_IR_DISCON 0x02 - -/** - * @brief CON Interrupt - * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. - */ -#define Sn_IR_CON 0x01 - -/* Sn_SR values */ -/** - * @brief Closed - * @details This indicates that Socket n is released.\N - * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. - */ -#define SOCK_CLOSED 0x00 - -/** - * @brief Initiate state - * @details This indicates Socket n is opened with TCP mode.\N - * It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N - * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. - */ -#define SOCK_INIT 0x13 - -/** - * @brief Listen state - * @details This indicates Socket n is operating as b>TCP servermode and waiting for connection-request (SYN packet) from a peer (b>TCP client.\n - * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n - * Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . - */ -#define SOCK_LISTEN 0x14 - -/** - * @brief Connection state - * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n - * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n - * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n - * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. - */ -#define SOCK_SYNSENT 0x15 - -/** - * @brief Connection state - * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n - * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n - * If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . - */ -#define SOCK_SYNRECV 0x16 - -/** - * @brief Success to connect - * @details This indicates the status of the connection of Socket n.\n - * It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVERprocessed the SYN packet from the b>TCP CLIENTduring @ref SOCK_LISTEN, or - * when the CONNECT command is successful.\n - * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. - */ -#define SOCK_ESTABLISHED 0x17 - -/** - * @brief Closing state - * @details These indicate Socket n is closing.\n - * These are shown in disconnect-process such as active-close and passive-close.\n - * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. - */ -#define SOCK_FIN_WAIT 0x18 - -/** - * @brief Closing state - * @details These indicate Socket n is closing.\n - * These are shown in disconnect-process such as active-close and passive-close.\n - * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. - */ -#define SOCK_CLOSING 0x1A - -/** - * @brief Closing state - * @details These indicate Socket n is closing.\n - * These are shown in disconnect-process such as active-close and passive-close.\n - * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. - */ -#define SOCK_TIME_WAIT 0x1B - -/** - * @brief Closing state - * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n - * This is half-closing status, and data can be transferred.\n - * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. - */ -#define SOCK_CLOSE_WAIT 0x1C - -/** - * @brief Closing state - * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n - * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . - */ -#define SOCK_LAST_ACK 0x1D - -/** - * @brief UDP socket - * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n - * It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n - * Unlike TCP mode, data can be transfered without the connection-process. - */ -#define SOCK_UDP 0x22 - -//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ - -/** - * @brief MAC raw mode socket - * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n - * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n - * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. - */ -#define SOCK_MACRAW 0x42 - -//#define SOCK_PPPOE 0x5F - -/* IP PROTOCOL */ -#define IPPROTO_IP 0 //< Dummy for IP -#define IPPROTO_ICMP 1 //< Control message protocol -#define IPPROTO_IGMP 2 //< Internet group management protocol -#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) -#define IPPROTO_TCP 6 //< TCP -#define IPPROTO_PUP 12 //< PUP -#define IPPROTO_UDP 17 //< UDP -#define IPPROTO_IDP 22 //< XNS idp -#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol -#define IPPROTO_RAW 255 //< Raw IP packet - - -/** - * @brief Enter a critical section - * - * @details It is provided to protect your shared code which are executed without distribution. \n \n - * - * In non-OS environment, It can be just implemented by disabling whole interrupt.\n - * In OS environment, You can replace it to critical section api supported by OS. - * - * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() - * \sa WIZCHIP_CRITICAL_EXIT() - */ -#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() - -/** - * @brief Exit a critical section - * - * @details It is provided to protect your shared code which are executed without distribution. \n\n - * - * In non-OS environment, It can be just implemented by disabling whole interrupt. \n - * In OS environment, You can replace it to critical section api supported by OS. - * - * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() - * @sa WIZCHIP_CRITICAL_ENTER() - */ -#ifdef _exit -#undef _exit -#endif -#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() - - - -//////////////////////// -// Basic I/O Function // -//////////////////////// - -/** - * @ingroup Basic_IO_function - * @brief It reads 1 byte value from a register. - * @param AddrSel Register address - * @return The value of register - */ -uint8_t WIZCHIP_READ (uint32_t AddrSel); - -/** - * @ingroup Basic_IO_function - * @brief It writes 1 byte value to a register. - * @param AddrSel Register address - * @param wb Write data - * @return void - */ -void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); - -/** - * @ingroup Basic_IO_function - * @brief It reads sequence data from registers. - * @param AddrSel Register address - * @param pBuf Pointer buffer to read data - * @param len Data length - */ -void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); - -/** - * @ingroup Basic_IO_function - * @brief It writes sequence data to registers. - * @param AddrSel Register address - * @param pBuf Pointer buffer to write data - * @param len Data length - */ -void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); - -///////////////////////////////// -// Common Register I/O function // -///////////////////////////////// -/** - * @ingroup Common_register_access_function - * @brief Set Mode Register - * @param (uint8_t)mr The value to be set. - * @sa getMR() - */ -#define setMR(mr) \ - WIZCHIP_WRITE(MR,mr) - - -/** - * @ingroup Common_register_access_function - * @brief Get Mode Register - * @return uint8_t. The value of Mode register. - * @sa setMR() - */ -#define getMR() \ - WIZCHIP_READ(MR) - -/** - * @ingroup Common_register_access_function - * @brief Set gateway IP address - * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. - * @sa getGAR() - */ -#define setGAR(gar) \ - WIZCHIP_WRITE_BUF(GAR,gar,4) - -/** - * @ingroup Common_register_access_function - * @brief Get gateway IP address - * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. - * @sa setGAR() - */ -#define getGAR(gar) \ - WIZCHIP_READ_BUF(GAR,gar,4) - -/** - * @ingroup Common_register_access_function - * @brief Set subnet mask address - * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. - * @sa getSUBR() - */ -#define setSUBR(subr) \ - WIZCHIP_WRITE_BUF(SUBR, subr,4) - - -/** - * @ingroup Common_register_access_function - * @brief Get subnet mask address - * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. - * @sa setSUBR() - */ -#define getSUBR(subr) \ - WIZCHIP_READ_BUF(SUBR, subr, 4) - -/** - * @ingroup Common_register_access_function - * @brief Set local MAC address - * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. - * @sa getSHAR() - */ -#define setSHAR(shar) \ - WIZCHIP_WRITE_BUF(SHAR, shar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Get local MAC address - * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. - * @sa setSHAR() - */ -#define getSHAR(shar) \ - WIZCHIP_READ_BUF(SHAR, shar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Set local IP address - * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. - * @sa getSIPR() - */ -#define setSIPR(sipr) \ - WIZCHIP_WRITE_BUF(SIPR, sipr, 4) - -/** - * @ingroup Common_register_access_function - * @brief Get local IP address - * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. - * @sa setSIPR() - */ -#define getSIPR(sipr) \ - WIZCHIP_READ_BUF(SIPR, sipr, 4) - -/** - * @ingroup Common_register_access_function - * @brief Set INTLEVEL register - * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. - * @sa getINTLEVEL() - */ -#define setINTLEVEL(intlevel) {\ - WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ - } - - -/** - * @ingroup Common_register_access_function - * @brief Get INTLEVEL register - * @return uint16_t. Value of @ref INTLEVEL register. - * @sa setINTLEVEL() - */ -#define getINTLEVEL() \ - ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref IR register - * @param (uint8_t)ir Value to set @ref IR register. - * @sa getIR() - */ -#define setIR(ir) \ - WIZCHIP_WRITE(IR, (ir & 0xF0)) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref IR register - * @return uint8_t. Value of @ref IR register. - * @sa setIR() - */ -#define getIR() \ - (WIZCHIP_READ(IR) & 0xF0) -/** - * @ingroup Common_register_access_function - * @brief Set @ref IMR register - * @param (uint8_t)imr Value to set @ref IMR register. - * @sa getIMR() - */ -#define setIMR(imr) \ - WIZCHIP_WRITE(IMR, imr) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref IMR register - * @return uint8_t. Value of @ref IMR register. - * @sa setIMR() - */ -#define getIMR() \ - WIZCHIP_READ(IMR) - - -/** - * @ingroup Common_register_access_function - * @brief Set @ref SIR register - * @param (uint8_t)sir Value to set @ref SIR register. - * @sa getSIR() - */ -#define setSIR(sir) \ - WIZCHIP_WRITE(SIR, sir) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref SIR register - * @return uint8_t. Value of @ref SIR register. - * @sa setSIR() - */ -#define getSIR() \ - WIZCHIP_READ(SIR) -/** - * @ingroup Common_register_access_function - * @brief Set @ref SIMR register - * @param (uint8_t)simr Value to set @ref SIMR register. - * @sa getSIMR() - */ -#define setSIMR(simr) \ - WIZCHIP_WRITE(SIMR, simr) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref SIMR register - * @return uint8_t. Value of @ref SIMR register. - * @sa setSIMR() - */ -#define getSIMR() \ - WIZCHIP_READ(SIMR) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref RTR register - * @param (uint16_t)rtr Value to set @ref RTR register. - * @sa getRTR() - */ -#define setRTR(rtr) {\ - WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RTR,1), (uint8_t) rtr); \ - } - -/** - * @ingroup Common_register_access_function - * @brief Get @ref RTR register - * @return uint16_t. Value of @ref RTR register. - * @sa setRTR() - */ -#define getRTR() \ - ((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(RTR,1))) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref RCR register - * @param (uint8_t)rcr Value to set @ref RCR register. - * @sa getRCR() - */ -#define setRCR(rcr) \ - WIZCHIP_WRITE(RCR, rcr) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref RCR register - * @return uint8_t. Value of @ref RCR register. - * @sa setRCR() - */ -#define getRCR() \ - WIZCHIP_READ(RCR) - -//================================================== test done =========================================================== - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PTIMER register - * @param (uint8_t)ptimer Value to set @ref PTIMER register. - * @sa getPTIMER() - */ -#define setPTIMER(ptimer) \ - WIZCHIP_WRITE(PTIMER, ptimer) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PTIMER register - * @return uint8_t. Value of @ref PTIMER register. - * @sa setPTIMER() - */ -#define getPTIMER() \ - WIZCHIP_READ(PTIMER) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PMAGIC register - * @param (uint8_t)pmagic Value to set @ref PMAGIC register. - * @sa getPMAGIC() - */ -#define setPMAGIC(pmagic) \ - WIZCHIP_WRITE(PMAGIC, pmagic) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PMAGIC register - * @return uint8_t. Value of @ref PMAGIC register. - * @sa setPMAGIC() - */ -#define getPMAGIC() \ - WIZCHIP_READ(PMAGIC) - -/** - * @ingroup Common_register_access_function - * @brief Set PHAR address - * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. - * @sa getPHAR() - */ -#define setPHAR(phar) \ - WIZCHIP_WRITE_BUF(PHAR, phar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Get local IP address - * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. - * @sa setPHAR() - */ -#define getPHAR(phar) \ - WIZCHIP_READ_BUF(PHAR, phar, 6) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PSID register - * @param (uint16_t)psid Value to set @ref PSID register. - * @sa getPSID() - */ -#define setPSID(psid) {\ - WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ - } - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PSID register - * @return uint16_t. Value of @ref PSID register. - * @sa setPSID() - */ -//uint16_t getPSID(void); -#define getPSID() \ - ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PMRU register - * @param (uint16_t)pmru Value to set @ref PMRU register. - * @sa getPMRU() - */ -#define setPMRU(pmru) { \ - WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ - } - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PMRU register - * @return uint16_t. Value of @ref PMRU register. - * @sa setPMRU() - */ -#define getPMRU() \ - ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) - -/** - * @ingroup Common_register_access_function - * @brief Get unreachable IP address - * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. - */ -#define getUIPR(uipr) \ - WIZCHIP_READ_BUF(UIPR,uipr,6) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref UPORTR register - * @return uint16_t. Value of @ref UPORTR register. - */ -#define getUPORTR() \ - ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) - -/** - * @ingroup Common_register_access_function - * @brief Set @ref PHYCFGR register - * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. - * @sa getPHYCFGR() - */ -#define setPHYCFGR(phycfgr) \ - WIZCHIP_WRITE(PHYCFGR, phycfgr) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref PHYCFGR register - * @return uint8_t. Value of @ref PHYCFGR register. - * @sa setPHYCFGR() - */ -#define getPHYCFGR() \ - WIZCHIP_READ(PHYCFGR) - -/** - * @ingroup Common_register_access_function - * @brief Get @ref VERSIONR register - * @return uint8_t. Value of @ref VERSIONR register. - */ -#define getVERSIONR() \ - WIZCHIP_READ(VERSIONR) - -///////////////////////////////////// - -/////////////////////////////////// -// Socket N register I/O function // -/////////////////////////////////// -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_MR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)mr Value to set @ref Sn_MR - * @sa getSn_MR() - */ -#define setSn_MR(sn, mr) \ - WIZCHIP_WRITE(Sn_MR(sn),mr) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_MR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_MR. - * @sa setSn_MR() - */ -#define getSn_MR(sn) \ - WIZCHIP_READ(Sn_MR(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_CR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)cr Value to set @ref Sn_CR - * @sa getSn_CR() - */ -#define setSn_CR(sn, cr) \ - WIZCHIP_WRITE(Sn_CR(sn), cr) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_CR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_CR. - * @sa setSn_CR() - */ -#define getSn_CR(sn) \ - WIZCHIP_READ(Sn_CR(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_IR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)ir Value to set @ref Sn_IR - * @sa getSn_IR() - */ -#define setSn_IR(sn, ir) \ - WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_IR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_IR. - * @sa setSn_IR() - */ -#define getSn_IR(sn) \ - (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_IMR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)imr Value to set @ref Sn_IMR - * @sa getSn_IMR() - */ -#define setSn_IMR(sn, imr) \ - WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_IMR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_IMR. - * @sa setSn_IMR() - */ -#define getSn_IMR(sn) \ - (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_SR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_SR. - */ -#define getSn_SR(sn) \ - WIZCHIP_READ(Sn_SR(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_PORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)port Value to set @ref Sn_PORT. - * @sa getSn_PORT() - */ -#define setSn_PORT(sn, port) { \ - WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_PORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_PORT. - * @sa setSn_PORT() - */ -#define getSn_PORT(sn) \ - ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_DHAR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. - * @sa getSn_DHAR() - */ -#define setSn_DHAR(sn, dhar) \ - WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_MR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. - * @sa setSn_DHAR() - */ -#define getSn_DHAR(sn, dhar) \ - WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_DIPR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. - * @sa getSn_DIPR() - */ -#define setSn_DIPR(sn, dipr) \ - WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_DIPR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. - * @sa SetSn_DIPR() - */ -#define getSn_DIPR(sn, dipr) \ - WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_DPORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)dport Value to set @ref Sn_DPORT - * @sa getSn_DPORT() - */ -#define setSn_DPORT(sn, dport) { \ - WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_DPORT register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_DPORT. - * @sa setSn_DPORT() - */ -#define getSn_DPORT(sn) \ - ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_MSSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)mss Value to set @ref Sn_MSSR - * @sa setSn_MSSR() - */ -#define setSn_MSSR(sn, mss) { \ - WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_MSSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_MSSR. - * @sa setSn_MSSR() - */ -#define getSn_MSSR(sn) \ - ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TOS register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)tos Value to set @ref Sn_TOS - * @sa getSn_TOS() - */ -#define setSn_TOS(sn, tos) \ - WIZCHIP_WRITE(Sn_TOS(sn), tos) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TOS register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of Sn_TOS. - * @sa setSn_TOS() - */ -#define getSn_TOS(sn) \ - WIZCHIP_READ(Sn_TOS(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TTL register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)ttl Value to set @ref Sn_TTL - * @sa getSn_TTL() - */ -#define setSn_TTL(sn, ttl) \ - WIZCHIP_WRITE(Sn_TTL(sn), ttl) - - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TTL register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_TTL. - * @sa setSn_TTL() - */ -#define getSn_TTL(sn) \ - WIZCHIP_READ(Sn_TTL(sn)) - - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_RXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE - * @sa getSn_RXBUF_SIZE() - */ -#define setSn_RXBUF_SIZE(sn, rxbufsize) \ - WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) - - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. - * @sa setSn_RXBUF_SIZE() - */ -#define getSn_RXBUF_SIZE(sn) \ - WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE - * @sa getSn_TXBUF_SIZE() - */ -#define setSn_TXBUF_SIZE(sn, txbufsize) \ - WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TXBUF_SIZE register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. - * @sa setSn_TXBUF_SIZE() - */ -#define getSn_TXBUF_SIZE(sn) \ - WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TX_FSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_TX_FSR. - */ -uint16_t getSn_TX_FSR(uint8_t sn); - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TX_RD register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_TX_RD. - */ -#define getSn_TX_RD(sn) \ - ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_TX_WR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)txwr Value to set @ref Sn_TX_WR - * @sa GetSn_TX_WR() - */ -#define setSn_TX_WR(sn, txwr) { \ - WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_TX_WR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_TX_WR. - * @sa setSn_TX_WR() - */ -#define getSn_TX_WR(sn) \ - ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) - - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RX_RSR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_RX_RSR. - */ -uint16_t getSn_RX_RSR(uint8_t sn); - - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_RX_RD register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD - * @sa getSn_RX_RD() - */ -#define setSn_RX_RD(sn, rxrd) { \ - WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RX_RD register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @regurn uint16_t. Value of @ref Sn_RX_RD. - * @sa setSn_RX_RD() - */ -#define getSn_RX_RD(sn) \ - ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_RX_WR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_RX_WR. - */ -#define getSn_RX_WR(sn) \ - ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) - - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_FRAG register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint16_t)frag Value to set @ref Sn_FRAG - * @sa getSn_FRAD() - */ -#define setSn_FRAG(sn, frag) { \ - WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ - WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ - } - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_FRAG register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of @ref Sn_FRAG. - * @sa setSn_FRAG() - */ -#define getSn_FRAG(sn) \ - ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) - -/** - * @ingroup Socket_register_access_function - * @brief Set @ref Sn_KPALVTR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR - * @sa getSn_KPALVTR() - */ -#define setSn_KPALVTR(sn, kpalvt) \ - WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) - -/** - * @ingroup Socket_register_access_function - * @brief Get @ref Sn_KPALVTR register - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint8_t. Value of @ref Sn_KPALVTR. - * @sa setSn_KPALVTR() - */ -#define getSn_KPALVTR(sn) \ - WIZCHIP_READ(Sn_KPALVTR(sn)) - -////////////////////////////////////// - -///////////////////////////////////// -// Sn_TXBUF & Sn_RXBUF IO function // -///////////////////////////////////// -/** - * @brief Gets the max buffer size of socket sn passed as parameter. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of Socket n RX max buffer size. - */ -#define getSn_RxMAX(sn) \ - (getSn_RXBUF_SIZE(sn) << 10) - -/** - * @brief Gets the max buffer size of socket sn passed as parameters. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @return uint16_t. Value of Socket n TX max buffer size. - */ -//uint16_t getSn_TxMAX(uint8_t sn); -#define getSn_TxMAX(sn) \ - (getSn_TXBUF_SIZE(sn) << 10) - -/** - * @ingroup Basic_IO_function - * @brief It copies data to internal TX memory - * - * @details This function reads the Tx write pointer register and after that, - * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory - * and updates the Tx write pointer register. - * This function is being called by send() and sendto() function also. - * - * @note User should read upper byte first and lower byte later to get proper value. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param wizdata Pointer buffer to write data - * @param len Data length - * @sa wiz_recv_data() - */ -void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); - -/** - * @ingroup Basic_IO_function - * @brief It copies data to your buffer from internal RX memory - * - * @details This function read the Rx read pointer register and after that, - * it copies the received data from internal RX memory - * to wizdata(pointer variable) of the length of len(variable) bytes. - * This function is being called by recv() also. - * - * @note User should read upper byte first and lower byte later to get proper value. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param wizdata Pointer buffer to read data - * @param len Data length - * @sa wiz_send_data() - */ -void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); - -/** - * @ingroup Basic_IO_function - * @brief It discard the received data in RX memory. - * @details It discards the data of the length of len(variable) bytes in internal RX memory. - * @param (uint8_t)sn Socket number. It should be 0 ~ 7. - * @param len Data length - */ -void wiz_recv_ignore(uint8_t sn, uint16_t len); - -#endif // _W5500_H_ diff --git a/drivers/wiznet5k/ethernet/wizchip_conf.c b/drivers/wiznet5k/ethernet/wizchip_conf.c deleted file mode 100644 index 3e54d2c90bcd..000000000000 --- a/drivers/wiznet5k/ethernet/wizchip_conf.c +++ /dev/null @@ -1,662 +0,0 @@ -//****************************************************************************/ -//! -//! \file wizchip_conf.c -//! \brief WIZCHIP Config Header File. -//! \version 1.0.1 -//! \date 2013/10/21 -//! \par Revision history -//! <2014/05/01> V1.0.1 Refer to M20140501 -//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte() -// Issued by Mathias ClauBen. -//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* -//! For remove the warning when pointer type size is not 32bit. -//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type. -//! <2013/10/21> 1st Release -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//*****************************************************************************/ -//A20140501 : for use the type - ptrdiff_t -#include -// - -#include "wizchip_conf.h" -#include "socket.h" - -/** - * @brief Default function to enable interrupt. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ -void wizchip_cris_enter(void) {}; -/** - * @brief Default function to disable interrupt. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ -void wizchip_cris_exit(void) {}; -/** - * @brief Default function to select chip. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ -void wizchip_cs_select(void) {}; -/** - * @brief Default function to deselect chip. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ -void wizchip_cs_deselect(void) {}; -/** - * @brief Default function to read in direct or indirect interface. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ - //M20140501 : Explict pointer type casting -//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); }; -uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }; -/** - * @brief Default function to write in direct or indirect interface. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ - -//M20140501 : Explict pointer type casting -//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; }; -void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }; - -/** - * @brief Default function to read in SPI interface. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ -void wizchip_spi_readbytes(uint8_t *buf, uint32_t len) {} -/** - * @brief Default function to write in SPI interface. - * @note This function help not to access wrong address. If you do not describe this function or register any functions, - * null function is called. - */ -void wizchip_spi_writebytes(const uint8_t *buf, uint32_t len) {} - -/** - * @\ref _WIZCHIP instance - */ -_WIZCHIP WIZCHIP = - { - .id = _WIZCHIP_ID_, - .if_mode = _WIZCHIP_IO_MODE_, - .CRIS._enter = wizchip_cris_enter, - .CRIS._exit = wizchip_cris_exit, - .CS._select = wizchip_cs_select, - .CS._deselect = wizchip_cs_deselect, - .IF.BUS._read_byte = wizchip_bus_readbyte, - .IF.BUS._write_byte = wizchip_bus_writebyte -// .IF.SPI._read_byte = wizchip_spi_readbyte, -// .IF.SPI._write_byte = wizchip_spi_writebyte - }; - -#if _WIZCHIP_ == 5200 // for W5200 ARP errata -static uint8_t _SUBN_[4]; // subnet -#endif -static uint8_t _DNS_[4]; // DNS server ip address -static dhcp_mode _DHCP_; // DHCP mode - -void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) -{ - if(!cris_en || !cris_ex) - { - WIZCHIP.CRIS._enter = wizchip_cris_enter; - WIZCHIP.CRIS._exit = wizchip_cris_exit; - } - else - { - WIZCHIP.CRIS._enter = cris_en; - WIZCHIP.CRIS._exit = cris_ex; - } -} - -void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) -{ - if(!cs_sel || !cs_desel) - { - WIZCHIP.CS._select = wizchip_cs_select; - WIZCHIP.CS._deselect = wizchip_cs_deselect; - } - else - { - WIZCHIP.CS._select = cs_sel; - WIZCHIP.CS._deselect = cs_desel; - } -} - -void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) -{ - while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); - - if(!bus_rb || !bus_wb) - { - WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; - WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; - } - else - { - WIZCHIP.IF.BUS._read_byte = bus_rb; - WIZCHIP.IF.BUS._write_byte = bus_wb; - } -} - -void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t)) -{ - while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); - - if(!spi_rb || !spi_wb) - { - WIZCHIP.IF.SPI._read_bytes = wizchip_spi_readbytes; - WIZCHIP.IF.SPI._write_bytes = wizchip_spi_writebytes; - } - else - { - WIZCHIP.IF.SPI._read_bytes = spi_rb; - WIZCHIP.IF.SPI._write_bytes = spi_wb; - } -} - -int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) -{ - uint8_t tmp = 0; - uint8_t* ptmp[2] = {0,0}; - switch(cwtype) - { - case CW_RESET_WIZCHIP: - wizchip_sw_reset(); - break; - case CW_INIT_WIZCHIP: - if(arg != 0) - { - ptmp[0] = (uint8_t*)arg; - ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; - } - return wizchip_init(ptmp[0], ptmp[1]); - case CW_CLR_INTERRUPT: - wizchip_clrinterrupt(*((intr_kind*)arg)); - break; - case CW_GET_INTERRUPT: - *((intr_kind*)arg) = wizchip_getinterrupt(); - break; - case CW_SET_INTRMASK: - wizchip_setinterruptmask(*((intr_kind*)arg)); - break; - case CW_GET_INTRMASK: - *((intr_kind*)arg) = wizchip_getinterruptmask(); - break; - #if _WIZCHIP_ > 5100 - case CW_SET_INTRTIME: - setINTLEVEL(*(uint16_t*)arg); - break; - case CW_GET_INTRTIME: - *(uint16_t*)arg = getINTLEVEL(); - break; - #endif - case CW_GET_ID: - ((uint8_t*)arg)[0] = WIZCHIP.id[0]; - ((uint8_t*)arg)[1] = WIZCHIP.id[1]; - ((uint8_t*)arg)[2] = WIZCHIP.id[2]; - ((uint8_t*)arg)[3] = WIZCHIP.id[3]; - ((uint8_t*)arg)[4] = WIZCHIP.id[4]; - ((uint8_t*)arg)[5] = 0; - break; - #if _WIZCHIP_ == 5500 - case CW_RESET_PHY: - wizphy_reset(); - break; - case CW_SET_PHYCONF: - wizphy_setphyconf((wiz_PhyConf*)arg); - break; - case CW_GET_PHYCONF: - wizphy_getphyconf((wiz_PhyConf*)arg); - break; - case CW_GET_PHYSTATUS: - break; - case CW_SET_PHYPOWMODE: - return wizphy_setphypmode(*(uint8_t*)arg); - #endif - case CW_GET_PHYPOWMODE: - tmp = wizphy_getphypmode(); - if((int8_t)tmp == -1) return -1; - *(uint8_t*)arg = tmp; - break; - case CW_GET_PHYLINK: - tmp = wizphy_getphylink(); - if((int8_t)tmp == -1) return -1; - *(uint8_t*)arg = tmp; - break; - default: - return -1; - } - return 0; -} - - -int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) -{ - - switch(cntype) - { - case CN_SET_NETINFO: - wizchip_setnetinfo((wiz_NetInfo*)arg); - break; - case CN_GET_NETINFO: - wizchip_getnetinfo((wiz_NetInfo*)arg); - break; - case CN_SET_NETMODE: - return wizchip_setnetmode(*(netmode_type*)arg); - case CN_GET_NETMODE: - *(netmode_type*)arg = wizchip_getnetmode(); - break; - case CN_SET_TIMEOUT: - wizchip_settimeout((wiz_NetTimeout*)arg); - break; - case CN_GET_TIMEOUT: - wizchip_gettimeout((wiz_NetTimeout*)arg); - break; - default: - return -1; - } - return 0; -} - -void wizchip_sw_reset(void) -{ - uint8_t gw[4], sn[4], sip[4]; - uint8_t mac[6]; - getSHAR(mac); - getGAR(gw); getSUBR(sn); getSIPR(sip); - setMR(MR_RST); - getMR(); // for delay - setSHAR(mac); - setGAR(gw); - setSUBR(sn); - setSIPR(sip); -} - -int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) -{ - int8_t i; - int8_t tmp = 0; - wizchip_sw_reset(); - if(txsize) - { - tmp = 0; - for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) - tmp += txsize[i]; - if(tmp > 16) return -1; - for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) - setSn_TXBUF_SIZE(i, txsize[i]); - } - if(rxsize) - { - tmp = 0; - for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) - tmp += rxsize[i]; - if(tmp > 16) return -1; - for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) - setSn_RXBUF_SIZE(i, rxsize[i]); - } - - WIZCHIP_EXPORT(socket_reset)(); - - return 0; -} - -void wizchip_clrinterrupt(intr_kind intr) -{ - uint8_t ir = (uint8_t)intr; - uint8_t sir = (uint8_t)((uint16_t)intr >> 8); -#if _WIZCHIP_ < 5500 - ir |= (1<<4); // IK_WOL -#endif -#if _WIZCHIP_ == 5200 - ir |= (1 << 6); -#endif - -#if _WIZCHIP_ < 5200 - sir &= 0x0F; -#endif - -#if _WIZCHIP_ == 5100 - ir |= sir; - setIR(ir); -#else - setIR(ir); - setSIR(sir); -#endif -} - -intr_kind wizchip_getinterrupt(void) -{ - uint8_t ir = 0; - uint8_t sir = 0; - uint16_t ret = 0; -#if _WIZCHIP_ == 5100 - ir = getIR(); - sir = ir 0x0F; -#else - ir = getIR(); - sir = getSIR(); -#endif - -#if _WIZCHIP_ < 5500 - ir &= ~(1<<4); // IK_WOL -#endif -#if _WIZCHIP_ == 5200 - ir &= ~(1 << 6); -#endif - ret = sir; - ret = (ret << 8) + ir; - return (intr_kind)ret; -} - -void wizchip_setinterruptmask(intr_kind intr) -{ - uint8_t imr = (uint8_t)intr; - uint8_t simr = (uint8_t)((uint16_t)intr >> 8); -#if _WIZCHIP_ < 5500 - imr &= ~(1<<4); // IK_WOL -#endif -#if _WIZCHIP_ == 5200 - imr &= ~(1 << 6); -#endif - -#if _WIZCHIP_ < 5200 - simr &= 0x0F; -#endif - -#if _WIZCHIP_ == 5100 - imr |= simr; - setIMR(imr); -#else - setIMR(imr); - setSIMR(simr); -#endif -} - -intr_kind wizchip_getinterruptmask(void) -{ - uint8_t imr = 0; - uint8_t simr = 0; - uint16_t ret = 0; -#if _WIZCHIP_ == 5100 - imr = getIMR(); - simr = imr 0x0F; -#else - imr = getIMR(); - simr = getSIMR(); -#endif - -#if _WIZCHIP_ < 5500 - imr &= ~(1<<4); // IK_WOL -#endif -#if _WIZCHIP_ == 5200 - imr &= ~(1 << 6); // IK_DEST_UNREACH -#endif - ret = simr; - ret = (ret << 8) + imr; - return (intr_kind)ret; -} - -int8_t wizphy_getphylink(void) -{ - int8_t tmp; -#if _WIZCHIP_ == 5200 - if(getPHYSTATUS() & PHYSTATUS_LINK) - tmp = PHY_LINK_ON; - else - tmp = PHY_LINK_OFF; -#elif _WIZCHIP_ == 5500 - if(getPHYCFGR() & PHYCFGR_LNK_ON) - tmp = PHY_LINK_ON; - else - tmp = PHY_LINK_OFF; -#else - tmp = -1; -#endif - return tmp; -} - -#if _WIZCHIP_ > 5100 - -int8_t wizphy_getphypmode(void) -{ - int8_t tmp = 0; - #if _WIZCHIP_ == 5200 - if(getPHYSTATUS() & PHYSTATUS_POWERDOWN) - tmp = PHY_POWER_DOWN; - else - tmp = PHY_POWER_NORM; - #elif _WIZCHIP_ == 5500 - if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) - tmp = PHY_POWER_DOWN; - else - tmp = PHY_POWER_NORM; - #else - tmp = -1; - #endif - return tmp; -} -#endif - -#if _WIZCHIP_ == 5500 -void wizphy_reset(void) -{ - uint8_t tmp = getPHYCFGR(); - tmp &= PHYCFGR_RST; - setPHYCFGR(tmp); - tmp = getPHYCFGR(); - tmp |= ~PHYCFGR_RST; - setPHYCFGR(tmp); -} - -void wizphy_setphyconf(wiz_PhyConf* phyconf) -{ - uint8_t tmp = 0; - if(phyconf->by == PHY_CONFBY_SW) - tmp |= PHYCFGR_OPMD; - else - tmp &= ~PHYCFGR_OPMD; - if(phyconf->mode == PHY_MODE_AUTONEGO) - tmp |= PHYCFGR_OPMDC_ALLA; - else - { - if(phyconf->duplex == PHY_DUPLEX_FULL) - { - if(phyconf->speed == PHY_SPEED_100) - tmp |= PHYCFGR_OPMDC_100F; - else - tmp |= PHYCFGR_OPMDC_10F; - } - else - { - if(phyconf->speed == PHY_SPEED_100) - tmp |= PHYCFGR_OPMDC_100H; - else - tmp |= PHYCFGR_OPMDC_10H; - } - } - setPHYCFGR(tmp); - wizphy_reset(); -} - -void wizphy_getphyconf(wiz_PhyConf* phyconf) -{ - uint8_t tmp = 0; - tmp = getPHYCFGR(); - phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; - switch(tmp & PHYCFGR_OPMDC_ALLA) - { - case PHYCFGR_OPMDC_ALLA: - case PHYCFGR_OPMDC_100FA: - phyconf->mode = PHY_MODE_AUTONEGO; - break; - default: - phyconf->mode = PHY_MODE_MANUAL; - break; - } - switch(tmp & PHYCFGR_OPMDC_ALLA) - { - case PHYCFGR_OPMDC_100FA: - case PHYCFGR_OPMDC_100F: - case PHYCFGR_OPMDC_100H: - phyconf->speed = PHY_SPEED_100; - break; - default: - phyconf->speed = PHY_SPEED_10; - break; - } - switch(tmp & PHYCFGR_OPMDC_ALLA) - { - case PHYCFGR_OPMDC_100FA: - case PHYCFGR_OPMDC_100F: - case PHYCFGR_OPMDC_10F: - phyconf->duplex = PHY_DUPLEX_FULL; - break; - default: - phyconf->duplex = PHY_DUPLEX_HALF; - break; - } -} - -void wizphy_getphystat(wiz_PhyConf* phyconf) -{ - uint8_t tmp = getPHYCFGR(); - phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; - phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; -} - -int8_t wizphy_setphypmode(uint8_t pmode) -{ - uint8_t tmp = 0; - tmp = getPHYCFGR(); - if((tmp & PHYCFGR_OPMD)== 0) return -1; - tmp &= ~PHYCFGR_OPMDC_ALLA; - if( pmode == PHY_POWER_DOWN) - tmp |= PHYCFGR_OPMDC_PDOWN; - else - tmp |= PHYCFGR_OPMDC_ALLA; - setPHYCFGR(tmp); - wizphy_reset(); - tmp = getPHYCFGR(); - if( pmode == PHY_POWER_DOWN) - { - if(tmp & PHYCFGR_OPMDC_PDOWN) return 0; - } - else - { - if(tmp & PHYCFGR_OPMDC_ALLA) return 0; - } - return -1; -} -#endif - - -void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) -{ - setSHAR(pnetinfo->mac); - setGAR(pnetinfo->gw); - setSUBR(pnetinfo->sn); - setSIPR(pnetinfo->ip); -#if _WIZCHIP_ == 5200 // for W5200 ARP errata - _SUBN_[0] = pnetinfo->sn[0]; - _SUBN_[1] = pnetinfo->sn[1]; - _SUBN_[2] = pnetinfo->sn[2]; - _SUBN_[3] = pnetinfo->sn[3]; -#endif - _DNS_[0] = pnetinfo->dns[0]; - _DNS_[1] = pnetinfo->dns[1]; - _DNS_[2] = pnetinfo->dns[2]; - _DNS_[3] = pnetinfo->dns[3]; - _DHCP_ = pnetinfo->dhcp; -} - -void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) -{ - getSHAR(pnetinfo->mac); - getGAR(pnetinfo->gw); - getSUBR(pnetinfo->sn); - getSIPR(pnetinfo->ip); -#if _WIZCHIP_ == 5200 // for W5200 ARP errata - pnetinfo->sn[0] = _SUBN_[0]; - pnetinfo->sn[1] = _SUBN_[1]; - pnetinfo->sn[2] = _SUBN_[2]; - pnetinfo->sn[3] = _SUBN_[3]; -#endif - pnetinfo->dns[0]= _DNS_[0]; - pnetinfo->dns[1]= _DNS_[1]; - pnetinfo->dns[2]= _DNS_[2]; - pnetinfo->dns[3]= _DNS_[3]; - pnetinfo->dhcp = _DHCP_; -} - -#if _WIZCHIP_ == 5200 // for W5200 ARP errata -uint8_t *wizchip_getsubn(void) { - return _SUBN_; -} -#endif - -int8_t wizchip_setnetmode(netmode_type netmode) -{ - uint8_t tmp = 0; -#if _WIZCHIP_ != 5500 - if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1; -#else - if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1; -#endif - tmp = getMR(); - tmp |= (uint8_t)netmode; - setMR(tmp); - return 0; -} - -netmode_type wizchip_getnetmode(void) -{ - return (netmode_type) getMR(); -} - -void wizchip_settimeout(wiz_NetTimeout* nettime) -{ - setRCR(nettime->retry_cnt); - setRTR(nettime->time_100us); -} - -void wizchip_gettimeout(wiz_NetTimeout* nettime) -{ - nettime->retry_cnt = getRCR(); - nettime->time_100us = getRTR(); -} diff --git a/drivers/wiznet5k/ethernet/wizchip_conf.h b/drivers/wiznet5k/ethernet/wizchip_conf.h deleted file mode 100644 index 4a7a7bd69140..000000000000 --- a/drivers/wiznet5k/ethernet/wizchip_conf.h +++ /dev/null @@ -1,554 +0,0 @@ -//***************************************************************************** -// -//! \file wizchip_conf.h -//! \brief WIZCHIP Config Header File. -//! \version 1.0.0 -//! \date 2013/10/21 -//! \par Revision history -//! <2013/10/21> 1st Release -//! \author MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -/** - * @defgroup extra_functions 2. WIZnet Extra Functions - * - * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions. - * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n - * - */ - -#ifndef _WIZCHIP_CONF_H_ -#define _WIZCHIP_CONF_H_ - -#include -/** - * @brief Select WIZCHIP. - * @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n - * ex> #define \_WIZCHIP_ 5500 - */ -#ifndef _WIZCHIP_ -#define _WIZCHIP_ 5200 // 5100, 5200, 5500 -#endif - -#define _WIZCHIP_IO_MODE_NONE_ 0x0000 -#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ -#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ -//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 -//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 -// Add to -// - -#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ -#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ - -#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ -#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ - - -#if (_WIZCHIP_ == 5100) - #define _WIZCHIP_ID_ "W5100\0" -/** - * @brief Define interface mode. - * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ - */ - -// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ -// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ - #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ - -#elif (_WIZCHIP_ == 5200) - #define _WIZCHIP_ID_ "W5200\0" -/** - * @brief Define interface mode. - * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ - */ -// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ - #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ - #include "w5200/w5200.h" -#elif (_WIZCHIP_ == 5500) - #define _WIZCHIP_ID_ "W5500\0" - -/** - * @brief Define interface mode. \n - * @todo Should select interface mode as chip. - * - @ref \_WIZCHIP_IO_MODE_SPI_ \n - * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n - * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n - * - @ref \_WIZCHIP_IO_MODE_BUS_ \n - * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n - * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n - * - Others will be defined in future. \n\n - * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ - * - */ - //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ - #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ - #include "w5500/w5500.h" -#else - #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" -#endif - -#ifndef _WIZCHIP_IO_MODE_ - #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" -#endif - -/** - * @brief Define I/O base address when BUS IF mode. - * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, - * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n - * ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 - */ -#define _WIZCHIP_IO_BASE_ 0x00000000 // - -#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS - #ifndef _WIZCHIP_IO_BASE_ - #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." - #endif -#endif - -#if _WIZCHIP_ > 5100 - #define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP -#else - #define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP -#endif - - -/******************************************************** -* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. -*********************************************************/ -/** - * @ingroup DATA_TYPE - * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 - */ -typedef struct __WIZCHIP -{ - uint16_t if_mode; ///< host interface mode - uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on. - /** - * The set of critical section callback func. - */ - struct _CRIS - { - void (*_enter) (void); ///< crtical section enter - void (*_exit) (void); ///< critial section exit - }CRIS; - /** - * The set of @ref\_WIZCHIP_ select control callback func. - */ - struct _CS - { - void (*_select) (void); ///< @ref \_WIZCHIP_ selected - void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected - }CS; - /** - * The set of interface IO callback func. - */ - union _IF - { - /** - * For BUS interface IO - */ - struct - { - uint8_t (*_read_byte) (uint32_t AddrSel); - void (*_write_byte) (uint32_t AddrSel, uint8_t wb); - }BUS; - /** - * For SPI interface IO - */ - struct - { - void (*_read_bytes) (uint8_t *buf, uint32_t len); - void (*_write_bytes) (const uint8_t *buf, uint32_t len); - }SPI; - // To be added - // - }IF; -}_WIZCHIP; - -extern _WIZCHIP WIZCHIP; - -/** - * @ingroup DATA_TYPE - * WIZCHIP control type enumration used in @ref ctlwizchip(). - */ -typedef enum -{ - CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly - CW_INIT_WIZCHIP, ///< Inializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t. - CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP - CW_CLR_INTERRUPT, ///< Clears interrupt - CW_SET_INTRMASK, ///< Masks interrupt - CW_GET_INTRMASK, ///< Get interrupt mask - CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt. - CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt. - CW_GET_ID, ///< Gets WIZCHIP name. - -#if _WIZCHIP_ == 5500 - CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000 - CW_SET_PHYCONF, ///< When PHY configured by interal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 - CW_GET_PHYCONF, ///< Get PHY operation mode in interal register. Valid Only W5000 - CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000 - CW_SET_PHYPOWMODE, ///< Set PHY power mode as noraml and down when PHYSTATUS.OPMD == 1. Valid Only W5000 -#endif - CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal - CW_GET_PHYLINK ///< Get PHY Link status -}ctlwizchip_type; - -/** - * @ingroup DATA_TYPE - * Network control type enumration used in @ref ctlnetwork(). - */ -typedef enum -{ - CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo - CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo - CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode - CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode - CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. - CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. -}ctlnetwork_type; - -/** - * @ingroup DATA_TYPE - * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK - * and CW_GET_INTRMASK is used in @ref ctlnetwork(). - * It can be used with OR operation. - */ -typedef enum -{ -#if _WIZCHIP_ > 5200 - IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. -#endif - - IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected - -#if _WIZCHIP_ != 5200 - IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreable, No use in W5200 -#endif - - IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred - - IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt - IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt - IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt - IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt -#if _WIZCHIP_ > 5100 - IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 - IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 - IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 - IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 -#endif - -#if _WIZCHIP_ > 5100 - IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrpt -#else - IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrpt -#endif -}intr_kind; - -#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin -#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register -#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. -#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation -#define PHY_SPEED_10 0 ///< Link Speed 10 -#define PHY_SPEED_100 1 ///< Link Speed 100 -#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex -#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex -#define PHY_LINK_OFF 0 ///< Link Off -#define PHY_LINK_ON 1 ///< Link On -#define PHY_POWER_NORM 0 ///< PHY power normal mode -#define PHY_POWER_DOWN 1 ///< PHY power down mode - - -#if _WIZCHIP_ == 5500 -/** - * @ingroup DATA_TYPE - * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500, - * and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n - * Valid only in W5500. - */ -typedef struct wiz_PhyConf_t -{ - uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW - uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO - uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 - uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL - //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN - //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF - }wiz_PhyConf; -#endif - -/** - * @ingroup DATA_TYPE - * It used in setting dhcp_mode of @ref wiz_NetInfo. - */ -typedef enum -{ - NETINFO_STATIC = 1, ///< Static IP configuration by manually. - NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever -}dhcp_mode; - -/** - * @ingroup DATA_TYPE - * Network Information for WIZCHIP - */ -typedef struct wiz_NetInfo_t -{ - uint8_t mac[6]; ///< Source Mac Address - uint8_t ip[4]; ///< Source IP Address - uint8_t sn[4]; ///< Subnet Mask - uint8_t gw[4]; ///< Gateway IP Address - uint8_t dns[4]; ///< DNS server IP Address - dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP -}wiz_NetInfo; - -/** - * @ingroup DATA_TYPE - * Network mode - */ -typedef enum -{ -#if _WIZCHIP_ == 5500 - NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500 -#endif - NM_WAKEONLAN = (1<<5), ///< Wake On Lan - NM_PINGBLOCK = (1<<4), ///< Block ping-request - NM_PPPOE = (1<<3), ///< PPPoE mode -}netmode_type; - -/** - * @ingroup DATA_TYPE - * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. - */ -typedef struct wiz_NetTimeout_t -{ - uint8_t retry_cnt; ///< retry count - uint16_t time_100us; ///< time unit 100us -}wiz_NetTimeout; - -/** - *@brief Registers call back function for critical section of I/O functions such as - *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. - *@param cris_en : callback function for critical section enter. - *@param cris_ex : callback function for critical section exit. - *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. - *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. - */ -void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); - - -/** - *@brief Registers call back function for WIZCHIP select & deselect. - *@param cs_sel : callback function for WIZCHIP select - *@param cs_desel : callback fucntion for WIZCHIP deselect - *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. - *@note If you do not describe or register, null function is called. - */ -void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); - -/** - *@brief Registers call back function for bus interface. - *@param bus_rb : callback function to read byte data using system bus - *@param bus_wb : callback function to write byte data using system bus - *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function - *or register your functions. - *@note If you do not describe or register, null function is called. - */ -void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); - -/** - *@brief Registers call back function for SPI interface. - *@param spi_rb : callback function to read byte usig SPI - *@param spi_wb : callback function to write byte usig SPI - *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function - *or register your functions. - *@note If you do not describe or register, null function is called. - */ -void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t)); - -/** - * @ingroup extra_functions - * @brief Controls to the WIZCHIP. - * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), - * controls interrupt & mask and so on. - * @param cwtype : Decides to the control type - * @param arg : arg type is dependent on cwtype. - * @return 0 : Success \n - * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP - */ -int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); - -/** - * @ingroup extra_functions - * @brief Controls to network. - * @details Controls to network environment, mode, timeout and so on. - * @param cntype : Input. Decides to the control type - * @param arg : Inout. arg type is dependent on cntype. - * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n - * 0 : Success - */ -int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); - - -/* - * The following functions are implemented for internal use. - * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). - */ - -/** - * @ingroup extra_functions - * @brief Reset WIZCHIP by softly. - */ -void wizchip_sw_reset(void); - -/** - * @ingroup extra_functions - * @brief Initializes WIZCHIP with socket buffer size - * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. - * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. - * @return 0 : succcess \n - * -1 : fail. Invalid buffer size - */ -int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); - -/** - * @ingroup extra_functions - * @brief Clear Interrupt of WIZCHIP. - * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. - */ -void wizchip_clrinterrupt(intr_kind intr); - -/** - * @ingroup extra_functions - * @brief Get Interrupt of WIZCHIP. - * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. - */ -intr_kind wizchip_getinterrupt(void); - -/** - * @ingroup extra_functions - * @brief Mask or Unmask Interrupt of WIZCHIP. - * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. - */ -void wizchip_setinterruptmask(intr_kind intr); - -/** - * @ingroup extra_functions - * @brief Get Interrupt mask of WIZCHIP. - * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. - */ -intr_kind wizchip_getinterruptmask(void); - -#if _WIZCHIP_ > 5100 - int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100 - int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 -#endif - -#if _WIZCHIP_ == 5500 - void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 -/** - * @ingroup extra_functions - * @brief Set the phy information for WIZCHIP without power mode - * @param phyconf : @ref wiz_PhyConf - */ - void wizphy_setphyconf(wiz_PhyConf* phyconf); - /** - * @ingroup extra_functions - * @brief Get phy configuration information. - * @param phyconf : @ref wiz_PhyConf - */ - void wizphy_getphyconf(wiz_PhyConf* phyconf); - /** - * @ingroup extra_functions - * @brief Get phy status. - * @param phyconf : @ref wiz_PhyConf - */ - void wizphy_getphystat(wiz_PhyConf* phyconf); - /** - * @ingroup extra_functions - * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 - * @param pmode Settig value of power down mode. - */ - int8_t wizphy_setphypmode(uint8_t pmode); -#endif - -/** -* @ingroup extra_functions - * @brief Set the network information for WIZCHIP - * @param pnetinfo : @ref wizNetInfo - */ -void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); - -/** - * @ingroup extra_functions - * @brief Get the network information for WIZCHIP - * @param pnetinfo : @ref wizNetInfo - */ -void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); - -#if _WIZCHIP_ == 5200 // for W5200 ARP errata -uint8_t *wizchip_getsubn(void); -#endif - -/** - * @ingroup extra_functions - * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. - * @param pnetinfo Value of network mode. Refer to @ref netmode_type. - */ -int8_t wizchip_setnetmode(netmode_type netmode); - -/** - * @ingroup extra_functions - * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. - * @return Value of network mode. Refer to @ref netmode_type. - */ -netmode_type wizchip_getnetmode(void); - -/** - * @ingroup extra_functions - * @brief Set retry time value(@ref RTR) and retry count(@ref RCR). - * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. - * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. - */ -void wizchip_settimeout(wiz_NetTimeout* nettime); - -/** - * @ingroup extra_functions - * @brief Get retry time value(@ref RTR) and retry count(@ref RCR). - * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. - * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. - */ -void wizchip_gettimeout(wiz_NetTimeout* nettime); - -#endif // _WIZCHIP_CONF_H_ diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.c b/drivers/wiznet5k/internet/dhcp/dhcp.c deleted file mode 100644 index 5747582599db..000000000000 --- a/drivers/wiznet5k/internet/dhcp/dhcp.c +++ /dev/null @@ -1,978 +0,0 @@ -//***************************************************************************** -// -//! \file dhcp.c -//! \brief DHCP APIs implement file. -//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. -//! \version 1.1.0 -//! \date 2013/11/18 -//! \par Revision history -//! <2013/11/18> 1st Release -//! <2012/12/20> V1.1.0 -//! 1. Optimize code -//! 2. Add reg_dhcp_cbfunc() -//! 3. Add DHCP_stop() -//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() -//! 5. Don't care system endian -//! 6. Add comments -//! <2012/12/26> V1.1.1 -//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization -//! \author Eric Jung & MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -//#include "Ethernet/socket.h" -//#include "Internet/DHCP/dhcp.h" -#include "../../Ethernet/socket.h" -#include "dhcp.h" - -/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ - -#ifdef _DHCP_DEBUG_ - #include -#endif - -/* DHCP state machine. */ -#define STATE_DHCP_INIT 0 ///< Initialize -#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER -#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK -#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased -#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP -#define STATE_DHCP_RELEASE 5 ///< No use -#define STATE_DHCP_STOP 6 ///< Stop processing DHCP - -#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG -#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG - -/* DHCP message OP code */ -#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG -#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG - -/* DHCP message type */ -#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG -#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG -#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG -#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG -#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG -#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG -#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use -#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use - -#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG -#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG - -#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG -#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG -#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG - -#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time - -#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG -#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG - -/* - * @brief DHCP option and value (cf. RFC1533) - */ -enum -{ - padOption = 0, - subnetMask = 1, - timerOffset = 2, - routersOnSubnet = 3, - timeServer = 4, - nameServer = 5, - dns = 6, - logServer = 7, - cookieServer = 8, - lprServer = 9, - impressServer = 10, - resourceLocationServer = 11, - hostName = 12, - bootFileSize = 13, - meritDumpFile = 14, - domainName = 15, - swapServer = 16, - rootPath = 17, - extentionsPath = 18, - IPforwarding = 19, - nonLocalSourceRouting = 20, - policyFilter = 21, - maxDgramReasmSize = 22, - defaultIPTTL = 23, - pathMTUagingTimeout = 24, - pathMTUplateauTable = 25, - ifMTU = 26, - allSubnetsLocal = 27, - broadcastAddr = 28, - performMaskDiscovery = 29, - maskSupplier = 30, - performRouterDiscovery = 31, - routerSolicitationAddr = 32, - staticRoute = 33, - trailerEncapsulation = 34, - arpCacheTimeout = 35, - ethernetEncapsulation = 36, - tcpDefaultTTL = 37, - tcpKeepaliveInterval = 38, - tcpKeepaliveGarbage = 39, - nisDomainName = 40, - nisServers = 41, - ntpServers = 42, - vendorSpecificInfo = 43, - netBIOSnameServer = 44, - netBIOSdgramDistServer = 45, - netBIOSnodeType = 46, - netBIOSscope = 47, - xFontServer = 48, - xDisplayManager = 49, - dhcpRequestedIPaddr = 50, - dhcpIPaddrLeaseTime = 51, - dhcpOptionOverload = 52, - dhcpMessageType = 53, - dhcpServerIdentifier = 54, - dhcpParamRequest = 55, - dhcpMsg = 56, - dhcpMaxMsgSize = 57, - dhcpT1value = 58, - dhcpT2value = 59, - dhcpClassIdentifier = 60, - dhcpClientIdentifier = 61, - endOption = 255 -}; - -/* - * @brief DHCP message format - */ -typedef struct { - uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY - uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB - uint8_t hlen; ///< @ref DHCP_HLENETHERNET - uint8_t hops; ///< @ref DHCP_HOPS - uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. - uint16_t secs; ///< @ref DHCP_SECS - uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST - uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever - uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server - uint8_t siaddr[4]; ///< No use - uint8_t giaddr[4]; ///< No use - uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero - uint8_t sname[64]; ///< No use - uint8_t file[128]; ///< No use - uint8_t OPT[OPT_SIZE]; ///< Option -} RIP_MSG; - - - -uint8_t DHCP_SOCKET; // Socket number for DHCP - -uint8_t DHCP_SIP[4]; // DHCP Server IP address - -// Network information from DHCP Server -uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address -uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP -uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP -uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP -uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP - - -int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state -int8_t dhcp_retry_count = 0; - -uint32_t dhcp_lease_time = INFINITE_LEASETIME; -volatile uint32_t dhcp_tick_1s = 0; // unit 1 second -uint32_t dhcp_tick_next = DHCP_WAIT_TIME ; - -uint32_t DHCP_XID; // Any number - -RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing - -uint8_t HOST_NAME[] = DCHP_HOST_NAME; - -uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. - -/* The default callback function */ -void default_ip_assign(void); -void default_ip_update(void); -void default_ip_conflict(void); - -/* Callback handler */ -void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ -void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ -void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ - -void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); - - -/* send DISCOVER message to DHCP server */ -void send_DHCP_DISCOVER(void); - -/* send REQEUST message to DHCP server */ -void send_DHCP_REQUEST(void); - -/* send DECLINE message to DHCP server */ -void send_DHCP_DECLINE(void); - -/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ -int8_t check_DHCP_leasedIP(void); - -/* check the timeout in DHCP process */ -uint8_t check_DHCP_timeout(void); - -/* Intialize to timeout process. */ -void reset_DHCP_timeout(void); - -/* Parse message as OFFER and ACK and NACK from DHCP server.*/ -int8_t parseDHCPCMSG(void); - -/* The default handler of ip assign first */ -void default_ip_assign(void) -{ - setSIPR(DHCP_allocated_ip); - setSUBR(DHCP_allocated_sn); - setGAR (DHCP_allocated_gw); -} - -/* The default handler of ip changed */ -void default_ip_update(void) -{ - /* WIZchip Software Reset */ - setMR(MR_RST); - getMR(); // for delay - default_ip_assign(); - setSHAR(DHCP_CHADDR); -} - -/* The default handler of ip changed */ -void default_ip_conflict(void) -{ - // WIZchip Software Reset - setMR(MR_RST); - getMR(); // for delay - setSHAR(DHCP_CHADDR); -} - -/* register the call back func. */ -void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)) -{ - dhcp_ip_assign = default_ip_assign; - dhcp_ip_update = default_ip_update; - dhcp_ip_conflict = default_ip_conflict; - if(ip_assign) dhcp_ip_assign = ip_assign; - if(ip_update) dhcp_ip_update = ip_update; - if(ip_conflict) dhcp_ip_conflict = ip_conflict; -} - -/* make the common DHCP message */ -void makeDHCPMSG(void) -{ - uint8_t bk_mac[6]; - uint8_t* ptmp; - uint8_t i; - getSHAR(bk_mac); - pDHCPMSG->op = DHCP_BOOTREQUEST; - pDHCPMSG->htype = DHCP_HTYPE10MB; - pDHCPMSG->hlen = DHCP_HLENETHERNET; - pDHCPMSG->hops = DHCP_HOPS; - ptmp = (uint8_t*)(&pDHCPMSG->xid); - *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); - *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); - *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); - *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); - pDHCPMSG->secs = DHCP_SECS; - ptmp = (uint8_t*)(&pDHCPMSG->flags); - *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); - *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); - - pDHCPMSG->ciaddr[0] = 0; - pDHCPMSG->ciaddr[1] = 0; - pDHCPMSG->ciaddr[2] = 0; - pDHCPMSG->ciaddr[3] = 0; - - pDHCPMSG->yiaddr[0] = 0; - pDHCPMSG->yiaddr[1] = 0; - pDHCPMSG->yiaddr[2] = 0; - pDHCPMSG->yiaddr[3] = 0; - - pDHCPMSG->siaddr[0] = 0; - pDHCPMSG->siaddr[1] = 0; - pDHCPMSG->siaddr[2] = 0; - pDHCPMSG->siaddr[3] = 0; - - pDHCPMSG->giaddr[0] = 0; - pDHCPMSG->giaddr[1] = 0; - pDHCPMSG->giaddr[2] = 0; - pDHCPMSG->giaddr[3] = 0; - - pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; - pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; - pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; - pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; - pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; - pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; - - for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; - for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; - for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; - - // MAGIC_COOKIE - pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); - pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); - pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); - pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0; -} - -/* SEND DHCP DISCOVER */ -void send_DHCP_DISCOVER(void) -{ - uint16_t i; - uint8_t ip[4]; - uint16_t k = 0; - - makeDHCPMSG(); - - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - - // Option Request Param - pDHCPMSG->OPT[k++] = dhcpMessageType; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_DISCOVER; - - // Client identifier - pDHCPMSG->OPT[k++] = dhcpClientIdentifier; - pDHCPMSG->OPT[k++] = 0x07; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - - // host name - pDHCPMSG->OPT[k++] = hostName; - pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname - for(i = 0 ; HOST_NAME[i] != 0; i++) - pDHCPMSG->OPT[k++] = HOST_NAME[i]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname - - pDHCPMSG->OPT[k++] = dhcpParamRequest; - pDHCPMSG->OPT[k++] = 0x06; // length of request - pDHCPMSG->OPT[k++] = subnetMask; - pDHCPMSG->OPT[k++] = routersOnSubnet; - pDHCPMSG->OPT[k++] = dns; - pDHCPMSG->OPT[k++] = domainName; - pDHCPMSG->OPT[k++] = dhcpT1value; - pDHCPMSG->OPT[k++] = dhcpT2value; - pDHCPMSG->OPT[k++] = endOption; - - for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; - - // send broadcasting packet - ip[0] = 255; - ip[1] = 255; - ip[2] = 255; - ip[3] = 255; - -#ifdef _DHCP_DEBUG_ - printf("> Send DHCP_DISCOVER\r\n"); -#endif - - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); -} - -/* SEND DHCP REQUEST */ -void send_DHCP_REQUEST(void) -{ - int i; - uint8_t ip[4]; - uint16_t k = 0; - - makeDHCPMSG(); - - if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) - { - *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); - *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); - pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; - pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; - pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; - pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; - ip[0] = DHCP_SIP[0]; - ip[1] = DHCP_SIP[1]; - ip[2] = DHCP_SIP[2]; - ip[3] = DHCP_SIP[3]; - } - else - { - ip[0] = 255; - ip[1] = 255; - ip[2] = 255; - ip[3] = 255; - } - - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - - // Option Request Param. - pDHCPMSG->OPT[k++] = dhcpMessageType; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_REQUEST; - - pDHCPMSG->OPT[k++] = dhcpClientIdentifier; - pDHCPMSG->OPT[k++] = 0x07; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - - if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) - { - pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; - - pDHCPMSG->OPT[k++] = dhcpServerIdentifier; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_SIP[0]; - pDHCPMSG->OPT[k++] = DHCP_SIP[1]; - pDHCPMSG->OPT[k++] = DHCP_SIP[2]; - pDHCPMSG->OPT[k++] = DHCP_SIP[3]; - } - - // host name - pDHCPMSG->OPT[k++] = hostName; - pDHCPMSG->OPT[k++] = 0; // length of hostname - for(i = 0 ; HOST_NAME[i] != 0; i++) - pDHCPMSG->OPT[k++] = HOST_NAME[i]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname - - pDHCPMSG->OPT[k++] = dhcpParamRequest; - pDHCPMSG->OPT[k++] = 0x08; - pDHCPMSG->OPT[k++] = subnetMask; - pDHCPMSG->OPT[k++] = routersOnSubnet; - pDHCPMSG->OPT[k++] = dns; - pDHCPMSG->OPT[k++] = domainName; - pDHCPMSG->OPT[k++] = dhcpT1value; - pDHCPMSG->OPT[k++] = dhcpT2value; - pDHCPMSG->OPT[k++] = performRouterDiscovery; - pDHCPMSG->OPT[k++] = staticRoute; - pDHCPMSG->OPT[k++] = endOption; - - for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; - -#ifdef _DHCP_DEBUG_ - printf("> Send DHCP_REQUEST\r\n"); -#endif - - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); - -} - -/* SEND DHCP DHCPDECLINE */ -void send_DHCP_DECLINE(void) -{ - int i; - uint8_t ip[4]; - uint16_t k = 0; - - makeDHCPMSG(); - - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - - *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); - *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); - - // Option Request Param. - pDHCPMSG->OPT[k++] = dhcpMessageType; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_DECLINE; - - pDHCPMSG->OPT[k++] = dhcpClientIdentifier; - pDHCPMSG->OPT[k++] = 0x07; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - - pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; - - pDHCPMSG->OPT[k++] = dhcpServerIdentifier; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_SIP[0]; - pDHCPMSG->OPT[k++] = DHCP_SIP[1]; - pDHCPMSG->OPT[k++] = DHCP_SIP[2]; - pDHCPMSG->OPT[k++] = DHCP_SIP[3]; - - pDHCPMSG->OPT[k++] = endOption; - - for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; - - //send broadcasting packet - ip[0] = 0xFF; - ip[1] = 0xFF; - ip[2] = 0xFF; - ip[3] = 0xFF; - -#ifdef _DHCP_DEBUG_ - printf("\r\n> Send DHCP_DECLINE\r\n"); -#endif - - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); -} - -/* PARSE REPLY pDHCPMSG */ -int8_t parseDHCPMSG(void) -{ - uint8_t svr_addr[6]; - uint16_t svr_port; - uint16_t len; - - uint8_t * p; - uint8_t * e; - uint8_t type; - uint8_t opt_len; - - if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) - { - len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); - #ifdef _DHCP_DEBUG_ - printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); - #endif - } - else return 0; - if (svr_port == DHCP_SERVER_PORT) { - // compare mac address - if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || - (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || - (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) - return 0; - type = 0; - p = (uint8_t *)(&pDHCPMSG->op); - p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) - e = p + (len - 240); - - while ( p < e ) { - - switch ( *p ) { - - case endOption : - p = e; // for break while(p < e) - break; - case padOption : - p++; - break; - case dhcpMessageType : - p++; - p++; - type = *p++; - break; - case subnetMask : - p++; - p++; - DHCP_allocated_sn[0] = *p++; - DHCP_allocated_sn[1] = *p++; - DHCP_allocated_sn[2] = *p++; - DHCP_allocated_sn[3] = *p++; - break; - case routersOnSubnet : - p++; - opt_len = *p++; - DHCP_allocated_gw[0] = *p++; - DHCP_allocated_gw[1] = *p++; - DHCP_allocated_gw[2] = *p++; - DHCP_allocated_gw[3] = *p++; - p = p + (opt_len - 4); - break; - case dns : - p++; - opt_len = *p++; - DHCP_allocated_dns[0] = *p++; - DHCP_allocated_dns[1] = *p++; - DHCP_allocated_dns[2] = *p++; - DHCP_allocated_dns[3] = *p++; - p = p + (opt_len - 4); - break; - case dhcpIPaddrLeaseTime : - p++; - opt_len = *p++; - dhcp_lease_time = *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - #ifdef _DHCP_DEBUG_ - dhcp_lease_time = 10; - #endif - break; - case dhcpServerIdentifier : - p++; - opt_len = *p++; - DHCP_SIP[0] = *p++; - DHCP_SIP[1] = *p++; - DHCP_SIP[2] = *p++; - DHCP_SIP[3] = *p++; - break; - default : - p++; - opt_len = *p++; - p += opt_len; - break; - } // switch - } // while - } // if - return type; -} - -uint8_t DHCP_run(void) -{ - uint8_t type; - uint8_t ret; - - if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; - - if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) - socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); - - ret = DHCP_RUNNING; - type = parseDHCPMSG(); - - switch ( dhcp_state ) { - case STATE_DHCP_INIT : - DHCP_allocated_ip[0] = 0; - DHCP_allocated_ip[1] = 0; - DHCP_allocated_ip[2] = 0; - DHCP_allocated_ip[3] = 0; - send_DHCP_DISCOVER(); - dhcp_state = STATE_DHCP_DISCOVER; - break; - case STATE_DHCP_DISCOVER : - if (type == DHCP_OFFER){ -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_OFFER\r\n"); -#endif - DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; - DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; - DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; - DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; - - send_DHCP_REQUEST(); - dhcp_state = STATE_DHCP_REQUEST; - } else ret = check_DHCP_timeout(); - break; - - case STATE_DHCP_REQUEST : - if (type == DHCP_ACK) { - -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_ACK\r\n"); -#endif - if (check_DHCP_leasedIP()) { - // Network info assignment from DHCP - dhcp_ip_assign(); - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_LEASED; - } else { - // IP address conflict occurred - reset_DHCP_timeout(); - dhcp_ip_conflict(); - dhcp_state = STATE_DHCP_INIT; - } - } else if (type == DHCP_NAK) { - -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_NACK\r\n"); -#endif - - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_DISCOVER; - } else ret = check_DHCP_timeout(); - break; - - case STATE_DHCP_LEASED : - ret = DHCP_IP_LEASED; - if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { - -#ifdef _DHCP_DEBUG_ - printf("> Maintains the IP address \r\n"); -#endif - - type = 0; - OLD_allocated_ip[0] = DHCP_allocated_ip[0]; - OLD_allocated_ip[1] = DHCP_allocated_ip[1]; - OLD_allocated_ip[2] = DHCP_allocated_ip[2]; - OLD_allocated_ip[3] = DHCP_allocated_ip[3]; - - DHCP_XID++; - - send_DHCP_REQUEST(); - - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_REREQUEST; - } - break; - - case STATE_DHCP_REREQUEST : - ret = DHCP_IP_LEASED; - if (type == DHCP_ACK) { - dhcp_retry_count = 0; - if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || - OLD_allocated_ip[1] != DHCP_allocated_ip[1] || - OLD_allocated_ip[2] != DHCP_allocated_ip[2] || - OLD_allocated_ip[3] != DHCP_allocated_ip[3]) - { - ret = DHCP_IP_CHANGED; - dhcp_ip_update(); - #ifdef _DHCP_DEBUG_ - printf(">IP changed.\r\n"); - #endif - - } - #ifdef _DHCP_DEBUG_ - else printf(">IP is continued.\r\n"); - #endif - reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_LEASED; - } else if (type == DHCP_NAK) { - -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); -#endif - - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_DISCOVER; - } else ret = check_DHCP_timeout(); - break; - default : - break; - } - - return ret; -} - -void DHCP_stop(void) -{ - close(DHCP_SOCKET); - dhcp_state = STATE_DHCP_STOP; -} - -uint8_t check_DHCP_timeout(void) -{ - uint8_t ret = DHCP_RUNNING; - - if (dhcp_retry_count < MAX_DHCP_RETRY) { - if (dhcp_tick_next < dhcp_tick_1s) { - - switch ( dhcp_state ) { - case STATE_DHCP_DISCOVER : -// printf("<> state : STATE_DHCP_DISCOVER\r\n"); - send_DHCP_DISCOVER(); - break; - - case STATE_DHCP_REQUEST : -// printf("<> state : STATE_DHCP_REQUEST\r\n"); - - send_DHCP_REQUEST(); - break; - - case STATE_DHCP_REREQUEST : -// printf("<> state : STATE_DHCP_REREQUEST\r\n"); - - send_DHCP_REQUEST(); - break; - - default : - break; - } - - dhcp_tick_1s = 0; - dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; - dhcp_retry_count++; - } - } else { // timeout occurred - - switch(dhcp_state) { - case STATE_DHCP_DISCOVER: - dhcp_state = STATE_DHCP_INIT; - ret = DHCP_FAILED; - break; - case STATE_DHCP_REQUEST: - case STATE_DHCP_REREQUEST: - send_DHCP_DISCOVER(); - dhcp_state = STATE_DHCP_DISCOVER; - break; - default : - break; - } - reset_DHCP_timeout(); - } - return ret; -} - -int8_t check_DHCP_leasedIP(void) -{ - uint8_t tmp; - int32_t ret; - - //WIZchip RCR value changed for ARP Timeout count control - tmp = getRCR(); - setRCR(0x03); - - // IP conflict detection : ARP request - ARP reply - // Broadcasting ARP Request for check the IP conflict using UDP sendto() function - ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); - - // RCR value restore - setRCR(tmp); - - if(ret == SOCKERR_TIMEOUT) { - // UDP send Timeout occurred : allocated IP address is unique, DHCP Success - -#ifdef _DHCP_DEBUG_ - printf("\r\n> Check leased IP - OK\r\n"); -#endif - - return 1; - } else { - // Received ARP reply or etc : IP address conflict occur, DHCP Failed - send_DHCP_DECLINE(); - - ret = dhcp_tick_1s; - while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message; - - return 0; - } -} - -void DHCP_init(uint8_t s, uint8_t * buf) -{ - uint8_t zeroip[4] = {0,0,0,0}; - getSHAR(DHCP_CHADDR); - if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) - { - // assign temporary mac address, you should be set SHAR before call this function. - DHCP_CHADDR[0] = 0x00; - DHCP_CHADDR[1] = 0x08; - DHCP_CHADDR[2] = 0xdc; - DHCP_CHADDR[3] = 0x00; - DHCP_CHADDR[4] = 0x00; - DHCP_CHADDR[5] = 0x00; - setSHAR(DHCP_CHADDR); - } - - DHCP_SOCKET = s; // SOCK_DHCP - pDHCPMSG = (RIP_MSG*)buf; - DHCP_XID = 0x12345678; - - // WIZchip Netinfo Clear - setSIPR(zeroip); - setSIPR(zeroip); - setGAR(zeroip); - - reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_INIT; -} - - -/* Rset the DHCP timeout count and retry count. */ -void reset_DHCP_timeout(void) -{ - dhcp_tick_1s = 0; - dhcp_tick_next = DHCP_WAIT_TIME; - dhcp_retry_count = 0; -} - -void DHCP_time_handler(void) -{ - dhcp_tick_1s++; -} - -void getIPfromDHCP(uint8_t* ip) -{ - ip[0] = DHCP_allocated_ip[0]; - ip[1] = DHCP_allocated_ip[1]; - ip[2] = DHCP_allocated_ip[2]; - ip[3] = DHCP_allocated_ip[3]; -} - -void getGWfromDHCP(uint8_t* ip) -{ - ip[0] =DHCP_allocated_gw[0]; - ip[1] =DHCP_allocated_gw[1]; - ip[2] =DHCP_allocated_gw[2]; - ip[3] =DHCP_allocated_gw[3]; -} - -void getSNfromDHCP(uint8_t* ip) -{ - ip[0] = DHCP_allocated_sn[0]; - ip[1] = DHCP_allocated_sn[1]; - ip[2] = DHCP_allocated_sn[2]; - ip[3] = DHCP_allocated_sn[3]; -} - -void getDNSfromDHCP(uint8_t* ip) -{ - ip[0] = DHCP_allocated_dns[0]; - ip[1] = DHCP_allocated_dns[1]; - ip[2] = DHCP_allocated_dns[2]; - ip[3] = DHCP_allocated_dns[3]; -} - -uint32_t getDHCPLeasetime(void) -{ - return dhcp_lease_time; -} - - - - diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.h b/drivers/wiznet5k/internet/dhcp/dhcp.h deleted file mode 100644 index ee154d506ac3..000000000000 --- a/drivers/wiznet5k/internet/dhcp/dhcp.h +++ /dev/null @@ -1,150 +0,0 @@ -//***************************************************************************** -// -//! \file dhcp.h -//! \brief DHCP APIs Header file. -//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. -//! \version 1.1.0 -//! \date 2013/11/18 -//! \par Revision history -//! <2013/11/18> 1st Release -//! <2012/12/20> V1.1.0 -//! 1. Move unreferenced DEFINE to dhcp.c -//! <2012/12/26> V1.1.1 -//! \author Eric Jung & MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** -#ifndef _DHCP_H_ -#define _DHCP_H_ - -/* - * @brief - * @details If you want to display debug & processing message, Define _DHCP_DEBUG_ - * @note If defined, it depends on - */ - -//#define _DHCP_DEBUG_ - -/* Retry to processing DHCP */ -#define MAX_DHCP_RETRY 2 ///< Maximum retry count -#define DHCP_WAIT_TIME 10 ///< Wait Time 10s - -/* UDP port numbers for DHCP */ -#define DHCP_SERVER_PORT 67 ///< DHCP server port number -#define DHCP_CLIENT_PORT 68 ///< DHCP client port number - -#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modified it any number - -#define DCHP_HOST_NAME "WIZnet\0" - -/* - * @brief return value of @ref DHCP_run() - */ -enum -{ - DHCP_FAILED = 0, ///< Processing Fail - DHCP_RUNNING, ///< Processing DHCP protocol - DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) - DHCP_IP_CHANGED, ///< Change IP address by new IP address from DHCP (if cbfunc == null, act as default default_ip_update) - DHCP_IP_LEASED, ///< Stand by - DHCP_STOPPED ///< Stop processing DHCP protocol -}; - -/* - * @brief DHCP client initialization (outside of the main loop) - * @param s - socket number - * @param buf - buffer for processing DHCP message - */ -void DHCP_init(uint8_t s, uint8_t * buf); - -/* - * @brief DHCP 1s Tick Timer handler - * @note SHOULD BE register to your system 1s Tick timer handler - */ -void DHCP_time_handler(void); - -/* - * @brief Register call back function - * @param ip_assign - callback func when IP is assigned from DHCP server first - * @param ip_update - callback func when IP is changed - * @prarm ip_conflict - callback func when the assigned IP is conflict with others. - */ -void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); - -/* - * @brief DHCP client in the main loop - * @return The value is as the follow \n - * @ref DHCP_FAILED \n - * @ref DHCP_RUNNING \n - * @ref DHCP_IP_ASSIGN \n - * @ref DHCP_IP_CHANGED \n - * @ref DHCP_IP_LEASED \n - * @ref DHCP_STOPPED \n - * - * @note This function is always called by you main task. - */ -uint8_t DHCP_run(void); - -/* - * @brief Stop DHCP processing - * @note If you want to restart. call DHCP_init() and DHCP_run() - */ -void DHCP_stop(void); - -/* Get Network information assigned from DHCP server */ -/* - * @brief Get IP address - * @param ip - IP address to be returned - */ -void getIPfromDHCP(uint8_t* ip); -/* - * @brief Get Gateway address - * @param ip - Gateway address to be returned - */ -void getGWfromDHCP(uint8_t* ip); -/* - * @brief Get Subnet mask value - * @param ip - Subnet mask to be returned - */ -void getSNfromDHCP(uint8_t* ip); -/* - * @brief Get DNS address - * @param ip - DNS address to be returned - */ -void getDNSfromDHCP(uint8_t* ip); - -/* - * @brief Get the leased time by DHCP sever - * @return unit 1s - */ -uint32_t getDHCPLeasetime(void); - -#endif /* _DHCP_H_ */ diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c deleted file mode 100644 index c0ad570c0097..000000000000 --- a/drivers/wiznet5k/internet/dns/dns.c +++ /dev/null @@ -1,566 +0,0 @@ -//***************************************************************************** -// -//! \file dns.c -//! \brief DNS APIs Implement file. -//! \details Send DNS query & Receive DNS reponse. \n -//! It depends on stdlib.h & string.h in ansi-c library -//! \version 1.1.0 -//! \date 2013/11/18 -//! \par Revision history -//! <2013/10/21> 1st Release -//! <2013/12/20> V1.1.0 -//! 1. Remove secondary DNS server in DNS_run -//! If 1st DNS_run failed, call DNS_run with 2nd DNS again -//! 2. DNS_timerHandler -> DNS_time_handler -//! 3. Remove the unused define -//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c -//! <2013/12/20> V1.1.0 -//! -//! \author Eric Jung & MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#include -#include - -//#include "Ethernet/socket.h" -//#include "Internet/DNS/dns.h" -#include "../../ethernet/socket.h" -#include "dns.h" - -#ifdef _DNS_DEBUG_ - #include -#endif - -#define INITRTT 2000L /* Initial smoothed response time */ -#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */ - -#define TYPE_A 1 /* Host address */ -#define TYPE_NS 2 /* Name server */ -#define TYPE_MD 3 /* Mail destination (obsolete) */ -#define TYPE_MF 4 /* Mail forwarder (obsolete) */ -#define TYPE_CNAME 5 /* Canonical name */ -#define TYPE_SOA 6 /* Start of Authority */ -#define TYPE_MB 7 /* Mailbox name (experimental) */ -#define TYPE_MG 8 /* Mail group member (experimental) */ -#define TYPE_MR 9 /* Mail rename name (experimental) */ -#define TYPE_NULL 10 /* Null (experimental) */ -#define TYPE_WKS 11 /* Well-known sockets */ -#define TYPE_PTR 12 /* Pointer record */ -#define TYPE_HINFO 13 /* Host information */ -#define TYPE_MINFO 14 /* Mailbox information (experimental)*/ -#define TYPE_MX 15 /* Mail exchanger */ -#define TYPE_TXT 16 /* Text strings */ -#define TYPE_ANY 255 /* Matches any type */ - -#define CLASS_IN 1 /* The ARPA Internet */ - -/* Round trip timing parameters */ -#define AGAIN 8 /* Average RTT gain = 1/8 */ -#define LAGAIN 3 /* Log2(AGAIN) */ -#define DGAIN 4 /* Mean deviation gain = 1/4 */ -#define LDGAIN 2 /* log2(DGAIN) */ - -/* Header for all domain messages */ -struct dhdr -{ - uint16_t id; /* Identification */ - uint8_t qr; /* Query/Response */ -#define QUERY 0 -#define RESPONSE 1 - uint8_t opcode; -#define IQUERY 1 - uint8_t aa; /* Authoratative answer */ - uint8_t tc; /* Truncation */ - uint8_t rd; /* Recursion desired */ - uint8_t ra; /* Recursion available */ - uint8_t rcode; /* Response code */ -#define NO_ERROR 0 -#define FORMAT_ERROR 1 -#define SERVER_FAIL 2 -#define NAME_ERROR 3 -#define NOT_IMPL 4 -#define REFUSED 5 - uint16_t qdcount; /* Question count */ - uint16_t ancount; /* Answer count */ - uint16_t nscount; /* Authority (name server) count */ - uint16_t arcount; /* Additional record count */ -}; - - -uint8_t* pDNSMSG; // DNS message buffer -uint8_t DNS_SOCKET; // SOCKET number for DNS -uint16_t DNS_MSGID; // DNS message ID - -extern uint32_t HAL_GetTick(void); -uint32_t hal_sys_tick; - -/* converts uint16_t from network buffer to a host byte order integer. */ -uint16_t get16(uint8_t * s) -{ - uint16_t i; - i = *s++ << 8; - i = i + *s; - return i; -} - -/* copies uint16_t to the network buffer with network byte order. */ -uint8_t * put16(uint8_t * s, uint16_t i) -{ - *s++ = i >> 8; - *s++ = i; - return s; -} - - -/* - * CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM - * - * Description : This function converts a compressed domain name to the human-readable form - * Arguments : msg - is a pointer to the reply message - * compressed - is a pointer to the domain name in reply message. - * buf - is a pointer to the buffer for the human-readable form name. - * len - is the MAX. size of buffer. - * Returns : the length of compressed message - */ -int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len) -{ - uint16_t slen; /* Length of current segment */ - uint8_t * cp; - int clen = 0; /* Total length of compressed name */ - int indirect = 0; /* Set if indirection encountered */ - int nseg = 0; /* Total number of segments in name */ - - cp = compressed; - - for (;;) - { - slen = *cp++; /* Length of this segment */ - - if (!indirect) clen++; - - if ((slen & 0xc0) == 0xc0) - { - if (!indirect) - clen++; - indirect = 1; - /* Follow indirection */ - cp = &msg[((slen & 0x3f)<<8) + *cp]; - slen = *cp++; - } - - if (slen == 0) /* zero length == all done */ - break; - - len -= slen + 1; - - if (len < 0) return -1; - - if (!indirect) clen += slen; - - while (slen-- != 0) *buf++ = (char)*cp++; - *buf++ = '.'; - nseg++; - } - - if (nseg == 0) - { - /* Root name; represent as single dot */ - *buf++ = '.'; - len--; - } - - *buf++ = '\0'; - len--; - - return clen; /* Length of compressed message */ -} - -/* - * PARSE QUESTION SECTION - * - * Description : This function parses the question record of the reply message. - * Arguments : msg - is a pointer to the reply message - * cp - is a pointer to the question record. - * Returns : a pointer the to next record. - */ -uint8_t * dns_question(uint8_t * msg, uint8_t * cp) -{ - int len; - char name[MAXCNAME]; - - len = parse_name(msg, cp, name, MAXCNAME); - - - if (len == -1) return 0; - - cp += len; - cp += 2; /* type */ - cp += 2; /* class */ - - return cp; -} - - -/* - * PARSE ANSER SECTION - * - * Description : This function parses the answer record of the reply message. - * Arguments : msg - is a pointer to the reply message - * cp - is a pointer to the answer record. - * Returns : a pointer the to next record. - */ -uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns) -{ - int len, type; - char name[MAXCNAME]; - - len = parse_name(msg, cp, name, MAXCNAME); - - if (len == -1) return 0; - - cp += len; - type = get16(cp); - cp += 2; /* type */ - cp += 2; /* class */ - cp += 4; /* ttl */ - cp += 2; /* len */ - - - switch (type) - { - case TYPE_A: - /* Just read the address directly into the structure */ - ip_from_dns[0] = *cp++; - ip_from_dns[1] = *cp++; - ip_from_dns[2] = *cp++; - ip_from_dns[3] = *cp++; - break; - case TYPE_CNAME: - case TYPE_MB: - case TYPE_MG: - case TYPE_MR: - case TYPE_NS: - case TYPE_PTR: - /* These types all consist of a single domain name */ - /* convert it to ASCII format */ - len = parse_name(msg, cp, name, MAXCNAME); - if (len == -1) return 0; - - cp += len; - break; - case TYPE_HINFO: - len = *cp++; - cp += len; - - len = *cp++; - cp += len; - break; - case TYPE_MX: - cp += 2; - /* Get domain name of exchanger */ - len = parse_name(msg, cp, name, MAXCNAME); - if (len == -1) return 0; - - cp += len; - break; - case TYPE_SOA: - /* Get domain name of name server */ - len = parse_name(msg, cp, name, MAXCNAME); - if (len == -1) return 0; - - cp += len; - - /* Get domain name of responsible person */ - len = parse_name(msg, cp, name, MAXCNAME); - if (len == -1) return 0; - - cp += len; - - cp += 4; - cp += 4; - cp += 4; - cp += 4; - cp += 4; - break; - case TYPE_TXT: - /* Just stash */ - break; - default: - /* Ignore */ - break; - } - - return cp; -} - -/* - * PARSE THE DNS REPLY - * - * Description : This function parses the reply message from DNS server. - * Arguments : dhdr - is a pointer to the header for DNS message - * buf - is a pointer to the reply message. - * len - is the size of reply message. - * Returns : -1 - Domain name length is too big - * 0 - Fail (Timeout or parse error) - * 1 - Success, - */ -int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns) -{ - uint16_t tmp; - uint16_t i; - uint8_t * msg; - uint8_t * cp; - - msg = pbuf; - memset(pdhdr, 0, sizeof(*pdhdr)); - - pdhdr->id = get16(&msg[0]); - tmp = get16(&msg[2]); - if (tmp & 0x8000) pdhdr->qr = 1; - - pdhdr->opcode = (tmp >> 11) & 0xf; - - if (tmp & 0x0400) pdhdr->aa = 1; - if (tmp & 0x0200) pdhdr->tc = 1; - if (tmp & 0x0100) pdhdr->rd = 1; - if (tmp & 0x0080) pdhdr->ra = 1; - - pdhdr->rcode = tmp & 0xf; - pdhdr->qdcount = get16(&msg[4]); - pdhdr->ancount = get16(&msg[6]); - pdhdr->nscount = get16(&msg[8]); - pdhdr->arcount = get16(&msg[10]); - - - /* Now parse the variable length sections */ - cp = &msg[12]; - - /* Question section */ - for (i = 0; i < pdhdr->qdcount; i++) - { - cp = dns_question(msg, cp); - if(!cp) - { -#ifdef _DNS_DEBUG_ - printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n"); -#endif - return -1; - } - } - - /* Answer section */ - for (i = 0; i < pdhdr->ancount; i++) - { - cp = dns_answer(msg, cp, ip_from_dns); - if(!cp) - { -#ifdef _DNS_DEBUG_ - printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n"); -#endif - return -1; - } - - } - - /* Name server (authority) section */ - for (i = 0; i < pdhdr->nscount; i++) - { - ; - } - - /* Additional section */ - for (i = 0; i < pdhdr->arcount; i++) - { - ; - } - - if(pdhdr->rcode == 0) return 1; // No error - else return 0; -} - - -/* - * MAKE DNS QUERY MESSAGE - * - * Description : This function makes DNS query message. - * Arguments : op - Recursion desired - * name - is a pointer to the domain name. - * buf - is a pointer to the buffer for DNS message. - * len - is the MAX. size of buffer. - * Returns : the pointer to the DNS message. - */ -int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len) -{ - uint8_t *cp; - char *cp1; - char sname[MAXCNAME]; - char *dname; - uint16_t p; - uint16_t dlen; - - cp = buf; - - DNS_MSGID++; - cp = put16(cp, DNS_MSGID); - p = (op << 11) | 0x0100; /* Recursion desired */ - cp = put16(cp, p); - cp = put16(cp, 1); - cp = put16(cp, 0); - cp = put16(cp, 0); - cp = put16(cp, 0); - - strcpy(sname, name); - dname = sname; - dlen = strlen(dname); - for (;;) - { - /* Look for next dot */ - cp1 = strchr(dname, '.'); - - if (cp1 != NULL) len = cp1 - dname; /* More to come */ - else len = dlen; /* Last component */ - - *cp++ = len; /* Write length of component */ - if (len == 0) break; - - /* Copy component up to (but not including) dot */ - memcpy(cp, dname, len); - cp += len; - if (cp1 == NULL) - { - *cp++ = 0; /* Last one; write null and finish */ - break; - } - dname += len+1; - dlen -= len+1; - } - - cp = put16(cp, 0x0001); /* type */ - cp = put16(cp, 0x0001); /* class */ - - return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf))); -} - -/* - * CHECK DNS TIMEOUT - * - * Description : This function check the DNS timeout - * Arguments : None. - * Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur - * Note : timeout : retry count and timer both over. - */ - -int8_t check_DNS_timeout(void) -{ - static uint8_t retry_count; - - uint32_t tick = HAL_GetTick(); - if(tick - hal_sys_tick >= DNS_WAIT_TIME * 1000) - { - hal_sys_tick = tick; - if(retry_count >= MAX_DNS_RETRY) { - retry_count = 0; - return -1; // timeout occurred - } - retry_count++; - return 0; // timer over, but no timeout - } - - return 1; // no timer over, no timeout occur -} - - - -/* DNS CLIENT INIT */ -void DNS_init(uint8_t s, uint8_t * buf) -{ - DNS_SOCKET = s; // SOCK_DNS - pDNSMSG = buf; // User's shared buffer - DNS_MSGID = DNS_MSG_ID; -} - -/* DNS CLIENT RUN */ -int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns) -{ - int8_t ret; - struct dhdr dhp; - uint8_t ip[4]; - uint16_t len, port; - int8_t ret_check_timeout; - - hal_sys_tick = HAL_GetTick(); - - // Socket open - WIZCHIP_EXPORT(socket)(DNS_SOCKET, Sn_MR_UDP, 0, 0); - -#ifdef _DNS_DEBUG_ - printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); -#endif - - len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE); - WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); - - while (1) - { - if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0) - { - if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE; - len = WIZCHIP_EXPORT(recvfrom)(DNS_SOCKET, pDNSMSG, len, ip, &port); - #ifdef _DNS_DEBUG_ - printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len); - #endif - ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns); - break; - } - // Check Timeout - ret_check_timeout = check_DNS_timeout(); - if (ret_check_timeout < 0) { - -#ifdef _DNS_DEBUG_ - printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); -#endif - return 0; // timeout occurred - } - else if (ret_check_timeout == 0) { - -#ifdef _DNS_DEBUG_ - printf("> DNS Timeout\r\n"); -#endif - WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); - } - } - WIZCHIP_EXPORT(close)(DNS_SOCKET); - // Return value - // 0 > : failed / 1 - success - return ret; -} diff --git a/drivers/wiznet5k/internet/dns/dns.h b/drivers/wiznet5k/internet/dns/dns.h deleted file mode 100644 index de0039515e28..000000000000 --- a/drivers/wiznet5k/internet/dns/dns.h +++ /dev/null @@ -1,96 +0,0 @@ -//***************************************************************************** -// -//! \file dns.h -//! \brief DNS APIs Header file. -//! \details Send DNS query & Receive DNS reponse. -//! \version 1.1.0 -//! \date 2013/11/18 -//! \par Revision history -//! <2013/10/21> 1st Release -//! <2013/12/20> V1.1.0 -//! 1. Remove secondary DNS server in DNS_run -//! If 1st DNS_run failed, call DNS_run with 2nd DNS again -//! 2. DNS_timerHandler -> DNS_time_handler -//! 3. Move the no reference define to dns.c -//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c -//! <2013/12/20> V1.1.0 -//! -//! \author Eric Jung & MidnightCow -//! \copyright -//! -//! Copyright (c) 2013, WIZnet Co., LTD. -//! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. -//! * Redistributions in binary form must reproduce the above copyright -//! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! -//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -//! THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#ifndef _DNS_H_ -#define _DNS_H_ - -#include -/* - * @brief Define it for Debug & Monitor DNS processing. - * @note If defined, it depends on - */ - -//#define _DNS_DEBUG_ - -#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */ -/* - * @brief Maximum length of your queried Domain name - * @todo SHOULD BE defined it equal as or greater than your Domain name length + null character(1) - * @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack. - */ -#define MAX_DOMAIN_NAME 32 // for example "www.google.com" - -#define MAX_DNS_RETRY 2 ///< Requery Count -#define DNS_WAIT_TIME 4 ///< Wait response time. unit 1s. - -#define IPPORT_DOMAIN 53 ///< DNS server port number - -#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modified it any number -/* - * @brief DNS process initialize - * @param s : Socket number for DNS - * @param buf : Buffer for DNS message - */ -void DNS_init(uint8_t s, uint8_t * buf); - -/* - * @brief DNS process - * @details Send DNS query and receive DNS response - * @param dns_ip : DNS server ip address - * @param name : Domain name to be queried - * @param ip_from_dns : IP address from DNS server - * @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n - * 0 : failed (Timeout or Parse error)\n - * 1 : success - * @note This function blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME - */ -int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns); - -#endif /* _DNS_H_ */ From 8308f9c977adf322b264e5fbec6dd84315231eb4 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 20 Aug 2022 11:25:34 +0200 Subject: [PATCH 1635/4290] extmod/network_wiznet5k: Use the configured DNS address if available. Instead of the default 8.8.8.8. The change was suggested by @omogenot. --- extmod/network_wiznet5k.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 89c933c2d454..95c852d7f729 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -397,6 +397,9 @@ STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); DNS_init(2, buf); + if (wiznet5k_obj.netinfo.dns[0]) { + memcpy(dns_ip, wiznet5k_obj.netinfo.dns, MOD_NETWORK_IPADDR_BUF_SIZE); + } mp_int_t ret = DNS_run(dns_ip, (uint8_t *)name, out_ip); m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); if (ret == 1) { From 47c45d0e7fda10f4a62b7017d48ae452203b22f0 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 22 Aug 2022 08:09:02 +0200 Subject: [PATCH 1636/4290] rp2/machine_wdt: Check for the maximum timeout value of watchdog. The value will be checked for timeout <= 8388. Notes were added to the documentation. --- docs/library/machine.WDT.rst | 5 +++-- docs/rp2/quickref.rst | 1 + ports/rp2/machine_wdt.c | 9 ++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst index 8c81e10ea581..95893cec36be 100644 --- a/docs/library/machine.WDT.rst +++ b/docs/library/machine.WDT.rst @@ -15,7 +15,7 @@ Example usage:: wdt = WDT(timeout=2000) # enable it with a timeout of 2s wdt.feed() -Availability of this class: pyboard, WiPy, esp8266, esp32. +Availability of this class: pyboard, WiPy, esp8266, esp32, rp2040, mimxrt. Constructors ------------ @@ -26,7 +26,8 @@ Constructors Once it is running the timeout cannot be changed and the WDT cannot be stopped either. Notes: On the esp32 the minimum timeout is 1 second. On the esp8266 a timeout - cannot be specified, it is determined by the underlying system. + cannot be specified, it is determined by the underlying system. On rp2040 devices, + the maximum timeout is 8388 ms. Methods ------- diff --git a/docs/rp2/quickref.rst b/docs/rp2/quickref.rst index 4824f390ebfb..430c130c6e86 100644 --- a/docs/rp2/quickref.rst +++ b/docs/rp2/quickref.rst @@ -296,6 +296,7 @@ See :ref:`machine.WDT `. :: wdt = WDT(timeout=5000) wdt.feed() +The maximum value for timeout is 8388 ms. OneWire driver -------------- diff --git a/ports/rp2/machine_wdt.c b/ports/rp2/machine_wdt.c index 38e0597018d6..d6914a4f2615 100644 --- a/ports/rp2/machine_wdt.c +++ b/ports/rp2/machine_wdt.c @@ -29,6 +29,9 @@ #include "hardware/watchdog.h" +// The maximum timeout in milliseconds is: 0xffffff / 2 / 1000 +#define WDT_TIMEOUT_MAX 8388 + typedef struct _machine_wdt_obj_t { mp_obj_base_t base; } machine_wdt_obj_t; @@ -53,7 +56,11 @@ STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type, size_t n_args, s } // Start the watchdog (timeout is in milliseconds). - watchdog_enable(args[ARG_timeout].u_int, false); + uint32_t timeout = args[ARG_timeout].u_int; + if (timeout > WDT_TIMEOUT_MAX) { + mp_raise_ValueError(MP_ERROR_TEXT("timeout exceeds " MP_STRINGIFY(WDT_TIMEOUT_MAX))); + } + watchdog_enable(timeout, false); return MP_OBJ_FROM_PTR(&machine_wdt); } From 98d1c50159fe9427d72ec358ba0219eaebb1d991 Mon Sep 17 00:00:00 2001 From: glenn20 Date: Sun, 31 Jul 2022 16:36:10 +1000 Subject: [PATCH 1637/4290] esp32/network_wlan: Use esp_wifi_set/get_channel to config wifi channel. Set the channel with esp_wifi_set_channel(), which adds support for setting the channel of the STA interface Get the channel with esp_wifi_get_channel() which returns the actual wifi channel of the radio, rather than the configured channel. --- ports/esp32/network_wlan.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index 9b2200e4ff9c..501dc40f275a 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -448,8 +448,22 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ break; } case MP_QSTR_channel: { - req_if = WIFI_IF_AP; - cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value); + uint8_t primary; + wifi_second_chan_t secondary; + // Get the current value of secondary + esp_exceptions(esp_wifi_get_channel(&primary, &secondary)); + primary = mp_obj_get_int(kwargs->table[i].value); + esp_err_t err = esp_wifi_set_channel(primary, secondary); + if (err == ESP_ERR_INVALID_ARG) { + // May need to swap secondary channel above to below or below to above + secondary = ( + (secondary == WIFI_SECOND_CHAN_ABOVE) + ? WIFI_SECOND_CHAN_BELOW + : (secondary == WIFI_SECOND_CHAN_BELOW) + ? WIFI_SECOND_CHAN_ABOVE + : WIFI_SECOND_CHAN_NONE); + esp_exceptions(esp_wifi_set_channel(primary, secondary)); + } break; } case MP_QSTR_hostname: @@ -535,10 +549,13 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ req_if = WIFI_IF_AP; val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode); break; - case MP_QSTR_channel: - req_if = WIFI_IF_AP; - val = MP_OBJ_NEW_SMALL_INT(cfg.ap.channel); + case MP_QSTR_channel: { + uint8_t channel; + wifi_second_chan_t second; + esp_exceptions(esp_wifi_get_channel(&channel, &second)); + val = MP_OBJ_NEW_SMALL_INT(channel); break; + } case MP_QSTR_hostname: case MP_QSTR_dhcp_hostname: { const char *s; From 76f2e3e62bd2bc177a62649bae34b67d9bd2c8b1 Mon Sep 17 00:00:00 2001 From: glenn20 Date: Sun, 31 Jul 2022 18:17:40 +1000 Subject: [PATCH 1638/4290] esp32/network_wlan: Add support to set/get the wifi protocol. Add 'protocol' option to WLAN.config() to support setting/getting the wifi protocol modes: MODE_11G|MODE_11G|MODE_11N. --- ports/esp32/network_wlan.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index 501dc40f275a..4f74262afc38 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -490,6 +490,10 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ esp_exceptions(esp_wifi_set_max_tx_power(power)); break; } + case MP_QSTR_protocol: { + esp_exceptions(esp_wifi_set_protocol(self->if_id, mp_obj_get_int(kwargs->table[i].value))); + break; + } default: goto unknown; } @@ -578,6 +582,12 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_ val = mp_obj_new_float(power * 0.25); break; } + case MP_QSTR_protocol: { + uint8_t protocol_bitmap; + esp_exceptions(esp_wifi_get_protocol(self->if_id, &protocol_bitmap)); + val = MP_OBJ_NEW_SMALL_INT(protocol_bitmap); + break; + } default: goto unknown; } From 0507f239e812fa7ae57c1e172c53eae8fc37cd18 Mon Sep 17 00:00:00 2001 From: glenn20 Date: Sun, 31 Jul 2022 18:19:18 +1000 Subject: [PATCH 1639/4290] esp32/modnetwork: Add network.MODE_LR constant. Adds the MODE_LR constant to the network module to support Espressif's long-range communication protocol. --- ports/esp32/modnetwork.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index 45231c42307c..7429274c1571 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -244,6 +244,7 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MODE_11B), MP_ROM_INT(WIFI_PROTOCOL_11B) }, { MP_ROM_QSTR(MP_QSTR_MODE_11G), MP_ROM_INT(WIFI_PROTOCOL_11G) }, { MP_ROM_QSTR(MP_QSTR_MODE_11N), MP_ROM_INT(WIFI_PROTOCOL_11N) }, + { MP_ROM_QSTR(MP_QSTR_MODE_LR), MP_ROM_INT(WIFI_PROTOCOL_LR) }, { MP_ROM_QSTR(MP_QSTR_AUTH_OPEN), MP_ROM_INT(WIFI_AUTH_OPEN) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WEP), MP_ROM_INT(WIFI_AUTH_WEP) }, From e6e60f4330c176e1a9443a994ba29ea155d7aca7 Mon Sep 17 00:00:00 2001 From: glenn20 Date: Fri, 12 Aug 2022 16:53:48 +1000 Subject: [PATCH 1640/4290] esp8266/modnetwork: Add support for WLAN.config(protocol=XX) option. Following esp32. This is preferred to using the phy_mode() function. --- ports/esp8266/modnetwork.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index dbc12f74d4ae..5240d3b32064 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -406,6 +406,10 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs } break; } + case MP_QSTR_protocol: { + wifi_set_phy_mode(mp_obj_get_int(kwargs->table[i].value)); + break; + } default: goto unknown; } @@ -473,6 +477,10 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs } break; } + case MP_QSTR_protocol: { + val = mp_obj_new_int(wifi_get_phy_mode()); + break; + } default: goto unknown; } From 13dceaa4ea4336eddb763985c2274cfa497c8e82 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 12 Jul 2022 18:25:41 +0200 Subject: [PATCH 1641/4290] esp32/machine_uart: Change sendbreak time to be at least 15 bit times. It used to be 10 bit times, which is too short. The break state must be longer than a regular character time, at least 13 bit times. This is now implemented by reducing the baudrate while sending the "0". The break time will now vary with data length and parity setting, but will at least be 15 bit times. Tested with a GENERIC_SPIRAM, GENERIC_C3 and UM_TINYS2 board. --- ports/esp32/machine_uart.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 49ce78b1b24c..28110e39f378 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -399,28 +399,19 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); // Save settings - uart_word_length_t word_length; - uart_parity_t parity; - uart_get_word_length(self->uart_num, &word_length); - uart_get_parity(self->uart_num, &parity); + uint32_t baudrate; + uart_get_baudrate(self->uart_num, &baudrate); - // Synthesise the break condition by either a longer word or using even parity + // Synthesise the break condition by reducing the baud rate, + // and cater for the worst case of 5 data bits, no parity. uart_wait_tx_done(self->uart_num, pdMS_TO_TICKS(1000)); - if (word_length != UART_DATA_8_BITS) { - uart_set_word_length(self->uart_num, UART_DATA_8_BITS); - } else if (parity == UART_PARITY_DISABLE) { - uart_set_parity(self->uart_num, UART_PARITY_EVEN); - } else { - // Cannot synthesise break - mp_raise_OSError(MP_EPERM); - } + uart_set_baudrate(self->uart_num, baudrate * 6 / 15); char buf[1] = {0}; uart_write_bytes(self->uart_num, buf, 1); uart_wait_tx_done(self->uart_num, pdMS_TO_TICKS(1000)); - // Restore original settings - uart_set_word_length(self->uart_num, word_length); - uart_set_parity(self->uart_num, parity); + // Restore original setting + uart_set_baudrate(self->uart_num, baudrate); return mp_const_none; } From 8139cbcf6bfad3f9b14865a5315bc83b5c5ecc7a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 17 Aug 2022 08:44:03 +0200 Subject: [PATCH 1642/4290] esp32/machine_timer: Support all init arguments in Timer constructor. Following the usual style of instantiation and init(). --- ports/esp32/machine_timer.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 8541bcbfdb48..66969b3a954f 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -68,6 +68,7 @@ typedef struct _machine_timer_obj_t { const mp_obj_type_t machine_timer_type; STATIC void machine_timer_disable(machine_timer_obj_t *self); +STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); void machine_timer_deinit_all(void) { // Disable, deallocate and remove all timers from list @@ -94,24 +95,35 @@ STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_pr } STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); mp_uint_t group = (mp_obj_get_int(args[0]) >> 1) & 1; mp_uint_t index = mp_obj_get_int(args[0]) & 1; - // Check whether the timer is already initialized, if so return it + machine_timer_obj_t *self = NULL; + + // Check whether the timer is already initialized, if so use it for (machine_timer_obj_t *t = MP_STATE_PORT(machine_timer_obj_head); t; t = t->next) { if (t->group == group && t->index == index) { - return t; + self = t; + break; } } + // The timer does not exist, create it. + if (self == NULL) { + self = mp_obj_malloc(machine_timer_obj_t, &machine_timer_type); + self->group = group; + self->index = index; + + // Add the timer to the linked-list of timers + self->next = MP_STATE_PORT(machine_timer_obj_head); + MP_STATE_PORT(machine_timer_obj_head) = self; + } - machine_timer_obj_t *self = mp_obj_malloc(machine_timer_obj_t, &machine_timer_type); - self->group = group; - self->index = index; - - // Add the timer to the linked-list of timers - self->next = MP_STATE_PORT(machine_timer_obj_head); - MP_STATE_PORT(machine_timer_obj_head) = self; + if (n_args > 1 || n_kw > 0) { + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_timer_init_helper(self, n_args - 1, args + 1, &kw_args); + } return self; } From 1fbf0efaebd597207f32a910d635a94ec9f6ef69 Mon Sep 17 00:00:00 2001 From: Damiano Mazzella Date: Tue, 23 Aug 2022 16:50:24 +0200 Subject: [PATCH 1643/4290] stm32/sdram: Enable MPU for unaligned access on H7 MCUs. So that SDRAM can be used as the heap on ARDUINO_PORTENTA_H7, for example. Fixes issue #9087. --- ports/stm32/sdram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/sdram.c b/ports/stm32/sdram.c index a94b802ea49f..fb0e5a8688d3 100644 --- a/ports/stm32/sdram.c +++ b/ports/stm32/sdram.c @@ -244,7 +244,7 @@ static void sdram_init_seq(SDRAM_HandleTypeDef #define REFRESH_COUNT (MICROPY_HW_SDRAM_REFRESH_RATE * 90000 / 8192 - 20) HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT); - #if defined(STM32F7) + #if defined(STM32F7) || defined(STM32H7) /* Enable MPU for the SDRAM Memory Region to allow non-aligned accesses (hard-fault otherwise) Initially disable all access for the entire SDRAM memory space, From 923375380b29aca68b50b3ec685c6d83465fd63d Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 30 Mar 2022 10:50:18 +1100 Subject: [PATCH 1644/4290] stm32/boards: Increase mboot region to 32k for WB55 boards. If mboot is built with support for packing (signing/encryption) it needs up to 32KiB. So for simplicity increase the mboot region to 32KiB unconditionally for WB55 boards (custom WB55 board configurations can still provide their own linker scripts to override this). --- ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk | 2 +- ports/stm32/boards/USBDONGLE_WB55/mpconfigboard.mk | 2 +- ports/stm32/boards/stm32wb55xg.ld | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk index 349ce46d7958..2e6ce1fe8f77 100644 --- a/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk @@ -6,7 +6,7 @@ STARTUP_FILE = $(STM32LIB_CMSIS_BASE)/Source/Templates/gcc/startup_stm32wb55xx_c ifeq ($(USE_MBOOT),1) # When using Mboot all the text goes together after the bootloader LD_FILES = boards/stm32wb55xg.ld boards/common_bl.ld -TEXT0_ADDR = 0x08004000 +TEXT0_ADDR = 0x08008000 else # When not using Mboot the text goes at the start of flash LD_FILES = boards/stm32wb55xg.ld boards/common_basic.ld diff --git a/ports/stm32/boards/USBDONGLE_WB55/mpconfigboard.mk b/ports/stm32/boards/USBDONGLE_WB55/mpconfigboard.mk index 349ce46d7958..2e6ce1fe8f77 100644 --- a/ports/stm32/boards/USBDONGLE_WB55/mpconfigboard.mk +++ b/ports/stm32/boards/USBDONGLE_WB55/mpconfigboard.mk @@ -6,7 +6,7 @@ STARTUP_FILE = $(STM32LIB_CMSIS_BASE)/Source/Templates/gcc/startup_stm32wb55xx_c ifeq ($(USE_MBOOT),1) # When using Mboot all the text goes together after the bootloader LD_FILES = boards/stm32wb55xg.ld boards/common_bl.ld -TEXT0_ADDR = 0x08004000 +TEXT0_ADDR = 0x08008000 else # When not using Mboot the text goes at the start of flash LD_FILES = boards/stm32wb55xg.ld boards/common_basic.ld diff --git a/ports/stm32/boards/stm32wb55xg.ld b/ports/stm32/boards/stm32wb55xg.ld index 841c32b8a0fb..9b1e5bca147d 100644 --- a/ports/stm32/boards/stm32wb55xg.ld +++ b/ports/stm32/boards/stm32wb55xg.ld @@ -6,7 +6,7 @@ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* sectors 0-127 */ - FLASH_APP (rx) : ORIGIN = 0x08004000, LENGTH = 496K /* sectors 4-127 */ + FLASH_APP (rx) : ORIGIN = 0x08008000, LENGTH = 480K /* sectors 8-127 */ FLASH_FS (r) : ORIGIN = 0x08080000, LENGTH = 256K /* sectors 128-191 */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K /* SRAM1 */ RAM2A (xrw) : ORIGIN = 0x20030000, LENGTH = 10K /* SRAM2A */ From 492ba5eaf2c6e1e9fe8e31fd2e8f47fac6188673 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 15 Aug 2022 16:20:40 +1000 Subject: [PATCH 1645/4290] stm32: Move board variant config to mpconfigboard.mk. Rather than having the autobuild know about the particular variants, have the mpconfigboard.mk describe them and make autobuild discover them automatically. Adds a "query-variants" target to stm32/Makefile to allow the set of possible variants to be queried. Removes pybv3 from the autobuild as this isn't use by the downloads page. Signed-off-by: Jim Mussared --- ports/stm32/Makefile | 3 ++ .../stm32/boards/PYBLITEV10/mpconfigboard.mk | 21 ++++++++++++ ports/stm32/boards/PYBV10/mpconfigboard.mk | 21 ++++++++++++ ports/stm32/boards/PYBV11/mpconfigboard.mk | 21 ++++++++++++ tools/autobuild/build-stm32-extra.sh | 34 +++++++------------ 5 files changed, 79 insertions(+), 21 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 7c912f4f0b23..f981f8f3eb05 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -37,6 +37,9 @@ include $(TOP)/extmod/extmod.mk GIT_SUBMODULES += lib/libhydrogen lib/lwip lib/mbedtls lib/stm32lib +query-variants: + $(ECHO) "VARIANTS:" $(BOARD_VARIANTS) + LD_DIR=boards USBDEV_DIR=usbdev #USBHOST_DIR=usbhost diff --git a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk index df9506522574..89977b74ead4 100644 --- a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk @@ -4,3 +4,24 @@ AF_FILE = boards/stm32f411_af.csv LD_FILES = boards/stm32f411.ld boards/common_ifs.ld TEXT0_ADDR = 0x08000000 TEXT1_ADDR = 0x08020000 + +# Provide different variants for the downloads page. +BOARD_VARIANTS += "dp thread dp-thread network" + +ifeq ($(BOARD_VARIANT),"dp") +MICROPY_FLOAT_IMPL=double +endif + +ifeq ($(BOARD_VARIANT),"thread") +CFLAGS += -DMICROPY_PY_THREAD=1 +endif + +ifeq ($(BOARD_VARIANT),"dp-thread") +MICROPY_FLOAT_IMPL=double +CFLAGS += -DMICROPY_PY_THREAD=1 +endif + +ifeq ($(BOARD_VARIANT),"network") +MICROPY_PY_NETWORK_WIZNET5K=5200 +MICROPY_PY_CC3K=1 +endif diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.mk b/ports/stm32/boards/PYBV10/mpconfigboard.mk index cb78a7846d93..071ae6eb7c6b 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV10/mpconfigboard.mk @@ -14,3 +14,24 @@ endif # MicroPython settings MICROPY_VFS_LFS2 = 1 + +# Provide different variants for the downloads page. +BOARD_VARIANTS += "dp thread dp-thread network" + +ifeq ($(BOARD_VARIANT),"dp") +MICROPY_FLOAT_IMPL=double +endif + +ifeq ($(BOARD_VARIANT),"thread") +CFLAGS += -DMICROPY_PY_THREAD=1 +endif + +ifeq ($(BOARD_VARIANT),"dp-thread") +MICROPY_FLOAT_IMPL=double +CFLAGS += -DMICROPY_PY_THREAD=1 +endif + +ifeq ($(BOARD_VARIANT),"network") +MICROPY_PY_NETWORK_WIZNET5K=5200 +MICROPY_PY_CC3K=1 +endif diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.mk b/ports/stm32/boards/PYBV11/mpconfigboard.mk index cb78a7846d93..071ae6eb7c6b 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV11/mpconfigboard.mk @@ -14,3 +14,24 @@ endif # MicroPython settings MICROPY_VFS_LFS2 = 1 + +# Provide different variants for the downloads page. +BOARD_VARIANTS += "dp thread dp-thread network" + +ifeq ($(BOARD_VARIANT),"dp") +MICROPY_FLOAT_IMPL=double +endif + +ifeq ($(BOARD_VARIANT),"thread") +CFLAGS += -DMICROPY_PY_THREAD=1 +endif + +ifeq ($(BOARD_VARIANT),"dp-thread") +MICROPY_FLOAT_IMPL=double +CFLAGS += -DMICROPY_PY_THREAD=1 +endif + +ifeq ($(BOARD_VARIANT),"network") +MICROPY_PY_NETWORK_WIZNET5K=5200 +MICROPY_PY_CC3K=1 +endif diff --git a/tools/autobuild/build-stm32-extra.sh b/tools/autobuild/build-stm32-extra.sh index 80c6f42f5e6c..feb269e35604 100755 --- a/tools/autobuild/build-stm32-extra.sh +++ b/tools/autobuild/build-stm32-extra.sh @@ -7,12 +7,15 @@ function do_build() { board=$2 shift shift - echo "building $descr $board" - build_dir=/tmp/stm-build-$board - $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BUILD=$build_dir || exit 1 - mv $build_dir/firmware.dfu $dest_dir/$descr$fw_tag.dfu - mv $build_dir/firmware.hex $dest_dir/$descr$fw_tag.hex - rm -rf $build_dir + for variant in `$MICROPY_AUTOBUILD_MAKE BOARD=$board query-variants | grep VARIANTS: | cut -d' ' -f2-`; do + target=$descr-$variant + echo "building $target $board" + build_dir=/tmp/stm-build-$board + $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BOARD_VARIANT=$variant BUILD=$build_dir || exit 1 + mv $build_dir/firmware.dfu $dest_dir/$target$fw_tag.dfu + mv $build_dir/firmware.hex $dest_dir/$target$fw_tag.hex + rm -rf $build_dir + done } # check/get parameters @@ -30,18 +33,7 @@ if [ ! -r modpyb.c ]; then exit 1 fi -# build the versions -do_build pybv3 PYBV3 -do_build pybv3-network PYBV3 MICROPY_PY_NETWORK_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build pybv10-dp PYBV10 MICROPY_FLOAT_IMPL=double -do_build pybv10-thread PYBV10 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' -do_build pybv10-dp-thread PYBV10 MICROPY_FLOAT_IMPL=double CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' -do_build pybv10-network PYBV10 MICROPY_PY_NETWORK_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build pybv11-dp PYBV11 MICROPY_FLOAT_IMPL=double -do_build pybv11-thread PYBV11 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' -do_build pybv11-dp-thread PYBV11 MICROPY_FLOAT_IMPL=double CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' -do_build pybv11-network PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 MICROPY_PY_CC3K=1 -do_build pyblitev10-dp PYBLITEV10 MICROPY_FLOAT_IMPL=double -do_build pyblitev10-thread PYBLITEV10 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' -do_build pyblitev10-dp-thread PYBLITEV10 MICROPY_FLOAT_IMPL=double CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' -do_build pyblitev10-network PYBLITEV10 MICROPY_PY_NETWORK_WIZNET5K=5200 MICROPY_PY_CC3K=1 +# build the variants for each board +do_build pybv10 PYBV10 +do_build pybv11 PYBV11 +do_build pyblitev10 PYBLITEV10 From 986ad6bf1d35cbc6f8073e847aa6b87156eefc4b Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 25 Aug 2022 12:27:49 +1000 Subject: [PATCH 1646/4290] stm32/boardctrl: Use HAL_Delay instead of mp_hal_delay_ms. Not safe to use mp_hal_delay_ms before boot if threading is enabled, because threading will not have been initialised, and MICROPY_EVENT_POLL_HOOK assumes threading is initialised. HAL_Delay doesn't call MICROPY_EVENT_POLL_HOOK, but is still power-efficient like mp_hal_delay_ms (unlike mp_hal_delay_us). Fixes #7816. Signed-off-by: Jim Mussared --- ports/stm32/boardctrl.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/ports/stm32/boardctrl.c b/ports/stm32/boardctrl.c index 406a98381419..85a42a240ff0 100644 --- a/ports/stm32/boardctrl.c +++ b/ports/stm32/boardctrl.c @@ -89,6 +89,9 @@ void boardctrl_maybe_enter_mboot(size_t n_args, const void *args_in) { #if !MICROPY_HW_USES_BOOTLOADER STATIC uint update_reset_mode(uint reset_mode) { + // Note: Must use HAL_Delay here as MicroPython is not yet initialised + // and mp_hal_delay_ms will attempt to invoke the scheduler. + #if MICROPY_HW_HAS_SWITCH if (switch_get()) { @@ -100,7 +103,7 @@ STATIC uint update_reset_mode(uint reset_mode) { led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); for (uint j = 0; j < 30; ++j) { - mp_hal_delay_ms(20); + HAL_Delay(20); if (!switch_get()) { goto select_mode; } @@ -115,13 +118,13 @@ STATIC uint update_reset_mode(uint reset_mode) { led_state(2, 0); led_state(3, 0); led_state(4, 0); - mp_hal_delay_ms(50); + HAL_Delay(50); led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); - mp_hal_delay_ms(50); + HAL_Delay(50); } - mp_hal_delay_ms(400); + HAL_Delay(400); #elif defined(MICROPY_HW_LED1) @@ -134,11 +137,11 @@ STATIC uint update_reset_mode(uint reset_mode) { break; } led_state(1, 1); - mp_hal_delay_ms(100); + HAL_Delay(100); led_state(1, 0); - mp_hal_delay_ms(200); + HAL_Delay(200); } - mp_hal_delay_ms(400); + HAL_Delay(400); if (!switch_get()) { break; } @@ -150,11 +153,11 @@ STATIC uint update_reset_mode(uint reset_mode) { for (uint i = 0; i < 2; i++) { for (uint j = 0; j < reset_mode; j++) { led_state(1, 1); - mp_hal_delay_ms(100); + HAL_Delay(100); led_state(1, 0); - mp_hal_delay_ms(200); + HAL_Delay(200); } - mp_hal_delay_ms(400); + HAL_Delay(400); } #else #error Need a reset mode update method From 1855df6361ad4ade62aa46ad08f3202a6a5b1bd1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 24 Aug 2022 10:44:35 +1000 Subject: [PATCH 1647/4290] stm32: Remove support for CC3000 WiFi driver. It has been about 8 years since support for this chip was added. Reasons to remove it are: - It is no longer easy to obtain this part. - There are now many other options for WiFi. - It's not a good use of developer time to maintain it. Signed-off-by: Damien George --- ports/stm32/Makefile | 23 - ports/stm32/boards/PYBLITEV10/board.md | 2 +- .../stm32/boards/PYBLITEV10/mpconfigboard.mk | 1 - ports/stm32/boards/PYBV10/board.md | 2 +- ports/stm32/boards/PYBV10/mpconfigboard.mk | 1 - ports/stm32/boards/PYBV11/board.md | 2 +- ports/stm32/boards/PYBV11/mpconfigboard.mk | 1 - ports/stm32/modnwcc3k.c | 608 ------------------ ports/stm32/mpconfigport.h | 8 - ports/stm32/mpconfigport.mk | 3 - tools/ci.sh | 2 - 11 files changed, 3 insertions(+), 650 deletions(-) delete mode 100644 ports/stm32/modnwcc3k.c diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index f981f8f3eb05..ee00d7717364 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -482,29 +482,6 @@ SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ ) endif -# for CC3000 module -ifeq ($(MICROPY_PY_CC3K),1) -CC3000_DIR=drivers/cc3000 -INC += -I$(TOP)/$(CC3000_DIR)/inc -CFLAGS_MOD += -DMICROPY_PY_CC3K=1 -SRC_MOD += modnwcc3k.c -SRC_MOD += $(addprefix $(CC3000_DIR)/src/,\ - cc3000_common.c \ - evnt_handler.c \ - hci.c \ - netapp.c \ - nvmem.c \ - security.c \ - socket.c \ - wlan.c \ - ccspi.c \ - inet_ntop.c \ - inet_pton.c \ - patch.c \ - patch_prog.c \ - ) -endif - ifeq ($(MICROPY_SSL_MBEDTLS),1) CFLAGS_MOD += -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' SRC_MOD += mbedtls/mbedtls_port.c diff --git a/ports/stm32/boards/PYBLITEV10/board.md b/ports/stm32/boards/PYBLITEV10/board.md index 1511ffcf514f..b490d5404691 100644 --- a/ports/stm32/boards/PYBLITEV10/board.md +++ b/ports/stm32/boards/PYBLITEV10/board.md @@ -1 +1 @@ -The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for CC3000 and WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. +The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. diff --git a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk index 89977b74ead4..8aeaf0e40cfb 100644 --- a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk @@ -23,5 +23,4 @@ endif ifeq ($(BOARD_VARIANT),"network") MICROPY_PY_NETWORK_WIZNET5K=5200 -MICROPY_PY_CC3K=1 endif diff --git a/ports/stm32/boards/PYBV10/board.md b/ports/stm32/boards/PYBV10/board.md index 1511ffcf514f..b490d5404691 100644 --- a/ports/stm32/boards/PYBV10/board.md +++ b/ports/stm32/boards/PYBV10/board.md @@ -1 +1 @@ -The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for CC3000 and WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. +The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.mk b/ports/stm32/boards/PYBV10/mpconfigboard.mk index 071ae6eb7c6b..97af22b5e19b 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV10/mpconfigboard.mk @@ -33,5 +33,4 @@ endif ifeq ($(BOARD_VARIANT),"network") MICROPY_PY_NETWORK_WIZNET5K=5200 -MICROPY_PY_CC3K=1 endif diff --git a/ports/stm32/boards/PYBV11/board.md b/ports/stm32/boards/PYBV11/board.md index 1511ffcf514f..b490d5404691 100644 --- a/ports/stm32/boards/PYBV11/board.md +++ b/ports/stm32/boards/PYBV11/board.md @@ -1 +1 @@ -The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for CC3000 and WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. +The "standard" build is listed first and is the default firmware that the pyboards are shipped with. Use this firmware if you are uncertain. The "double FP" builds use double-precision floating point instead of the standard single precision. The "threading" builds contain the \_thread module and allow multithreading. The "network" builds have network drivers for WIZ820io included. All these different firmware are completely interchangeable and you can freely change from one to the other without losing the filesystem on your pyboard. diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.mk b/ports/stm32/boards/PYBV11/mpconfigboard.mk index 071ae6eb7c6b..97af22b5e19b 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV11/mpconfigboard.mk @@ -33,5 +33,4 @@ endif ifeq ($(BOARD_VARIANT),"network") MICROPY_PY_NETWORK_WIZNET5K=5200 -MICROPY_PY_CC3K=1 endif diff --git a/ports/stm32/modnwcc3k.c b/ports/stm32/modnwcc3k.c deleted file mode 100644 index 952e535c2dbc..000000000000 --- a/ports/stm32/modnwcc3k.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -// CC3000 defines its own ENOBUFS (different to standard one!) -#undef ENOBUFS - -#include "py/objtuple.h" -#include "py/objlist.h" -#include "py/stream.h" -#include "py/runtime.h" -#include "py/mperrno.h" -#include "py/mphal.h" -#include "shared/netutils/netutils.h" -#include "extmod/modnetwork.h" -#include "pin.h" -#include "spi.h" - -#include "hci.h" -#include "socket.h" -#include "inet_ntop.h" -#include "inet_pton.h" -#include "ccspi.h" -#include "wlan.h" -#include "nvmem.h" -#include "netapp.h" -#include "patch_prog.h" - -#define MAX_ADDRSTRLEN (128) -#define MAX_RX_PACKET (CC3000_RX_BUFFER_SIZE - CC3000_MINIMAL_RX_SIZE - 1) -#define MAX_TX_PACKET (CC3000_TX_BUFFER_SIZE - CC3000_MINIMAL_TX_SIZE - 1) - -#define MAKE_SOCKADDR(addr, ip, port) \ - sockaddr addr; \ - addr.sa_family = AF_INET; \ - addr.sa_data[0] = port >> 8; \ - addr.sa_data[1] = port; \ - addr.sa_data[2] = ip[0]; \ - addr.sa_data[3] = ip[1]; \ - addr.sa_data[4] = ip[2]; \ - addr.sa_data[5] = ip[3]; - -#define UNPACK_SOCKADDR(addr, ip, port) \ - port = (addr.sa_data[0] << 8) | addr.sa_data[1]; \ - ip[0] = addr.sa_data[2]; \ - ip[1] = addr.sa_data[3]; \ - ip[2] = addr.sa_data[4]; \ - ip[3] = addr.sa_data[5]; - -STATIC int cc3k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); - -int CC3000_EXPORT(errno); // for cc3000 driver - -STATIC volatile uint32_t fd_closed_state = 0; -STATIC volatile bool wlan_connected = false; -STATIC volatile bool ip_obtained = false; - -STATIC int cc3k_get_fd_closed_state(int fd) { - return fd_closed_state & (1 << fd); -} - -STATIC void cc3k_set_fd_closed_state(int fd) { - fd_closed_state |= 1 << fd; -} - -STATIC void cc3k_reset_fd_closed_state(int fd) { - fd_closed_state &= ~(1 << fd); -} - -STATIC void cc3k_callback(long event_type, char *data, unsigned char length) { - switch (event_type) { - case HCI_EVNT_WLAN_UNSOL_CONNECT: - wlan_connected = true; - break; - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - // link down - wlan_connected = false; - ip_obtained = false; - break; - case HCI_EVNT_WLAN_UNSOL_DHCP: - ip_obtained = true; - break; - case HCI_EVNT_BSD_TCP_CLOSE_WAIT: - // mark socket for closure - cc3k_set_fd_closed_state(data[0]); - break; - } -} - -STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { - uint32_t ip; - // CC3000 gethostbyname is unreliable and usually returns -95 on first call - for (int retry = 5; CC3000_EXPORT(gethostbyname)((char *)name, len, &ip) < 0; retry--) { - if (retry == 0 || CC3000_EXPORT(errno) != -95) { - return CC3000_EXPORT(errno); - } - mp_hal_delay_ms(50); - } - - if (ip == 0) { - // unknown host - return -2; - } - - out_ip[0] = ip >> 24; - out_ip[1] = ip >> 16; - out_ip[2] = ip >> 8; - out_ip[3] = ip; - - return 0; -} - -STATIC int cc3k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { - if (socket->domain != MOD_NETWORK_AF_INET) { - *_errno = MP_EAFNOSUPPORT; - return -1; - } - - mp_uint_t type; - switch (socket->type) { - case MOD_NETWORK_SOCK_STREAM: - type = SOCK_STREAM; - break; - case MOD_NETWORK_SOCK_DGRAM: - type = SOCK_DGRAM; - break; - case MOD_NETWORK_SOCK_RAW: - type = SOCK_RAW; - break; - default: - *_errno = MP_EINVAL; - return -1; - } - - // open socket - int fd = CC3000_EXPORT(socket)(AF_INET, type, 0); - if (fd < 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - - // clear socket state - cc3k_reset_fd_closed_state(fd); - - // store state of this socket - socket->fileno = fd; - - // make accept blocking by default - int optval = SOCK_OFF; - socklen_t optlen = sizeof(optval); - CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); - - return 0; -} - -STATIC void cc3k_socket_close(mod_network_socket_obj_t *socket) { - CC3000_EXPORT(closesocket)(socket->fileno); -} - -STATIC int cc3k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - MAKE_SOCKADDR(addr, ip, port) - int ret = CC3000_EXPORT(bind)(socket->fileno, &addr, sizeof(addr)); - if (ret != 0) { - *_errno = ret; - return -1; - } - return 0; -} - -STATIC int cc3k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { - int ret = CC3000_EXPORT(listen)(socket->fileno, backlog); - if (ret != 0) { - *_errno = ret; - return -1; - } - return 0; -} - -STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { - // accept incoming connection - int fd; - sockaddr addr; - socklen_t addr_len = sizeof(addr); - if ((fd = CC3000_EXPORT(accept)(socket->fileno, &addr, &addr_len)) < 0) { - if (fd == SOC_IN_PROGRESS) { - *_errno = MP_EAGAIN; - } else { - *_errno = -fd; - } - return -1; - } - - // clear socket state - cc3k_reset_fd_closed_state(fd); - - // store state in new socket object - socket2->fileno = fd; - - // return ip and port - // it seems CC3000 returns little endian for accept?? - // UNPACK_SOCKADDR(addr, ip, *port); - *port = (addr.sa_data[1] << 8) | addr.sa_data[0]; - ip[3] = addr.sa_data[2]; - ip[2] = addr.sa_data[3]; - ip[1] = addr.sa_data[4]; - ip[0] = addr.sa_data[5]; - - return 0; -} - -STATIC int cc3k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - MAKE_SOCKADDR(addr, ip, port) - int ret = CC3000_EXPORT(connect)(socket->fileno, &addr, sizeof(addr)); - if (ret != 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - return 0; -} - -STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { - if (cc3k_get_fd_closed_state(socket->fileno)) { - CC3000_EXPORT(closesocket)(socket->fileno); - *_errno = MP_EPIPE; - return -1; - } - - // CC3K does not handle fragmentation, and will overflow, - // split the packet into smaller ones and send them out. - mp_int_t bytes = 0; - while (bytes < len) { - int n = MIN((len - bytes), MAX_TX_PACKET); - n = CC3000_EXPORT(send)(socket->fileno, (uint8_t *)buf + bytes, n, 0); - if (n <= 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - bytes += n; - } - - return bytes; -} - -STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { - // check the socket is open - if (cc3k_get_fd_closed_state(socket->fileno)) { - // socket is closed, but CC3000 may have some data remaining in buffer, so check - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(socket->fileno, &rfds); - cc3000_timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 1; - int nfds = CC3000_EXPORT(select)(socket->fileno + 1, &rfds, NULL, NULL, &tv); - if (nfds == -1 || !FD_ISSET(socket->fileno, &rfds)) { - // no data waiting, so close socket and return 0 data - CC3000_EXPORT(closesocket)(socket->fileno); - return 0; - } - } - - // cap length at MAX_RX_PACKET - len = MIN(len, MAX_RX_PACKET); - - // do the recv - int ret = CC3000_EXPORT(recv)(socket->fileno, buf, len, 0); - if (ret < 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - - return ret; -} - -STATIC mp_uint_t cc3k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { - MAKE_SOCKADDR(addr, ip, port) - int ret = CC3000_EXPORT(sendto)(socket->fileno, (byte *)buf, len, 0, (sockaddr *)&addr, sizeof(addr)); - if (ret < 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - return ret; -} - -STATIC mp_uint_t cc3k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { - sockaddr addr; - socklen_t addr_len = sizeof(addr); - mp_int_t ret = CC3000_EXPORT(recvfrom)(socket->fileno, buf, len, 0, &addr, &addr_len); - if (ret < 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - UNPACK_SOCKADDR(addr, ip, *port); - return ret; -} - -STATIC int cc3k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { - int ret = CC3000_EXPORT(setsockopt)(socket->fileno, level, opt, optval, optlen); - if (ret < 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - return 0; -} - -STATIC int cc3k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { - int ret; - if (timeout_ms == 0 || timeout_ms == -1) { - int optval; - socklen_t optlen = sizeof(optval); - if (timeout_ms == 0) { - // set non-blocking mode - optval = SOCK_ON; - } else { - // set blocking mode - optval = SOCK_OFF; - } - ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen); - if (ret == 0) { - ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); - } - } else { - // set timeout - socklen_t optlen = sizeof(timeout_ms); - ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &timeout_ms, optlen); - } - - if (ret != 0) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - - return 0; -} - -STATIC int cc3k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { - mp_uint_t ret; - if (request == MP_STREAM_POLL) { - mp_uint_t flags = arg; - ret = 0; - int fd = socket->fileno; - - // init fds - fd_set rfds, wfds, xfds; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - - // set fds if needed - if (flags & MP_STREAM_POLL_RD) { - FD_SET(fd, &rfds); - - // A socked that just closed is available for reading. A call to - // recv() returns 0 which is consistent with BSD. - if (cc3k_get_fd_closed_state(fd)) { - ret |= MP_STREAM_POLL_RD; - } - } - if (flags & MP_STREAM_POLL_WR) { - FD_SET(fd, &wfds); - } - if (flags & MP_STREAM_POLL_HUP) { - FD_SET(fd, &xfds); - } - - // call cc3000 select with minimum timeout - cc3000_timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 1; - int nfds = CC3000_EXPORT(select)(fd + 1, &rfds, &wfds, &xfds, &tv); - - // check for error - if (nfds == -1) { - *_errno = CC3000_EXPORT(errno); - return -1; - } - - // check return of select - if (FD_ISSET(fd, &rfds)) { - ret |= MP_STREAM_POLL_RD; - } - if (FD_ISSET(fd, &wfds)) { - ret |= MP_STREAM_POLL_WR; - } - if (FD_ISSET(fd, &xfds)) { - ret |= MP_STREAM_POLL_HUP; - } - } else { - *_errno = MP_EINVAL; - ret = -1; - } - return ret; -} - -/******************************************************************************/ -// MicroPython bindings; CC3K class - -typedef struct _cc3k_obj_t { - mp_obj_base_t base; -} cc3k_obj_t; - -STATIC const cc3k_obj_t cc3k_obj = {{(mp_obj_type_t *)&mod_network_nic_type_cc3k}}; - -// \classmethod \constructor(spi, pin_cs, pin_en, pin_irq) -// Initialise the CC3000 using the given SPI bus and pins and return a CC3K object. -// -// Note: pins were originally hard-coded to: -// PYBv1.0: init(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) -// [SPI on Y position; Y6=B13=SCK, Y7=B14=MISO, Y8=B15=MOSI] -// -// STM32F4DISC: init(pyb.SPI(2), pyb.Pin.cpu.A15, pyb.Pin.cpu.B10, pyb.Pin.cpu.B11) -STATIC mp_obj_t cc3k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 4, 4, false); - - // set the pins to use - SpiInit( - spi_from_mp_obj(args[0])->spi, - pin_find(args[1]), - pin_find(args[2]), - pin_find(args[3]) - ); - - // initialize and start the module - wlan_init(cc3k_callback, NULL, NULL, NULL, - ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin); - - if (wlan_start(0) != 0) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed to init CC3000 module")); - } - - // set connection policy. this should be called explicitly by the user - // wlan_ioctl_set_connection_policy(0, 0, 0); - - // Mask out all non-required events from the CC3000 - wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE | - HCI_EVNT_WLAN_UNSOL_INIT | - HCI_EVNT_WLAN_ASYNC_PING_REPORT | - HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE); - - // register with network module - mod_network_register_nic((mp_obj_t)&cc3k_obj); - - return (mp_obj_t)&cc3k_obj; -} - -// method connect(ssid, key=None, *, security=WPA2, bssid=None) -STATIC mp_obj_t cc3k_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = WLAN_SEC_WPA2} }, - { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // get ssid - size_t ssid_len; - const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len); - - // get key and sec - size_t key_len = 0; - const char *key = NULL; - mp_uint_t sec = WLAN_SEC_UNSEC; - if (args[1].u_obj != mp_const_none) { - key = mp_obj_str_get_data(args[1].u_obj, &key_len); - sec = args[2].u_int; - } - - // get bssid - const char *bssid = NULL; - if (args[3].u_obj != mp_const_none) { - bssid = mp_obj_str_get_str(args[3].u_obj); - } - - // connect to AP - if (wlan_connect(sec, (char *)ssid, ssid_len, (uint8_t *)bssid, (uint8_t *)key, key_len) != 0) { - mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("could not connect to ssid=%s, sec=%d, key=%s\n"), ssid, sec, key); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(cc3k_connect_obj, 1, cc3k_connect); - -STATIC mp_obj_t cc3k_disconnect(mp_obj_t self_in) { - // should we check return value? - wlan_disconnect(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(cc3k_disconnect_obj, cc3k_disconnect); - -STATIC mp_obj_t cc3k_isconnected(mp_obj_t self_in) { - return mp_obj_new_bool(wlan_connected && ip_obtained); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(cc3k_isconnected_obj, cc3k_isconnected); - -STATIC mp_obj_t cc3k_ifconfig(mp_obj_t self_in) { - tNetappIpconfigRetArgs ipconfig; - netapp_ipconfig(&ipconfig); - - // render MAC address - VSTR_FIXED(mac_vstr, 18); - const uint8_t *mac = ipconfig.uaMacAddr; - vstr_printf(&mac_vstr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); - - // create and return tuple with ifconfig info - mp_obj_t tuple[7] = { - netutils_format_ipv4_addr(ipconfig.aucIP, NETUTILS_LITTLE), - netutils_format_ipv4_addr(ipconfig.aucSubnetMask, NETUTILS_LITTLE), - netutils_format_ipv4_addr(ipconfig.aucDefaultGateway, NETUTILS_LITTLE), - netutils_format_ipv4_addr(ipconfig.aucDNSServer, NETUTILS_LITTLE), - netutils_format_ipv4_addr(ipconfig.aucDHCPServer, NETUTILS_LITTLE), - mp_obj_new_str(mac_vstr.buf, mac_vstr.len), - mp_obj_new_str((const char *)ipconfig.uaSSID, strlen((const char *)ipconfig.uaSSID)), - }; - return mp_obj_new_tuple(MP_ARRAY_SIZE(tuple), tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(cc3k_ifconfig_obj, cc3k_ifconfig); - -STATIC mp_obj_t cc3k_patch_version(mp_obj_t self_in) { - uint8_t pver[2]; - mp_obj_tuple_t *t_pver; - - nvmem_read_sp_version(pver); - t_pver = mp_obj_new_tuple(2, NULL); - t_pver->items[0] = mp_obj_new_int(pver[0]); - t_pver->items[1] = mp_obj_new_int(pver[1]); - return t_pver; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(cc3k_patch_version_obj, cc3k_patch_version); - -STATIC mp_obj_t cc3k_patch_program(mp_obj_t self_in, mp_obj_t key_in) { - const char *key = mp_obj_str_get_str(key_in); - if (key[0] == 'p' && key[1] == 'g' && key[2] == 'm' && key[3] == '\0') { - patch_prog_start(); - } else { - mp_print_str(&mp_plat_print, "pass 'pgm' as argument in order to program\n"); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(cc3k_patch_program_obj, cc3k_patch_program); - -STATIC const mp_rom_map_elem_t cc3k_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&cc3k_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&cc3k_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&cc3k_isconnected_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&cc3k_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_patch_version), MP_ROM_PTR(&cc3k_patch_version_obj) }, - { MP_ROM_QSTR(MP_QSTR_patch_program), MP_ROM_PTR(&cc3k_patch_program_obj) }, - - // class constants - { MP_ROM_QSTR(MP_QSTR_WEP), MP_ROM_INT(WLAN_SEC_WEP) }, - { MP_ROM_QSTR(MP_QSTR_WPA), MP_ROM_INT(WLAN_SEC_WPA) }, - { MP_ROM_QSTR(MP_QSTR_WPA2), MP_ROM_INT(WLAN_SEC_WPA2) }, -}; - -STATIC MP_DEFINE_CONST_DICT(cc3k_locals_dict, cc3k_locals_dict_table); - -const mod_network_nic_type_t mod_network_nic_type_cc3k = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_CC3K, - .make_new = cc3k_make_new, - .locals_dict = (mp_obj_dict_t *)&cc3k_locals_dict, - }, - .gethostbyname = cc3k_gethostbyname, - .socket = cc3k_socket_socket, - .close = cc3k_socket_close, - .bind = cc3k_socket_bind, - .listen = cc3k_socket_listen, - .accept = cc3k_socket_accept, - .connect = cc3k_socket_connect, - .send = cc3k_socket_send, - .recv = cc3k_socket_recv, - .sendto = cc3k_socket_sendto, - .recvfrom = cc3k_socket_recvfrom, - .setsockopt = cc3k_socket_setsockopt, - .settimeout = cc3k_socket_settimeout, - .ioctl = cc3k_socket_ioctl, -}; diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index e06e32c0d217..69b29e8ec393 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -200,13 +200,6 @@ extern const struct _mod_network_nic_type_t mod_network_nic_type_wiznet5k; #define MICROPY_HW_NIC_WIZNET5K #endif -#if MICROPY_PY_CC3K -extern const struct _mod_network_nic_type_t mod_network_nic_type_cc3k; -#define MICROPY_HW_NIC_CC3K { MP_ROM_QSTR(MP_QSTR_CC3K), MP_ROM_PTR(&mod_network_nic_type_cc3k) }, -#else -#define MICROPY_HW_NIC_CC3K -#endif - // extra constants #define MICROPY_PORT_CONSTANTS \ MACHINE_BUILTIN_MODULE_CONSTANTS \ @@ -221,7 +214,6 @@ extern const struct _mod_network_nic_type_t mod_network_nic_type_cc3k; MICROPY_HW_NIC_ETH \ MICROPY_HW_NIC_CYW43 \ MICROPY_HW_NIC_WIZNET5K \ - MICROPY_HW_NIC_CC3K \ MICROPY_BOARD_NETWORK_INTERFACES \ #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/stm32/mpconfigport.mk b/ports/stm32/mpconfigport.mk index 830ccf03123a..737ff9d3d29a 100644 --- a/ports/stm32/mpconfigport.mk +++ b/ports/stm32/mpconfigport.mk @@ -6,9 +6,6 @@ # 5500 : support for W5500 module MICROPY_PY_NETWORK_WIZNET5K ?= 0 -# cc3k module for wifi support -MICROPY_PY_CC3K ?= 0 - # VFS FAT FS support MICROPY_VFS_FAT ?= 1 diff --git a/tools/ci.sh b/tools/ci.sh index b7b20e3c7d65..b4cb7dc2e380 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -313,8 +313,6 @@ function ci_stm32_pyb_build { git submodule update --init lib/btstack git submodule update --init lib/mynewt-nimble make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 USER_C_MODULES=../../examples/usercmodule - make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 clean - make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_CC3K=1 make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2 make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1 make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBV10 CFLAGS_EXTRA='-DMBOOT_FSLOAD=1 -DMBOOT_VFS_LFS2=1' From 7d3f4b23dc26bd26477a2ef6d7b25b3af73453f4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 24 Aug 2022 10:48:27 +1000 Subject: [PATCH 1648/4290] drivers/cc3000: Remove CC3000 WiFi driver files. It's no longer used by any port. Signed-off-by: Damien George --- LICENSE | 1 - docs/library/network.CC3K.rst | 89 -- docs/library/network.rst | 1 - drivers/cc3000/inc/cc3000_common.h | 365 ------- drivers/cc3000/inc/ccspi.h | 84 -- drivers/cc3000/inc/data_types.h | 107 -- drivers/cc3000/inc/evnt_handler.h | 166 --- drivers/cc3000/inc/hci.h | 330 ------ drivers/cc3000/inc/host_driver_version.h | 40 - drivers/cc3000/inc/inet_ntop.h | 4 - drivers/cc3000/inc/inet_pton.h | 4 - drivers/cc3000/inc/netapp.h | 343 ------ drivers/cc3000/inc/nvmem.h | 248 ----- drivers/cc3000/inc/patch_prog.h | 11 - drivers/cc3000/inc/security.h | 130 --- drivers/cc3000/inc/socket.h | 676 ------------ drivers/cc3000/inc/wlan.h | 518 --------- drivers/cc3000/src/cc3000_common.c | 164 --- drivers/cc3000/src/ccspi.c | 455 -------- drivers/cc3000/src/evnt_handler.c | 849 --------------- drivers/cc3000/src/hci.c | 225 ---- drivers/cc3000/src/inet_ntop.c | 200 ---- drivers/cc3000/src/inet_pton.c | 216 ---- drivers/cc3000/src/netapp.c | 459 -------- drivers/cc3000/src/nvmem.c | 334 ------ drivers/cc3000/src/patch.c | 117 -- drivers/cc3000/src/patch_prog.c | 414 ------- drivers/cc3000/src/security.c | 530 --------- drivers/cc3000/src/socket.c | 1182 -------------------- drivers/cc3000/src/wlan.c | 1252 ---------------------- 30 files changed, 9514 deletions(-) delete mode 100644 docs/library/network.CC3K.rst delete mode 100644 drivers/cc3000/inc/cc3000_common.h delete mode 100644 drivers/cc3000/inc/ccspi.h delete mode 100644 drivers/cc3000/inc/data_types.h delete mode 100644 drivers/cc3000/inc/evnt_handler.h delete mode 100644 drivers/cc3000/inc/hci.h delete mode 100644 drivers/cc3000/inc/host_driver_version.h delete mode 100644 drivers/cc3000/inc/inet_ntop.h delete mode 100644 drivers/cc3000/inc/inet_pton.h delete mode 100644 drivers/cc3000/inc/netapp.h delete mode 100644 drivers/cc3000/inc/nvmem.h delete mode 100644 drivers/cc3000/inc/patch_prog.h delete mode 100644 drivers/cc3000/inc/security.h delete mode 100644 drivers/cc3000/inc/socket.h delete mode 100644 drivers/cc3000/inc/wlan.h delete mode 100644 drivers/cc3000/src/cc3000_common.c delete mode 100644 drivers/cc3000/src/ccspi.c delete mode 100644 drivers/cc3000/src/evnt_handler.c delete mode 100644 drivers/cc3000/src/hci.c delete mode 100644 drivers/cc3000/src/inet_ntop.c delete mode 100644 drivers/cc3000/src/inet_pton.c delete mode 100644 drivers/cc3000/src/netapp.c delete mode 100644 drivers/cc3000/src/nvmem.c delete mode 100644 drivers/cc3000/src/patch.c delete mode 100644 drivers/cc3000/src/patch_prog.c delete mode 100644 drivers/cc3000/src/security.c delete mode 100644 drivers/cc3000/src/socket.c delete mode 100644 drivers/cc3000/src/wlan.c diff --git a/LICENSE b/LICENSE index 2b9a64b89a72..5a91df195fd4 100644 --- a/LICENSE +++ b/LICENSE @@ -35,7 +35,6 @@ used during the build process and is not part of the compiled source code. / (MIT) /drivers - /cc3000 (BSD-3-clause) /cc3100 (BSD-3-clause) /wiznet5k (BSD-3-clause) /lib diff --git a/docs/library/network.CC3K.rst b/docs/library/network.CC3K.rst deleted file mode 100644 index 41d3fb437e99..000000000000 --- a/docs/library/network.CC3K.rst +++ /dev/null @@ -1,89 +0,0 @@ -.. currentmodule:: network -.. _network.CC3K: - -class CC3K -- control CC3000 WiFi modules -========================================= - -This class provides a driver for CC3000 WiFi modules. Example usage:: - - import network - nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) - nic.connect('your-ssid', 'your-password') - while not nic.isconnected(): - pyb.delay(50) - print(nic.ifconfig()) - - # now use socket as usual - ... - -For this example to work the CC3000 module must have the following connections: - - - MOSI connected to Y8 - - MISO connected to Y7 - - CLK connected to Y6 - - CS connected to Y5 - - VBEN connected to Y4 - - IRQ connected to Y3 - -It is possible to use other SPI buses and other pins for CS, VBEN and IRQ. - -Constructors ------------- - -.. class:: CC3K(spi, pin_cs, pin_en, pin_irq) - - Create a CC3K driver object, initialise the CC3000 module using the given SPI bus - and pins, and return the CC3K object. - - Arguments are: - - - *spi* is an :ref:`SPI object ` which is the SPI bus that the CC3000 is - connected to (the MOSI, MISO and CLK pins). - - *pin_cs* is a :ref:`Pin object ` which is connected to the CC3000 CS pin. - - *pin_en* is a :ref:`Pin object ` which is connected to the CC3000 VBEN pin. - - *pin_irq* is a :ref:`Pin object ` which is connected to the CC3000 IRQ pin. - - All of these objects will be initialised by the driver, so there is no need to - initialise them yourself. For example, you can use:: - - nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) - -Methods -------- - -.. method:: CC3K.connect(ssid, key=None, *, security=WPA2, bssid=None) - - Connect to a WiFi access point using the given SSID, and other security - parameters. - -.. method:: CC3K.disconnect() - - Disconnect from the WiFi access point. - -.. method:: CC3K.isconnected() - - Returns True if connected to a WiFi access point and has a valid IP address, - False otherwise. - -.. method:: CC3K.ifconfig() - - Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server, - MAC address, SSID). - -.. method:: CC3K.patch_version() - - Return the version of the patch program (firmware) on the CC3000. - -.. method:: CC3K.patch_program('pgm') - - Upload the current firmware to the CC3000. You must pass 'pgm' as the first - argument in order for the upload to proceed. - -Constants ---------- - -.. data:: CC3K.WEP -.. data:: CC3K.WPA -.. data:: CC3K.WPA2 - - security type to use diff --git a/docs/library/network.rst b/docs/library/network.rst index 6742a2e0733d..0a6f5506ea41 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -150,7 +150,6 @@ provide a way to control networking interfaces of various kinds. network.WLAN.rst network.WLANWiPy.rst - network.CC3K.rst network.WIZNET5K.rst network.LAN.rst diff --git a/drivers/cc3000/inc/cc3000_common.h b/drivers/cc3000/inc/cc3000_common.h deleted file mode 100644 index d0c4b1d4b92e..000000000000 --- a/drivers/cc3000/inc/cc3000_common.h +++ /dev/null @@ -1,365 +0,0 @@ -/***************************************************************************** -* -* cc3000_common.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_COMMON_H__ -#define __CC3000_COMMON_H__ - -#include "data_types.h" - -//****************************************************************************** -// Include files -//****************************************************************************** -#include -#include - -//***************************************************************************** -// Prefix exported names to avoid name clash -//***************************************************************************** -#define CC3000_EXPORT(name) cc3000_ ## name - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -extern int CC3000_EXPORT(errno); - -//***************************************************************************** -// ERROR CODES -//***************************************************************************** -#define ESUCCESS 0 -#define EFAIL -1 -#define EERROR EFAIL - -//***************************************************************************** -// COMMON DEFINES -//***************************************************************************** -#define ERROR_SOCKET_INACTIVE -57 - -#define WLAN_ENABLE (1) -#define WLAN_DISABLE (0) - -#define MAC_ADDR_LEN (6) - -#define SP_PORTION_SIZE (32) - -/*Defines for minimal and maximal RX buffer size. This size includes the spi - header and hci header. - The maximal buffer size derives from: - MTU + HCI header + SPI header + sendto() agrs size - The minimum buffer size derives from: - HCI header + SPI header + max args size - - This buffer is used for receiving events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for reception of the data - and events from CC3000. That is why the minimum is defined. - The calculation for the actual size of buffer for reception is: - Given the maximal data size MAX_DATA that is expected to be received by - application, the required buffer is: - Using recv() or recvfrom(): - - max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen - + ucArgsize + 1) - - Using gethostbyname() with minimal buffer size will limit the host name - returned to 99 bytes only. - The 1 is used for the overrun detection - - Buffer size increased to 130 following the add_profile() with WEP security - which requires TX buffer size of 130 bytes: - HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130 - MAX SSID LEN = 32 - MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, - therfore maximum key size is 13) -*/ - -#define CC3000_MINIMAL_RX_SIZE (130 + 1) -#define CC3000_MAXIMAL_RX_SIZE (1519 + 1) - -/*Defines for minimal and maximal TX buffer size. - This buffer is used for sending events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for transmission of the data - and commands. That is why the minimum is defined. - The calculation for the actual size of buffer for transmission is: - Given the maximal data size MAX_DATA, the required buffer is: - Using Sendto(): - - max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE - + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - Using Send(): - - max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE - + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - The 1 is used for the overrun detection */ - -#define CC3000_MINIMAL_TX_SIZE (130 + 1) -#define CC3000_MAXIMAL_TX_SIZE (1519 + 1) - -//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8. -#ifdef CC3000_TINY_DRIVER -#define TINY_CC3000_MAXIMAL_RX_SIZE 44 -#define TINY_CC3000_MAXIMAL_TX_SIZE 59 -#endif - -/*In order to determine your preferred buffer size, - change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between - the minimal and maximal specified above. - Note that the buffers are allocated by SPI. - In case you change the size of those buffers, you might need also to change - the linker file, since for example on MSP430 FRAM devices the buffers are - allocated in the FRAM section that is allocated manually and not by IDE. -*/ - -#ifndef CC3000_TINY_DRIVER - - #define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE) - #define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE) - -//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption -#else - #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE) - #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE) - -#endif - -//***************************************************************************** -// Compound Types -//***************************************************************************** -typedef INT32 cc3000_time_t; -typedef UINT32 clock_t; -typedef INT32 suseconds_t; - -typedef struct cc3000_timeval cc3000_timeval; - -struct cc3000_timeval -{ - cc3000_time_t tv_sec; /* seconds */ - suseconds_t tv_usec; /* microseconds */ -}; - -typedef CHAR *(*tFWPatches)(UINT32 *usLength); - -typedef CHAR *(*tDriverPatches)(UINT32 *usLength); - -typedef CHAR *(*tBootLoaderPatches)(UINT32 *usLength); - -typedef void (*tWlanCB)(INT32 event_type, CHAR * data, UINT8 length ); - -typedef INT32 (*tWlanReadInteruptPin)(void); - -typedef void (*tWlanInterruptEnable)(void); - -typedef void (*tWlanInterruptDisable)(void); - -typedef void (*tWriteWlanPin)(UINT8 val); - -typedef struct -{ - UINT16 usRxEventOpcode; - UINT16 usEventOrDataReceived; - UINT8 *pucReceivedData; - UINT8 *pucTxCommandBuffer; - - tFWPatches sFWPatches; - tDriverPatches sDriverPatches; - tBootLoaderPatches sBootLoaderPatches; - tWlanCB sWlanCB; - tWlanReadInteruptPin ReadWlanInterruptPin; - tWlanInterruptEnable WlanInterruptEnable; - tWlanInterruptDisable WlanInterruptDisable; - tWriteWlanPin WriteWlanPin; - - INT32 slTransmitDataError; - UINT16 usNumberOfFreeBuffers; - UINT16 usSlBufferLength; - UINT16 usBufferSize; - UINT16 usRxDataPending; - - UINT32 NumberOfSentPackets; - UINT32 NumberOfReleasedPackets; - - UINT8 InformHostOnTxComplete; -}sSimplLinkInformation; - -extern volatile sSimplLinkInformation tSLInformation; - - -//***************************************************************************** -// Prototypes for the APIs. -//***************************************************************************** - - - -//***************************************************************************** -// -//! SimpleLinkWaitEvent -//! -//! @param usOpcode command operation code -//! @param pRetParams command return parameters -//! -//! @return none -//! -//! @brief Wait for event, pass it to the hci_event_handler and -//! update the event opcode in a global variable. -// -//***************************************************************************** - -extern void SimpleLinkWaitEvent(UINT16 usOpcode, void *pRetParams); - -//***************************************************************************** -// -//! SimpleLinkWaitData -//! -//! @param pBuf data buffer -//! @param from from information -//! @param fromlen from information length -//! -//! @return none -//! -//! @brief Wait for data, pass it to the hci_event_handler -//! and update in a global variable that there is -//! data to read. -// -//***************************************************************************** - -extern void SimpleLinkWaitData(UINT8 *pBuf, UINT8 *from, UINT8 *fromlen); - -//***************************************************************************** -// -//! UINT32_TO_STREAM_f -//! -//! \param p pointer to the new stream -//! \param u32 pointer to the 32 bit -//! -//! \return pointer to the new stream -//! -//! \brief This function is used for copying 32 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -extern UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32); - -//***************************************************************************** -// -//! UINT16_TO_STREAM_f -//! -//! \param p pointer to the new stream -//! \param u32 pointer to the 16 bit -//! -//! \return pointer to the new stream -//! -//! \brief This function is used for copying 16 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -extern UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16); - -//***************************************************************************** -// -//! STREAM_TO_UINT16_f -//! -//! \param p pointer to the stream -//! \param offset offset in the stream -//! -//! \return pointer to the new 16 bit -//! -//! \brief This function is used for copying received stream to -//! 16 bit in little endian format. -// -//***************************************************************************** - -extern UINT16 STREAM_TO_UINT16_f(CHAR* p, UINT16 offset); - -//***************************************************************************** -// -//! STREAM_TO_UINT32_f -//! -//! \param p pointer to the stream -//! \param offset offset in the stream -//! -//! \return pointer to the new 32 bit -//! -//! \brief This function is used for copying received stream to -//! 32 bit in little endian format. -// -//***************************************************************************** - -extern UINT32 STREAM_TO_UINT32_f(CHAR* p, UINT16 offset); - - -//***************************************************************************** -// COMMON MACROs -//***************************************************************************** - - -//This macro is used for copying 8 bit to stream while converting to little endian format. -#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);} -//This macro is used for copying 16 bit to stream while converting to little endian format. -#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16)) -//This macro is used for copying 32 bit to stream while converting to little endian format. -#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32)) -//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format. -#define ARRAY_TO_STREAM(p, a, l) {register INT16 _i; for (_i = 0; _i < l; _i++) *(p)++ = ((UINT8 *) a)[_i];} -//This macro is used for copying received stream to 8 bit in little endian format. -#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (UINT8)(*(_p + _offset));} -//This macro is used for copying received stream to 16 bit in little endian format. -#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);} -//This macro is used for copying received stream to 32 bit in little endian format. -#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);} -#define STREAM_TO_STREAM(p, a, l) {register INT16 _i; for (_i = 0; _i < l; _i++) *(a)++= ((UINT8 *) p)[_i];} - - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_COMMON_H__ diff --git a/drivers/cc3000/inc/ccspi.h b/drivers/cc3000/inc/ccspi.h deleted file mode 100644 index 8fa3ecd10c2f..000000000000 --- a/drivers/cc3000/inc/ccspi.h +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************************** -* -* spi.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - - -#ifndef __CC3000_SPI_H__ -#define __CC3000_SPI_H__ - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*gcSpiHandleRx)(void *p); -typedef void (*gcSpiHandleTx)(void); -extern unsigned char wlan_tx_buffer[]; - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef* -extern void SpiInit(void *spi, const void *pin_cs, const void *pin_en, const void *pin_irq); - -extern void SpiOpen(gcSpiHandleRx pfRxHandler); -extern void SpiClose(void); -extern void SpiPauseSpi(void); -extern void SpiResumeSpi(void); -extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength); -extern void SpiConfigureHwMapping(void); -extern void SpiCleanGPIOISR(void); -extern void SSIConfigure(unsigned long ulSSIFreq, unsigned long bForceGpioConfiguration, unsigned long uiReconfigureSysClock); -extern int init_spi(void); -extern long ReadWlanInterruptPin(void); -extern void WriteWlanPin(unsigned char val); -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif - diff --git a/drivers/cc3000/inc/data_types.h b/drivers/cc3000/inc/data_types.h deleted file mode 100644 index 0520a9202fb8..000000000000 --- a/drivers/cc3000/inc/data_types.h +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************** -* -* data_types.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_DATA_TYPES__ -#define __CC3000_DATA_TYPES__ - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef NULL -#define NULL (0) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#ifndef OK -#define OK (0) -#endif - -#ifndef _INT8 -#define _INT8 -typedef signed char INT8; -#endif - -#ifndef _UINT8 -#define _UINT8 -typedef unsigned char UINT8; -#endif - -#ifndef _INT16 -#define _INT16 -typedef signed short INT16; -#endif - -#ifndef _UINT16 -#define _UINT16 -typedef unsigned short UINT16; -#endif - -#ifndef _BOOLEAN -#define _BOOLEAN -typedef unsigned char BOOLEAN; -#endif - -#ifndef _INT32 -#define _INT32 -typedef signed long INT32; -#endif - -#ifndef _UINT32 -#define _UINT32 -typedef unsigned long UINT32; -#endif - -typedef int INT; -typedef char CHAR; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __CC3000_DATA_TYPES__ */ diff --git a/drivers/cc3000/inc/evnt_handler.h b/drivers/cc3000/inc/evnt_handler.h deleted file mode 100644 index d05a442f05fb..000000000000 --- a/drivers/cc3000/inc/evnt_handler.h +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************** -* -* evnt_handler.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_EVENT_HANDLER_H__ -#define __CC3000_EVENT_HANDLER_H__ -#include "hci.h" -#include "socket.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -//***************************************************************************** -// -//! hci_event_handler -//! -//! @param pRetParams incoming data buffer -//! @param from from information (in case of data received) -//! @param fromlen from information length (in case of data received) -//! -//! @return none -//! -//! @brief Parse the incoming events packets and issues corresponding -//! event handler from global array of handlers pointers -// -//***************************************************************************** -extern UINT8 *hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen); - -//***************************************************************************** -// -//! hci_unsol_event_handler -//! -//! @param event_hdr event header -//! -//! @return 1 if event supported and handled -//! 0 if event is not supported -//! -//! @brief Handle unsolicited events -// -//***************************************************************************** -extern INT32 hci_unsol_event_handler(CHAR *event_hdr); - -//***************************************************************************** -// -//! hci_unsolicited_event_handler -//! -//! @param None -//! -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Parse the incoming unsolicited event packets and issues -//! corresponding event handler. -// -//***************************************************************************** -extern INT32 hci_unsolicited_event_handler(void); - -#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((CHAR *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE) - -#define SOCKET_STATUS_ACTIVE 0 -#define SOCKET_STATUS_INACTIVE 1 -/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE. - Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */ -#define SOCKET_STATUS_INIT_VAL 0xFFFF -#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) -#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) - -extern UINT32 socket_active_status; - -extern void set_socket_active_status(INT32 Sd, INT32 Status); -extern INT32 get_socket_active_status(INT32 Sd); - -typedef struct _bsd_accept_return_t -{ - INT32 iSocketDescriptor; - INT32 iStatus; - sockaddr tSocketAddress; - -} tBsdReturnParams; - - -typedef struct _bsd_read_return_t -{ - INT32 iSocketDescriptor; - INT32 iNumberOfBytes; - UINT32 uiFlags; -} tBsdReadReturnParams; - -#define BSD_RECV_FROM_FROMLEN_OFFSET (4) -#define BSD_RECV_FROM_FROM_OFFSET (16) - - -typedef struct _bsd_select_return_t -{ - INT32 iStatus; - UINT32 uiRdfd; - UINT32 uiWrfd; - UINT32 uiExfd; -} tBsdSelectRecvParams; - - -typedef struct _bsd_getsockopt_return_t -{ - UINT8 ucOptValue[4]; - CHAR iStatus; -} tBsdGetSockOptReturnParams; - -typedef struct _bsd_gethostbyname_return_t -{ - INT32 retVal; - INT32 outputAddress; -} tBsdGethostbynameParams; - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_EVENT_HANDLER_H__ - diff --git a/drivers/cc3000/inc/hci.h b/drivers/cc3000/inc/hci.h deleted file mode 100644 index f12b00e918e1..000000000000 --- a/drivers/cc3000/inc/hci.h +++ /dev/null @@ -1,330 +0,0 @@ -/***************************************************************************** -* -* hci.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_HCI_H__ -#define __CC3000_HCI_H__ - -#include "cc3000_common.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -#define SPI_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4) -#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) -#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2) - - -//***************************************************************************** -// -// Values that can be used as HCI Commands and HCI Packet header defines -// -//***************************************************************************** -#define HCI_TYPE_CMND 0x1 -#define HCI_TYPE_DATA 0x2 -#define HCI_TYPE_PATCH 0x3 -#define HCI_TYPE_EVNT 0x4 - - -#define HCI_EVENT_PATCHES_DRV_REQ (1) -#define HCI_EVENT_PATCHES_FW_REQ (2) -#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3) - - -#define HCI_CMND_WLAN_BASE (0x0000) -#define HCI_CMND_WLAN_CONNECT 0x0001 -#define HCI_CMND_WLAN_DISCONNECT 0x0002 -#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003 -#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004 -#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005 -#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006 -#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007 -#define HCI_CMND_EVENT_MASK 0x0008 -#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009 -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C -#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D - - -#define HCI_CMND_SOCKET_BASE 0x1000 -#define HCI_CMND_SOCKET 0x1001 -#define HCI_CMND_BIND 0x1002 -#define HCI_CMND_RECV 0x1004 -#define HCI_CMND_ACCEPT 0x1005 -#define HCI_CMND_LISTEN 0x1006 -#define HCI_CMND_CONNECT 0x1007 -#define HCI_CMND_BSD_SELECT 0x1008 -#define HCI_CMND_SETSOCKOPT 0x1009 -#define HCI_CMND_GETSOCKOPT 0x100A -#define HCI_CMND_CLOSE_SOCKET 0x100B -#define HCI_CMND_RECVFROM 0x100D -#define HCI_CMND_GETHOSTNAME 0x1010 -#define HCI_CMND_MDNS_ADVERTISE 0x1011 -#define HCI_CMND_GETMSSVALUE 0x1012 - - -#define HCI_DATA_BASE 0x80 - -#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE) -#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE) -#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE) -#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE) - - -#define HCI_CMND_NVMEM_CBASE (0x0200) - - -#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203) -#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205) -#define HCI_CMND_NVMEM_READ (0x0201) -#define HCI_CMND_NVMEM_WRITE (0x0090) -#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204) -#define HCI_CMND_READ_SP_VERSION (0x0207) - -#define HCI_CMND_READ_BUFFER_SIZE 0x400B -#define HCI_CMND_SIMPLE_LINK_START 0x4000 - -#define HCI_CMND_NETAPP_BASE 0x2000 - -#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE) - - - - - - -//***************************************************************************** -// -// Values that can be used as HCI Events defines -// -//***************************************************************************** -#define HCI_EVNT_WLAN_BASE 0x0000 -#define HCI_EVNT_WLAN_CONNECT 0x0001 -#define HCI_EVNT_WLAN_DISCONNECT \ - 0x0002 -#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \ - 0x0005 - - -#define HCI_EVNT_SOCKET HCI_CMND_SOCKET -#define HCI_EVNT_BIND HCI_CMND_BIND -#define HCI_EVNT_RECV HCI_CMND_RECV -#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT -#define HCI_EVNT_LISTEN HCI_CMND_LISTEN -#define HCI_EVNT_CONNECT HCI_CMND_CONNECT -#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT -#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET -#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM -#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT -#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT -#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME -#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE -#define HCI_EVNT_GETMSSVALUE HCI_CMND_GETMSSVALUE - -#define HCI_EVNT_SEND 0x1003 -#define HCI_EVNT_WRITE 0x100E -#define HCI_EVNT_SENDTO 0x100F - -#define HCI_EVNT_PATCHES_REQ 0x1000 - -#define HCI_EVNT_UNSOL_BASE 0x4000 - -#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000) - -#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE) - -#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \ - 0x4100 - -#define HCI_EVNT_NVMEM_CREATE_ENTRY \ - HCI_CMND_NVMEM_CREATE_ENTRY -#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY - -#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ -#define HCI_EVNT_NVMEM_WRITE (0x0202) - -#define HCI_EVNT_READ_SP_VERSION \ - HCI_CMND_READ_SP_VERSION - -#define HCI_EVNT_INPROGRESS 0xFFFF - - -#define HCI_DATA_RECVFROM 0x84 -#define HCI_DATA_RECV 0x85 -#define HCI_DATA_NVMEM 0x91 - -#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99 - -//***************************************************************************** -// -// Prototypes for the structures for APIs. -// -//***************************************************************************** - -#define HCI_DATA_HEADER_SIZE (5) -#define HCI_EVENT_HEADER_SIZE (5) -#define HCI_DATA_CMD_HEADER_SIZE (5) -#define HCI_PATCH_HEADER_SIZE (6) - -#define HCI_PACKET_TYPE_OFFSET (0) -#define HCI_PACKET_ARGSIZE_OFFSET (2) -#define HCI_PACKET_LENGTH_OFFSET (3) - - -#define HCI_EVENT_OPCODE_OFFSET (1) -#define HCI_EVENT_LENGTH_OFFSET (3) -#define HCI_EVENT_STATUS_OFFSET (4) -#define HCI_DATA_LENGTH_OFFSET (3) - - - - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -//***************************************************************************** -// -//! hci_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param ucArgsLength length of the arguments -//! -//! @return none -//! -//! @brief Initiate an HCI command. -// -//***************************************************************************** -extern UINT16 hci_command_send(UINT16 usOpcode, - UINT8 *ucArgs, - UINT8 ucArgsLength); - - -//***************************************************************************** -// -//! hci_data_send -//! -//! @param usOpcode command operation code -//! @param ucArgs pointer to the command's arguments buffer -//! @param usArgsLength length of the arguments -//! @param ucTail pointer to the data buffer -//! @param usTailLength buffer length -//! -//! @return none -//! -//! @brief Initiate an HCI data write operation -// -//***************************************************************************** -extern INT32 hci_data_send(UINT8 ucOpcode, - UINT8 *ucArgs, - UINT16 usArgsLength, - UINT16 usDataLength, - const UINT8 *ucTail, - UINT16 usTailLength); - - -//***************************************************************************** -// -//! hci_data_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the data buffer -//! @param ucArgsLength arguments length -//! @param ucDataLength data length -//! -//! @return none -//! -//! @brief Prepare HCI header and initiate an HCI data write operation -// -//***************************************************************************** -extern void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff, - UINT8 ucArgsLength, UINT16 ucDataLength); - -//***************************************************************************** -// -//! hci_patch_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer -//! @param usDataLength data length -//! -//! @return none -//! -//! @brief Prepare HCI header and initiate an HCI patch write operation -// -//***************************************************************************** -extern void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength); - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_HCI_H__ diff --git a/drivers/cc3000/inc/host_driver_version.h b/drivers/cc3000/inc/host_driver_version.h deleted file mode 100644 index a28d21f1beac..000000000000 --- a/drivers/cc3000/inc/host_driver_version.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************** -* -* host_driver_version.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_HOST_DRIVER_VERSION_H__ -#define __CC3000_HOST_DRIVER_VERSION_H__ - -#define DRIVER_VERSION_NUMBER 15 - -#endif // __CC3000_HOST_DRIVER_VERSION_H__ diff --git a/drivers/cc3000/inc/inet_ntop.h b/drivers/cc3000/inc/inet_ntop.h deleted file mode 100644 index fa70806206ac..000000000000 --- a/drivers/cc3000/inc/inet_ntop.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __INET_NTOP_H -#define __INET_NTOP_H -char *inet_ntop(int af, const void *addr, char *buf, size_t size); -#endif /* __INET_NTOP_H */ diff --git a/drivers/cc3000/inc/inet_pton.h b/drivers/cc3000/inc/inet_pton.h deleted file mode 100644 index 0896d5d29fd7..000000000000 --- a/drivers/cc3000/inc/inet_pton.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __INET_PTON_H -#define __INET_PTON_H -int inet_pton(int, const char *, void *); -#endif /* __INET_PTON_H */ diff --git a/drivers/cc3000/inc/netapp.h b/drivers/cc3000/inc/netapp.h deleted file mode 100644 index 1e4f26589656..000000000000 --- a/drivers/cc3000/inc/netapp.h +++ /dev/null @@ -1,343 +0,0 @@ -/***************************************************************************** -* -* netapp.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_NETAPP_H__ -#define __CC3000_NETAPP_H__ - -#include "data_types.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -//***************************************************************************** -// -//! \addtogroup netapp_api -//! @{ -// -//***************************************************************************** - -typedef struct _netapp_dhcp_ret_args_t -{ - UINT8 aucIP[4]; - UINT8 aucSubnetMask[4]; - UINT8 aucDefaultGateway[4]; - UINT8 aucDHCPServer[4]; - UINT8 aucDNSServer[4]; -}tNetappDhcpParams; - -typedef struct _netapp_ipconfig_ret_args_t -{ - UINT8 aucIP[4]; - UINT8 aucSubnetMask[4]; - UINT8 aucDefaultGateway[4]; - UINT8 aucDHCPServer[4]; - UINT8 aucDNSServer[4]; - UINT8 uaMacAddr[6]; - UINT8 uaSSID[32]; -}tNetappIpconfigRetArgs; - - -/*Ping send report parameters*/ -typedef struct _netapp_pingreport_args -{ - UINT32 packets_sent; - UINT32 packets_received; - UINT32 min_round_time; - UINT32 max_round_time; - UINT32 avg_round_time; -} netapp_pingreport_args_t; - - -//***************************************************************************** -// -//! netapp_config_mac_adrress -//! -//! @param mac device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Configure device MAC address and store it in NVMEM. -//! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved -//! over resets. -// -//***************************************************************************** -extern INT32 netapp_config_mac_adrress( UINT8 *mac ); - -//***************************************************************************** -// -//! netapp_dhcp -//! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, -//! aucIP, aucSubnetMask, aucDefaultGateway must be 0. -//! The default mode of CC3000 is DHCP mode. -//! Note that the configuration is saved in non volatile memory -//! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. -//! -//***************************************************************************** -extern INT32 netapp_dhcp(UINT32 *aucIP, UINT32 *aucSubnetMask,UINT32 *aucDefaultGateway, UINT32 *aucDNSServer); - - - -//***************************************************************************** -// -//! netapp_timeout_values -//! -//! @param aucDHCP DHCP lease time request, also impact -//! the DHCP renew timeout. Range: [0-0xffffffff] seconds, -//! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds. -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 14400 seconds. -//! -//! @param aucARP ARP refresh timeout, if ARP entry is not updated by -//! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. -//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 3600 seconds. -//! -//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout -//! Range: [0-0xffffffff] seconds, 0 == infinity timeout -//! Resolution: 10 seconds. -//! Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 10 seconds. -//! -//! @param aucInactivity Socket inactivity timeout, socket timeout is -//! refreshed by incoming or outgoing packet, by the -//! end of the socket timeout the socket will be closed -//! Range: [0-0xffffffff] sec, 0 == infinity timeout. -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 60 seconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! -//! @note If a parameter set to non zero value which is less than 10s, -//! it will be set automatically to 10s. -//! -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT32 netapp_timeout_values(UINT32 *aucDHCP, UINT32 *aucARP, UINT32 *aucKeepalive, UINT32 *aucInactivity); -#endif - -//***************************************************************************** -// -//! netapp_ping_send -//! -//! @param ip destination IP address -//! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes -//! @param pingTimeout Time to wait for a response,in milliseconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report -//! event will be generated. The report structure is as defined -//! by structure netapp_pingreport_args_t. -//! -//! @warning Calling this function while a previous Ping Requests are in -//! progress will stop the previous ping request. -//***************************************************************************** - - #ifndef CC3000_TINY_DRIVER -extern INT32 netapp_ping_send(UINT32 *ip, UINT32 ulPingAttempts, UINT32 ulPingSize, UINT32 ulPingTimeout); -#endif - -//***************************************************************************** -// -//! netapp_ping_stop -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief Stop any ping request. -//! -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -extern INT32 netapp_ping_stop(); -#endif -//***************************************************************************** -// -//! netapp_ping_report -//! -//! @param none -//! -//! @return none -//! -//! @brief Request for ping status. This API triggers the CC3000 to send -//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. -//! This event will carry the report structure: -//! netapp_pingreport_args_t. This structure is filled in with ping -//! results up till point of triggering API. -//! netapp_pingreport_args_t:\n packets_sent - echo sent, -//! packets_received - echo reply, min_round_time - minimum -//! round time, max_round_time - max round time, -//! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure -//! fields are 0. -//! -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern void netapp_ping_report(); -#endif - - -//***************************************************************************** -// -//! netapp_ipconfig -//! -//! @param[out] ipconfig This argument is a pointer to a -//! tNetappIpconfigRetArgs structure. This structure is -//! filled in with the network interface configuration. -//! tNetappIpconfigRetArgs:\n aucIP - ip address, -//! aucSubnetMask - mask, aucDefaultGateway - default -//! gateway address, aucDHCPServer - dhcp server address -//! aucDNSServer - dns server address, uaMacAddr - mac -//! address, uaSSID - connected AP ssid -//! -//! @return none -//! -//! @brief Obtain the CC3000 Network interface information. -//! Note that the information is available only after the WLAN -//! connection was established. Calling this function before -//! associated, will cause non-defined values to be returned. -//! -//! @note The function is useful for figuring out the IP Configuration of -//! the device when DHCP is used and for figuring out the SSID of -//! the Wireless network the device is associated with. -//! -//***************************************************************************** - -extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ); - - -//***************************************************************************** -// -//! netapp_arp_flush -//! -//! @param none -//! -//! @return none -//! -//! @brief Flushes ARP table -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -extern INT32 netapp_arp_flush(); -#endif - - -//***************************************************************************** -// -//! netapp_set_debug_level -//! -//! @param[in] level debug level. Bitwise [0-8], -//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical -//! message, 1 information message, 2 - core messages, 3 - -//! HCI messages, 4 - Network stack messages, 5 - wlan -//! messages, 6 - wlan driver messages, 7 - epprom messages, -//! 8 - general messages. Default: 0x13f. Saved: no -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Debug messages sent via the UART debug channel, this function -//! enable/disable the debug level -//! -//***************************************************************************** - - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_set_debug_level(UINT32 ulLevel); -#endif -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_NETAPP_H__ - diff --git a/drivers/cc3000/inc/nvmem.h b/drivers/cc3000/inc/nvmem.h deleted file mode 100644 index b99a2e7b9ec5..000000000000 --- a/drivers/cc3000/inc/nvmem.h +++ /dev/null @@ -1,248 +0,0 @@ -/***************************************************************************** -* -* nvmem.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_NVRAM_H__ -#define __CC3000_NVRAM_H__ - -#include "cc3000_common.h" - - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -//***************************************************************************** -// -//! \addtogroup nvmem_api -//! @{ -// -//***************************************************************************** - -/**************************************************************************** -** -** Definitions for File IDs -** -****************************************************************************/ -/* NVMEM file ID - system files*/ -#define NVMEM_NVS_FILEID (0) -#define NVMEM_NVS_SHADOW_FILEID (1) -#define NVMEM_WLAN_CONFIG_FILEID (2) -#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) -#define NVMEM_WLAN_DRIVER_SP_FILEID (4) -#define NVMEM_WLAN_FW_SP_FILEID (5) -#define NVMEM_MAC_FILEID (6) -#define NVMEM_FRONTEND_VARS_FILEID (7) -#define NVMEM_IP_CONFIG_FILEID (8) -#define NVMEM_IP_CONFIG_SHADOW_FILEID (9) -#define NVMEM_BOOTLOADER_SP_FILEID (10) -#define NVMEM_RM_FILEID (11) - -/* NVMEM file ID - user files*/ -#define NVMEM_AES128_KEY_FILEID (12) -#define NVMEM_SHARED_MEM_FILEID (13) - -/* max entry in order to invalid nvmem */ -#define NVMEM_MAX_ENTRY (16) - - -//***************************************************************************** -// -//! nvmem_read -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, -//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, -//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, -//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read -//! @param buff output buffer pointer -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads data from the file referred by the ulFileId parameter. -//! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! -//***************************************************************************** - -extern INT32 nvmem_read(UINT32 file_id, UINT32 length, UINT32 offset, UINT8 *buff); - -//***************************************************************************** -// -//! nvmem_write -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from -//! @param buff data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be -//! marked invalid till the write is done. The file entry doesn't -//! need to be valid - only allocated. -//! -//***************************************************************************** - -extern INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff); - - -//***************************************************************************** -// -//! nvmem_set_mac_address -//! -//! @param mac mac address to be set -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write MAC address to EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** -extern UINT8 nvmem_set_mac_address(UINT8 *mac); - - -//***************************************************************************** -// -//! nvmem_get_mac_address -//! -//! @param[out] mac mac address -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read MAC address from EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** -extern UINT8 nvmem_get_mac_address(UINT8 *mac); - - -//***************************************************************************** -// -//! nvmem_write_patch -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write -//! @param spData SP data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief program a patch to a specific file ID. -//! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is -//! applied in SP_PORTION_SIZE bytes portions. -//! -//***************************************************************************** -extern UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData); - - -//***************************************************************************** -// -//! nvmem_read_sp_version -//! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read patch version. read package version (WiFi FW patch, -//! driver-supplicant-NS patch, bootloader patch) -//! -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern UINT8 nvmem_read_sp_version(UINT8* patchVer); -#endif - -//***************************************************************************** -// -//! nvmem_create_entry -//! -//! @param ulFileId nvmem file Id:\n -//! * NVMEM_AES128_KEY_FILEID: 12 -//! * NVMEM_SHARED_MEM_FILEID: 13 -//! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength -//! -//! @return on success 0, error otherwise. -//! -//! @brief Create new file entry and allocate space on the NVMEM. -//! Applies only to user files. -//! Modify the size of file. -//! If the entry is unallocated - allocate it to size -//! ulNewLen (marked invalid). -//! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - -//! set ulNewLen=0. -//! -//***************************************************************************** -extern INT32 nvmem_create_entry(UINT32 file_id, UINT32 newlen); - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_NVRAM_H__ diff --git a/drivers/cc3000/inc/patch_prog.h b/drivers/cc3000/inc/patch_prog.h deleted file mode 100644 index 0a141a0cb535..000000000000 --- a/drivers/cc3000/inc/patch_prog.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __CC3000_PATCH_PROG_H__ -#define __CC3000_PATCH_PROG_H__ -extern unsigned short fw_length; -extern const unsigned char fw_patch[]; - -extern unsigned short drv_length; -extern const unsigned char wlan_drv_patch[]; -extern const unsigned char cRMdefaultParams[128]; - -void patch_prog_start(); -#endif //__CC3000_PATCH_PROG_H__ diff --git a/drivers/cc3000/inc/security.h b/drivers/cc3000/inc/security.h deleted file mode 100644 index cd1baf55416f..000000000000 --- a/drivers/cc3000/inc/security.h +++ /dev/null @@ -1,130 +0,0 @@ -/***************************************************************************** -* -* security.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_SECURITY__ -#define __CC3000_SECURITY__ - -#include "nvmem.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -#define AES128_KEY_SIZE 16 - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - - -//***************************************************************************** -// -//! aes_encrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief AES128 encryption: -//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes -//! is computed. The AES implementation is in mode ECB (Electronic -//! Code Book). -//! -//! -//***************************************************************************** -extern void aes_encrypt(UINT8 *state, UINT8 *key); - -//***************************************************************************** -// -//! aes_decrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief AES128 decryption: -//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes -//! is computed The AES implementation is in mode ECB -//! (Electronic Code Book). -//! -//! -//***************************************************************************** -extern void aes_decrypt(UINT8 *state, UINT8 *key); - - -//***************************************************************************** -// -//! aes_read_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads AES128 key from EEPROM -//! Reads the AES128 key from fileID #12 in EEPROM -//! returns an error if the key does not exist. -//! -//! -//***************************************************************************** -extern INT32 aes_read_key(UINT8 *key); - -//***************************************************************************** -// -//! aes_write_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief writes AES128 key from EEPROM -//! Writes the AES128 key to fileID #12 in EEPROM -//! -//! -//***************************************************************************** -extern INT32 aes_write_key(UINT8 *key); - -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif diff --git a/drivers/cc3000/inc/socket.h b/drivers/cc3000/inc/socket.h deleted file mode 100644 index 96c814bf77a0..000000000000 --- a/drivers/cc3000/inc/socket.h +++ /dev/null @@ -1,676 +0,0 @@ -/***************************************************************************** -* -* socket.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_SOCKET_H__ -#define __CC3000_SOCKET_H__ - -#include "cc3000_common.h" - -//***************************************************************************** -// -//! \addtogroup socket_api -//! @{ -// -//***************************************************************************** - - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value - -//--------- Address Families -------- - -#define AF_INET 2 -#define AF_INET6 23 - -//------------ Socket Types ------------ - -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers -#define SOCK_RDM 4 -#define SOCK_SEQPACKET 5 - -//----------- Socket Protocol ---------- - -#define IPPROTO_IP 0 // dummy for IP -#define IPPROTO_ICMP 1 // control message protocol -#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP -#define IPPROTO_TCP 6 // tcp -#define IPPROTO_UDP 17 // user datagram protocol -#define IPPROTO_IPV6 41 // IPv6 in IPv6 -#define IPPROTO_NONE 59 // No next header -#define IPPROTO_RAW 255 // raw IP packet -#define IPPROTO_MAX 256 - -//----------- Socket retunr codes ----------- - -#define SOC_ERROR (-1) // error -#define SOC_IN_PROGRESS (-2) // socket in progress - -//----------- Socket Options ----------- -#define SOL_SOCKET 0xffff // socket level -#define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode) -#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout -#define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode) -#define SOCK_ON 0 // socket non-blocking mode is enabled -#define SOCK_OFF 1 // socket blocking mode is enabled - -#define MAX_PACKET_SIZE 1500 -#define MAX_LISTEN_QUEUE 4 - -#define IOCTL_SOCKET_EVENTMASK - -#define ENOBUFS 55 // No buffer space available - -#define __FD_SETSIZE 32 - -#define ASIC_ADDR_LEN 8 - -#define NO_QUERY_RECIVED -3 - - -typedef struct _in_addr_t -{ - UINT32 s_addr; // load with inet_aton() -} in_addr; - -typedef struct _sockaddr_t -{ - UINT16 sa_family; - UINT8 sa_data[14]; -} sockaddr; - -typedef struct _sockaddr_in_t -{ - INT16 sin_family; // e.g. AF_INET - UINT16 sin_port; // e.g. htons(3490) - in_addr sin_addr; // see struct in_addr, below - CHAR sin_zero[8]; // zero this if you want to -} sockaddr_in; - -typedef UINT32 socklen_t; - -// The fd_set member is required to be an array of INT32s. -typedef INT32 __fd_mask; - -// It's easier to assume 8-bit bytes than to get CHAR_BIT. -#define __NFDBITS (8 * sizeof (__fd_mask)) -#define __FDELT(d) ((d) / __NFDBITS) -#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) - -// fd_set for select and pselect. -typedef struct -{ - __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; -#define __FDS_BITS(set) ((set)->fds_bits) -} fd_set; - -// We don't use `memset' because this would require a prototype and -// the array isn't too big. -#define __FD_ZERO(set) \ - do { \ - UINT16 __i; \ - fd_set *__arr = (set); \ - for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ - __FDS_BITS (__arr)[__i] = 0; \ - } while (0) -#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) -#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d)) -#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d)) - -// Access macros for 'fd_set'. -#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) -#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) -#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) -#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) - -//Use in case of Big Endian only - -#define htonl(A) ((((UINT32)(A) & 0xff000000) >> 24) | \ - (((UINT32)(A) & 0x00ff0000) >> 8) | \ - (((UINT32)(A) & 0x0000ff00) << 8) | \ - (((UINT32)(A) & 0x000000ff) << 24)) - -#define ntohl htonl - -//Use in case of Big Endian only -#define htons(A) ((((UINT32)(A) & 0xff00) >> 8) | \ - (((UINT32)(A) & 0x00ff) << 8)) - - -#define ntohs htons - -// mDNS port - 5353 mDNS multicast address - 224.0.0.251 -#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \ - sockaddr.sa_data[1] = 0xe9; \ - sockaddr.sa_data[2] = 0xe0; \ - sockaddr.sa_data[3] = 0x0; \ - sockaddr.sa_data[4] = 0x0; \ - sockaddr.sa_data[5] = 0xfb; - - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -//***************************************************************************** -// -//! socket -//! -//! @param domain selects the protocol family which will be used for -//! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version -//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are -//! supported. -//! -//! @return On success, socket handle that is used for consequent socket -//! operations. On error, -1 is returned. -//! -//! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the -//! application layer to obtain a socket handle. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(socket)(INT32 domain, INT32 type, INT32 protocol); - -//***************************************************************************** -// -//! closesocket -//! -//! @param sd socket handle. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief The socket function closes a created socket. -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(closesocket)(INT32 sd); - -//***************************************************************************** -// -//! accept -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. -//! On this version only AF_INET is supported. -//! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: -//! it should initially contain the size of the structure -//! pointed to by addr. -//! -//! @return For socket in blocking mode: -//! On success, socket handle. on failure negative -//! For socket in non-blocking mode: -//! - On connection establishment, socket handle -//! - On connection pending, SOC_IN_PROGRESS (-2) -//! - On failure, SOC_ERROR (-1) -//! -//! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the -//! queue of pending connections, creates a new connected socket, and -//! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. -//! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the -//! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the -//! socket's address family. The addrlen argument is a value-result -//! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual -//! length (in bytes) of the address returned. -//! -//! @sa socket ; bind ; listen -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(accept)(INT32 sd, sockaddr *addr, socklen_t *addrlen); - -//***************************************************************************** -// -//! bind -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief assign a name to a socket -//! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address -//! family) but has no name assigned. -//! It is necessary to assign a local address before a SOCK_STREAM -//! socket may receive connections. -//! -//! @sa socket ; accept ; listen -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(bind)(INT32 sd, const sockaddr *addr, INT32 addrlen); - -//***************************************************************************** -// -//! listen -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] backlog specifies the listen queue depth. On this version -//! backlog is not supported. -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief listen for connections on a socket -//! The willingness to accept incoming connections and a queue -//! limit for incoming connections are specified with listen(), -//! and then the connections are accepted with accept. -//! The listen() call applies only to sockets of type SOCK_STREAM -//! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. -//! -//! @sa socket ; accept ; bind -//! -//! @note On this version, backlog is not supported -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(listen)(INT32 sd, INT32 backlog); - -//***************************************************************************** -// -//! gethostbyname -//! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. -//! @return On success, positive is returned. On error, negative is returned -//! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, -//! by its name. -//! -//! @note On this version, only blocking mode is supported. Also note that -//! the function requires DNS server to be configured prior to its usage. -// -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT16 CC3000_EXPORT(gethostbyname)(CHAR * hostname, UINT16 usNameLen, UINT32* out_ip_addr); -#endif - - -//***************************************************************************** -// -//! connect -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] addr specifies the destination addr. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is -//! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by -//! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection -//! establishment or for the connection establishment failure. -//! -//! @sa socket -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(connect)(INT32 sd, const sockaddr *addr, INT32 addrlen); - -//***************************************************************************** -// -//! select -//! -//! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. -//! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring -//! @param[out] exceptsds socket descriptors list for exception monitoring -//! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity -//! timeout. The minimum timeout is 5 milliseconds, -//! less than 5 milliseconds will be set -//! automatically to 5 milliseconds. -//! @return On success, select() returns the number of file descriptors -//! contained in the three returned descriptor sets (that is, the -//! total number of bits that are set in readfds, writefds, -//! exceptfds) which may be zero if the timeout expires before -//! anything interesting happens. -//! On error, -1 is returned. -//! *readsds - return the sockets on which Read request will -//! return without delay with valid data. -//! *writesds - return the sockets on which Write request -//! will return without delay. -//! *exceptsds - return the sockets which closed recently. -//! -//! @brief Monitor socket activity -//! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation -//! -//! @Note If the timeout value set to less than 5ms it will automatically set -//! to 5ms to prevent overload of the system -//! -//! @sa socket -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(select)(INT32 nfds, fd_set *readsds, fd_set *writesds, - fd_set *exceptsds, struct cc3000_timeval *timeout); - -//***************************************************************************** -// -//! setsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[in] optval specifies a value for the option -//! @param[in] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa getsockopt -// -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT16 CC3000_EXPORT(setsockopt)(INT32 sd, INT32 level, INT32 optname, const void *optval, - socklen_t optlen); -#endif -//***************************************************************************** -// -//! getsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[out] optval specifies a value for the option -//! @param[out] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa setsockopt -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(getsockopt)(INT32 sd, INT32 level, INT32 optname, void *optval, - socklen_t *optlen); - -//***************************************************************************** -// -//! recv -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief function receives a message from a connection-mode socket -//! -//! @sa recvfrom -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(recv)(INT32 sd, void *buf, INT32 len, INT32 flags); - -//***************************************************************************** -// -//! recvfrom -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! @param[in] from pointer to an address structure indicating the source -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param[in] fromlen source address structure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief read data from socket -//! function receives a message from a connection-mode or -//! connectionless-mode socket. Note that raw sockets are not -//! supported. -//! -//! @sa recv -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(recvfrom)(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from, - socklen_t *fromlen); - -//***************************************************************************** -// -//! send -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa sendto -// -//***************************************************************************** - -extern INT16 CC3000_EXPORT(send)(INT32 sd, const void *buf, INT32 len, INT32 flags); - -//***************************************************************************** -// -//! sendto -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating the destination -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa send -// -//***************************************************************************** - -extern INT16 CC3000_EXPORT(sendto)(INT32 sd, const void *buf, INT32 len, INT32 flags, - const sockaddr *to, socklen_t tolen); - -//***************************************************************************** -// -//! mdnsAdvertiser -//! -//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature -//! @param[in] deviceServiceName Service name as part of the published -//! canonical domain name -//! @param[in] deviceServiceNameLength Length of the service name - up to 32 chars -//! -//! -//! @return On success, zero is returned, return SOC_ERROR if socket was not -//! opened successfully, or if an error occurred. -//! -//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(mdnsAdvertiser)(UINT16 mdnsEnabled, CHAR * deviceServiceName, UINT16 deviceServiceNameLength); - - -//***************************************************************************** -// -//! getmssvalue -//! -//! @param[in] sd socket descriptor -//! -//! @return On success, returns the MSS value of a TCP connection -//! -//! @brief Returns the MSS value of a TCP connection according to the socket descriptor -// -//***************************************************************************** -extern UINT16 CC3000_EXPORT(getmssvalue) (INT32 sd); - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SOCKET_H__ diff --git a/drivers/cc3000/inc/wlan.h b/drivers/cc3000/inc/wlan.h deleted file mode 100644 index 48d195b32ae8..000000000000 --- a/drivers/cc3000/inc/wlan.h +++ /dev/null @@ -1,518 +0,0 @@ -/***************************************************************************** -* -* wlan.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_WLAN_H__ -#define __CC3000_WLAN_H__ - -#include "cc3000_common.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -#define WLAN_SEC_UNSEC (0) -#define WLAN_SEC_WEP (1) -#define WLAN_SEC_WPA (2) -#define WLAN_SEC_WPA2 (3) -//***************************************************************************** -// -//! \addtogroup wlan_api -//! @{ -// -//***************************************************************************** - - -//***************************************************************************** -// -//! wlan_init -//! -//! @param sWlanCB Asynchronous events callback. -//! 0 no event call back. -//! -call back parameters: -//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR -//! HCI_EVNT_WLAN_KEEPALIVE keepalive. -//! 2) data: pointer to extra data that received by the event -//! (NULL no data). -//! 3) length: data length. -//! -Events with extra data: -//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, -//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes -//! for DNS server. -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, -//! 4 bytes Packets received, 4 bytes Min round time, -//! 4 bytes Max round time and 4 bytes for Avg round time. -//! -//! @param sFWPatches 0 no patch or pointer to FW patches -//! @param sDriverPatches 0 no patch or pointer to driver patches -//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches -//! @param sReadWlanInterruptPin init callback. the callback read wlan -//! interrupt status. -//! @param sWlanInterruptEnable init callback. the callback enable wlan -//! interrupt. -//! @param sWlanInterruptDisable init callback. the callback disable wlan -//! interrupt. -//! @param sWriteWlanPin init callback. the callback write value -//! to device pin. -//! -//! @return none -//! -//! @sa wlan_set_event_mask , wlan_start , wlan_stop -//! -//! @brief Initialize wlan driver -//! -//! @warning This function must be called before ANY other wlan driver function -// -//***************************************************************************** -extern void wlan_init( tWlanCB sWlanCB, - tFWPatches sFWPatches, - tDriverPatches sDriverPatches, - tBootLoaderPatches sBootLoaderPatches, - tWlanReadInteruptPin sReadWlanInterruptPin, - tWlanInterruptEnable sWlanInterruptEnable, - tWlanInterruptDisable sWlanInterruptDisable, - tWriteWlanPin sWriteWlanPin); - - - -//***************************************************************************** -// -//! wlan_start -//! -//! @param usPatchesAvailableAtHost - flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Start WLAN device. This function asserts the enable pin of -//! the device (WLAN_EN), starting the HW initialization process. -//! The function blocked until device Initialization is completed. -//! Function also configure patches (FW, driver or bootloader) -//! and calls appropriate device callbacks. -//! -//! @Note Prior calling the function wlan_init shall be called. -//! @Warning This function must be called after wlan_init and before any -//! other wlan API -//! @sa wlan_init , wlan_stop -//! -// -//***************************************************************************** -extern int wlan_start(UINT16 usPatchesAvailableAtHost); - -//***************************************************************************** -// -//! wlan_stop -//! -//! @param none -//! -//! @return none -//! -//! @brief Stop WLAN device by putting it into reset state. -//! -//! @sa wlan_start -// -//***************************************************************************** -extern void wlan_stop(void); - -//***************************************************************************** -// -//! wlan_connect -//! -//! @param sec_type security options: -//! WLAN_SEC_UNSEC, -//! WLAN_SEC_WEP (ASCII support only), -//! WLAN_SEC_WPA or WLAN_SEC_WPA2 -//! @param ssid up to 32 bytes and is ASCII SSID of the AP -//! @param ssid_len length of the SSID -//! @param bssid 6 bytes specified the AP bssid -//! @param key up to 32 bytes specified the AP security key -//! @param key_len key length -//! -//! @return On success, zero is returned. On error, negative is returned. -//! Note that even though a zero is returned on success to trigger -//! connection operation, it does not mean that CCC3000 is already -//! connected. An asynchronous "Connected" event is generated when -//! actual association process finishes and CC3000 is connected to -//! the AP. If DHCP is set, An asynchronous "DHCP" event is -//! generated when DHCP process is finish. -//! -//! -//! @brief Connect to AP -//! @warning Please Note that when connection to AP configured with security -//! type WEP, please confirm that the key is set as ASCII and not -//! as HEX. -//! @sa wlan_disconnect -// -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT32 wlan_connect(UINT32 ulSecType, CHAR *ssid, INT32 ssid_len, - UINT8 *bssid, UINT8 *key, INT32 key_len); -#else -extern INT32 wlan_connect(CHAR *ssid, INT32 ssid_len); - -#endif - -//***************************************************************************** -// -//! wlan_disconnect -//! -//! @return 0 disconnected done, other CC3000 already disconnected -//! -//! @brief Disconnect connection from AP. -//! -//! @sa wlan_connect -// -//***************************************************************************** - -extern INT32 wlan_disconnect(void); - -//***************************************************************************** -// -//! wlan_add_profile -//! -//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 -//! @param ucSsid ssid SSID up to 32 bytes -//! @param ulSsidLen ssid length -//! @param ucBssid bssid 6 bytes -//! @param ulPriority ulPriority profile priority. Lowest priority:0. -//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security -//! @param ulGroupCipher_TxKeyIndex key index -//! @param ulKeyMgmt KEY management -//! @param ucPf_OrKey security key -//! @param ulPassPhraseLen security key length for WPA\WPA2 -//! -//! @return On success, index (1-7) of the stored profile is returned. -//! On error, -1 is returned. -//! -//! @brief When auto start is enabled, the device connects to -//! station from the profiles table. Up to 7 profiles are supported. -//! If several profiles configured the device choose the highest -//! priority profile, within each priority group, device will choose -//! profile based on security policy, signal strength, etc -//! parameters. All the profiles are stored in CC3000 NVMEM. -//! -//! @sa wlan_ioctl_del_profile -// -//***************************************************************************** - -extern INT32 wlan_add_profile(UINT32 ulSecType, UINT8* ucSsid, - UINT32 ulSsidLen, - UINT8 *ucBssid, - UINT32 ulPriority, - UINT32 ulPairwiseCipher_Or_Key, - UINT32 ulGroupCipher_TxKeyLen, - UINT32 ulKeyMgmt, - UINT8* ucPf_OrKey, - UINT32 ulPassPhraseLen); - - - -//***************************************************************************** -// -//! wlan_ioctl_del_profile -//! -//! @param index number of profile to delete -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Delete WLAN profile -//! -//! @Note In order to delete all stored profile, set index to 255. -//! -//! @sa wlan_add_profile -// -//***************************************************************************** -extern INT32 wlan_ioctl_del_profile(UINT32 ulIndex); - -//***************************************************************************** -// -//! wlan_set_event_mask -//! -//! @param mask mask option: -//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done -//! HCI_EVNT_WLAN_UNSOL_INIT init done -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report -//! HCI_EVNT_WLAN_KEEPALIVE keepalive -//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission -//! Saved: no. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Mask event according to bit mask. In case that event is -//! masked (1), the device will not send the masked event to host. -// -//***************************************************************************** -extern INT32 wlan_set_event_mask(UINT32 ulMask); - -//***************************************************************************** -// -//! wlan_ioctl_statusget -//! -//! @param none -//! -//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, -//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED -//! -//! @brief get wlan status: disconnected, scanning, connecting or connected -// -//***************************************************************************** -extern INT32 wlan_ioctl_statusget(void); - - -//***************************************************************************** -// -//! wlan_ioctl_set_connection_policy -//! -//! @param should_connect_to_open_ap enable(1), disable(0) connect to any -//! available AP. This parameter corresponds to the configuration of -//! item # 3 in the brief description. -//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries -//! to connect to the last connected AP. This parameter corresponds -//! to the configuration of item # 1 in the brief description. -//! @param auto_start enable(1), disable(0) auto connect -//! after reset and periodically reconnect if needed. This -//! configuration configures option 2 in the above description. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief When auto is enabled, the device tries to connect according -//! the following policy: -//! 1) If fast connect is enabled and last connection is valid, -//! the device will try to connect to it without the scanning -//! procedure (fast). The last connection will be marked as -//! invalid, due to adding/removing profile. -//! 2) If profile exists, the device will try to connect it -//! (Up to seven profiles). -//! 3) If fast and profiles are not found, and open mode is -//! enabled, the device will try to connect to any AP. -//! * Note that the policy settings are stored in the CC3000 NVMEM. -//! -//! @sa wlan_add_profile , wlan_ioctl_del_profile -// -//***************************************************************************** -extern INT32 wlan_ioctl_set_connection_policy( - UINT32 should_connect_to_open_ap, - UINT32 should_use_fast_connect, - UINT32 ulUseProfiles); - -//***************************************************************************** -// -//! wlan_ioctl_get_scan_results -//! -//! @param[in] scan_timeout parameter not supported -//! @param[out] ucResults scan result (_wlan_full_scan_results_args_t) -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Gets entry from scan result table. -//! The scan results are returned one by one, and each entry -//! represents a single AP found in the area. The following is a -//! format of the scan result: -//! - 4 Bytes: number of networks found -//! - 4 Bytes: The status of the scan: 0 - aged results, -//! 1 - results valid, 2 - no results -//! - 42 bytes: Result entry, where the bytes are arranged as follows: -//! -//! - 1 bit isValid - is result valid or not -//! - 7 bits rssi - RSSI value; -//! - 2 bits: securityMode - security mode of the AP: -//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 -//! - 6 bits: SSID name length -//! - 2 bytes: the time at which the entry has entered into -//! scans result table -//! - 32 bytes: SSID name -//! - 6 bytes: BSSID -//! -//! @Note scan_timeout, is not supported on this version. -//! -//! @sa wlan_ioctl_set_scan_params -// -//***************************************************************************** - - -extern INT32 wlan_ioctl_get_scan_results(UINT32 ulScanTimeout, - UINT8 *ucResults); - -//***************************************************************************** -// -//! wlan_ioctl_set_scan_params -//! -//! @param uiEnable - start/stop application scan: -//! 1 = start scan with default interval value of 10 min. -//! in order to set a different scan interval value apply the value -//! in milliseconds. minimum 1 second. 0=stop). Wlan reset -//! (wlan_stop() wlan_start()) is needed when changing scan interval -//! value. Saved: No -//! @param uiMinDwellTime minimum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 20) -//! @param uiMaxDwellTime maximum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 30) -//! @param uiNumOfProbeRequests max probe request between dwell time. -//! Saved: yes. Recommended Value: 5 (Default:2) -//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). -//! Saved: yes. Default: 0x7ff -//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) -//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) -//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) -//! @param aiIntervalList pointer to array with 16 entries (16 channels) -//! each entry (UINT32) holds timeout between periodic scan -//! (connection scan) - in milliseconds. Saved: yes. Default 2000ms. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief start and stop scan procedure. Set scan parameters. -//! -//! @Note uiDefaultTxPower, is not supported on this version. -//! -//! @sa wlan_ioctl_get_scan_results -// -//***************************************************************************** -extern INT32 wlan_ioctl_set_scan_params(UINT32 uiEnable, UINT32 - uiMinDwellTime,UINT32 uiMaxDwellTime, - UINT32 uiNumOfProbeRequests, - UINT32 uiChannelMask, - INT32 iRSSIThreshold,UINT32 uiSNRThreshold, - UINT32 uiDefaultTxPower, - UINT32 *aiIntervalList); - - -//***************************************************************************** -// -//! wlan_smart_config_start -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Start to acquire device profile. The device acquire its own -//! profile, if profile message is found. The acquired AP information -//! is stored in CC3000 EEPROM only in case AES128 encryption is used. -//! In case AES128 encryption is not used, a profile is created by -//! CC3000 internally. -//! -//! @Note An asynchronous event - Smart Config Done will be generated as soon -//! as the process finishes successfully. -//! -//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop -// -//***************************************************************************** -extern INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag); - - -//***************************************************************************** -// -//! wlan_smart_config_stop -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Stop the acquire profile procedure -//! -//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix -// -//***************************************************************************** -extern INT32 wlan_smart_config_stop(void); - -//***************************************************************************** -// -//! wlan_smart_config_set_prefix -//! -//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Configure station ssid prefix. The prefix is used internally -//! in CC3000. It should always be TTT. -//! -//! @Note The prefix is stored in CC3000 NVMEM -//! -//! @sa wlan_smart_config_start , wlan_smart_config_stop -// -//***************************************************************************** -extern INT32 wlan_smart_config_set_prefix(CHAR* cNewPrefix); - -//***************************************************************************** -// -//! wlan_smart_config_process -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief process the acquired data and store it as a profile. The acquired -//! AP information is stored in CC3000 EEPROM encrypted. -//! The encrypted data is decrypted and stored as a profile. -//! behavior is as defined by connection policy. -// -//***************************************************************************** -extern INT32 wlan_smart_config_process(void); - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_WLAN_H__ diff --git a/drivers/cc3000/src/cc3000_common.c b/drivers/cc3000/src/cc3000_common.c deleted file mode 100644 index b4c87848cf47..000000000000 --- a/drivers/cc3000/src/cc3000_common.c +++ /dev/null @@ -1,164 +0,0 @@ -/***************************************************************************** -* -* cc3000_common.c.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -//***************************************************************************** -// -//! \addtogroup common_api -//! @{ -// -//***************************************************************************** -/****************************************************************************** -* -* Include files -* -*****************************************************************************/ - -#include "cc3000_common.h" -#include "socket.h" -#include "wlan.h" -#include "evnt_handler.h" - -//***************************************************************************** -// -//! __error__ -//! -//! @param pcFilename - file name, where error occurred -//! @param ulLine - line number, where error occurred -//! -//! @return none -//! -//! @brief stub function for ASSERT macro -// -//***************************************************************************** -void __error__(CHAR *pcFilename, UINT32 ulLine) -{ - //TODO full up function -} - - - -//***************************************************************************** -// -//! UINT32_TO_STREAM_f -//! -//! @param p pointer to the new stream -//! @param u32 pointer to the 32 bit -//! -//! @return pointer to the new stream -//! -//! @brief This function is used for copying 32 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32) -{ - *(p)++ = (UINT8)(u32); - *(p)++ = (UINT8)((u32) >> 8); - *(p)++ = (UINT8)((u32) >> 16); - *(p)++ = (UINT8)((u32) >> 24); - return p; -} - -//***************************************************************************** -// -//! UINT16_TO_STREAM_f -//! -//! @param p pointer to the new stream -//! @param u32 pointer to the 16 bit -//! -//! @return pointer to the new stream -//! -//! @brief This function is used for copying 16 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16) -{ - *(p)++ = (UINT8)(u16); - *(p)++ = (UINT8)((u16) >> 8); - return p; -} - -//***************************************************************************** -// -//! STREAM_TO_UINT16_f -//! -//! @param p pointer to the stream -//! @param offset offset in the stream -//! -//! @return pointer to the new 16 bit -//! -//! @brief This function is used for copying received stream to -//! 16 bit in little endian format. -// -//***************************************************************************** - -UINT16 STREAM_TO_UINT16_f(CHAR* p, UINT16 offset) -{ - return (UINT16)((UINT16)((UINT16) - (*(p + offset + 1)) << 8) + (UINT16)(*(p + offset))); -} - -//***************************************************************************** -// -//! STREAM_TO_UINT32_f -//! -//! @param p pointer to the stream -//! @param offset offset in the stream -//! -//! @return pointer to the new 32 bit -//! -//! @brief This function is used for copying received stream to -//! 32 bit in little endian format. -// -//***************************************************************************** - -UINT32 STREAM_TO_UINT32_f(CHAR* p, UINT16 offset) -{ - return (UINT32)((UINT32)((UINT32) - (*(p + offset + 3)) << 24) + (UINT32)((UINT32) - (*(p + offset + 2)) << 16) + (UINT32)((UINT32) - (*(p + offset + 1)) << 8) + (UINT32)(*(p + offset))); -} - - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/ccspi.c b/drivers/cc3000/src/ccspi.c deleted file mode 100644 index 1dcd61884086..000000000000 --- a/drivers/cc3000/src/ccspi.c +++ /dev/null @@ -1,455 +0,0 @@ -/***************************************************************************** - * - * spi.c - CC3000 Host Driver Implementation. - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include - -#include "py/runtime.h" -#include "pin.h" -#include "led.h" -#include "extint.h" -#include "spi.h" -#include "ccspi.h" -#include "evnt_handler.h" - -#if 0 // print debugging info -#include -#define DEBUG_printf(args...) printf(args) -#else // don't print debugging info -#define DEBUG_printf(args...) (void)0 -#endif - -// these need to be set to valid values before anything in this file will work -STATIC const spi_t *SPI_HANDLE = NULL; -STATIC const pin_obj_t *PIN_CS = NULL; -STATIC const pin_obj_t *PIN_EN = NULL; -STATIC const pin_obj_t *PIN_IRQ = NULL; - -#define CS_LOW() HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_RESET) -#define CS_HIGH() HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET) - -#define READ 3 -#define WRITE 1 - -#define HI(value) (((value) & 0xFF00) >> 8) -#define LO(value) ((value) & 0x00FF) - -#define SPI_TIMEOUT (1000) -#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5) - -/* SPI bus states */ -#define eSPI_STATE_POWERUP (0) -#define eSPI_STATE_INITIALIZED (1) -#define eSPI_STATE_IDLE (2) -#define eSPI_STATE_WRITE_IRQ (3) -#define eSPI_STATE_WRITE_FIRST_PORTION (4) -#define eSPI_STATE_WRITE_EOT (5) -#define eSPI_STATE_READ_IRQ (6) -#define eSPI_STATE_READ_FIRST_PORTION (7) -#define eSPI_STATE_READ_EOT (8) - -// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) -// for the purpose of detection of the overrun. The location of the memory where the magic number -// resides shall never be written. In case it is written - the overrun occured and either recevie function -// or send function will stuck forever. -#define CC3000_BUFFER_MAGIC_NUMBER (0xDE) - -typedef struct { - gcSpiHandleRx SPIRxHandler; - unsigned short usTxPacketLength; - unsigned short usRxPacketLength; - unsigned long ulSpiState; - unsigned char *pTxPacket; - unsigned char *pRxPacket; -} tSpiInformation; -STATIC tSpiInformation sSpiInformation; - -STATIC char spi_buffer[CC3000_RX_BUFFER_SIZE]; -unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE]; - -STATIC const mp_obj_fun_builtin_fixed_t irq_callback_obj; - -// set the pins to use to communicate with the CC3000 -// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef* -void SpiInit(void *spi, const void *pin_cs, const void *pin_en, const void *pin_irq) { - SPI_HANDLE = spi; - PIN_CS = pin_cs; - PIN_EN = pin_en; - PIN_IRQ = pin_irq; -} - -void SpiClose(void) -{ - if (sSpiInformation.pRxPacket) { - sSpiInformation.pRxPacket = 0; - } - - tSLInformation.WlanInterruptDisable(); - - //HAL_SPI_DeInit(SPI_HANDLE); -} - -void SpiOpen(gcSpiHandleRx pfRxHandler) -{ - DEBUG_printf("SpiOpen\n"); - - /* initialize SPI state */ - sSpiInformation.ulSpiState = eSPI_STATE_POWERUP; - sSpiInformation.SPIRxHandler = pfRxHandler; - sSpiInformation.usTxPacketLength = 0; - sSpiInformation.pTxPacket = NULL; - sSpiInformation.pRxPacket = (unsigned char *)spi_buffer; - sSpiInformation.usRxPacketLength = 0; - spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - - /* SPI configuration */ - SPI_InitTypeDef *init = &SPI_HANDLE->spi->Init; - init->Mode = SPI_MODE_MASTER; - init->Direction = SPI_DIRECTION_2LINES; - init->DataSize = SPI_DATASIZE_8BIT; - init->CLKPolarity = SPI_POLARITY_LOW; - init->CLKPhase = SPI_PHASE_2EDGE; - init->NSS = SPI_NSS_SOFT; - init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; - init->FirstBit = SPI_FIRSTBIT_MSB; - init->TIMode = SPI_TIMODE_DISABLED; - init->CRCCalculation = SPI_CRCCALCULATION_DISABLED; - init->CRCPolynomial = 7; - spi_init(SPI_HANDLE, false); - - // configure wlan CS and EN pins - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Speed = GPIO_SPEED_FAST; - GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Alternate = 0; - - GPIO_InitStructure.Pin = PIN_CS->pin_mask; - HAL_GPIO_Init(PIN_CS->gpio, &GPIO_InitStructure); - - GPIO_InitStructure.Pin = PIN_EN->pin_mask; - HAL_GPIO_Init(PIN_EN->gpio, &GPIO_InitStructure); - - HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET); - HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, GPIO_PIN_RESET); - - /* do a dummy read, this ensures SCLK is low before - actual communications start, it might be required */ - CS_LOW(); - uint8_t buf[1]; - HAL_SPI_Receive(SPI_HANDLE->spi, buf, sizeof(buf), SPI_TIMEOUT); - CS_HIGH(); - - // register EXTI - extint_register((mp_obj_t)PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true); - extint_enable(PIN_IRQ->pin); - - DEBUG_printf("SpiOpen finished; IRQ.pin=%d IRQ_LINE=%d\n", PIN_IRQ->pin, PIN_IRQ->pin); -} - -long ReadWlanInterruptPin(void) -{ - return HAL_GPIO_ReadPin(PIN_IRQ->gpio, PIN_IRQ->pin_mask); -} - -void WriteWlanPin(unsigned char val) -{ - HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, - (WLAN_ENABLE)? GPIO_PIN_SET:GPIO_PIN_RESET); -} - -STATIC void SpiWriteDataSynchronous(unsigned char *data, unsigned short size) -{ - DEBUG_printf("SpiWriteDataSynchronous(data=%p [%x %x %x %x], size=%u)\n", data, data[0], data[1], data[2], data[3], size); - __disable_irq(); - if (HAL_SPI_TransmitReceive(SPI_HANDLE->spi, data, data, size, SPI_TIMEOUT) != HAL_OK) { - //BREAK(); - } - __enable_irq(); - DEBUG_printf(" - rx data = [%x %x %x %x]\n", data[0], data[1], data[2], data[3]); -} - -STATIC void SpiReadDataSynchronous(unsigned char *data, unsigned short size) -{ - memset(data, READ, size); - __disable_irq(); - if (HAL_SPI_TransmitReceive(SPI_HANDLE->spi, data, data, size, SPI_TIMEOUT) != HAL_OK) { - //BREAK(); - } - __enable_irq(); -} - -STATIC void __delay_cycles(volatile int x) -{ - x *= 6; // for 168 MHz CPU - while (x--); -} - -STATIC long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) -{ - DEBUG_printf("SpiFirstWrite %lu\n", sSpiInformation.ulSpiState); - - CS_LOW(); - - // Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles; - __delay_cycles(1200); - - // SPI writes first 4 bytes of data - SpiWriteDataSynchronous(ucBuf, 4); - - __delay_cycles(1200); - - SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); - - // From this point on - operate in a regular way - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - CS_HIGH(); - - return(0); -} - -long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) -{ - DEBUG_printf("SpiWrite %lu\n", sSpiInformation.ulSpiState); - - unsigned char ucPad = 0; - - // Figure out the total length of the packet in order to figure out if there - // is padding or not - if(!(usLength & 0x0001)) { - ucPad++; - } - - pUserBuffer[0] = WRITE; - pUserBuffer[1] = HI(usLength + ucPad); - pUserBuffer[2] = LO(usLength + ucPad); - pUserBuffer[3] = 0; - pUserBuffer[4] = 0; - - usLength += (SPI_HEADER_SIZE + ucPad); - - // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) - // for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun - // occurred - and we will stuck here forever! - if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { - while (1); - } - - if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { - while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED); - } - - if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED) { - // This is time for first TX/RX transactions over SPI: - // the IRQ is down - so need to send read buffer size command - SpiFirstWrite(pUserBuffer, usLength); - } else { - // - // We need to prevent here race that can occur in case 2 back to back packets are sent to the - // device, so the state will move to IDLE and once again to not IDLE due to IRQ - // - tSLInformation.WlanInterruptDisable(); - - while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE); - - sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ; - sSpiInformation.pTxPacket = pUserBuffer; - sSpiInformation.usTxPacketLength = usLength; - - // Assert the CS line and wait till SSI IRQ line is active and then initialize write operation - CS_LOW(); - - // Re-enable IRQ - if it was not disabled - this is not a problem... - tSLInformation.WlanInterruptEnable(); - - // check for a missing interrupt between the CS assertion and enabling back the interrupts - if (tSLInformation.ReadWlanInterruptPin() == 0) { - SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - CS_HIGH(); - } - } - - // Due to the fact that we are currently implementing a blocking situation - // here we will wait till end of transaction - while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState); - - return(0); -} - -#if 0 -unused -STATIC void SpiReadPacket(void) -{ - int length; - - /* read SPI header */ - SpiReadDataSynchronous(sSpiInformation.pRxPacket, SPI_HEADER_SIZE); - - /* parse data length */ - STREAM_TO_UINT8(sSpiInformation.pRxPacket, SPI_HEADER_SIZE-1, length); - - /* read the remainder of the packet */ - SpiReadDataSynchronous(sSpiInformation.pRxPacket + SPI_HEADER_SIZE, length); - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; -} -#endif - -STATIC void SpiReadHeader(void) -{ - SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10); -} - -STATIC void SpiTriggerRxProcessing(void) -{ - SpiPauseSpi(); - CS_HIGH(); - - // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) - // for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun - // occurred - and we will stuck here forever! - if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { - while (1); - } - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE); -} - - -STATIC long SpiReadDataCont(void) -{ - long data_to_recv=0; - unsigned char *evnt_buff, type; - - //determine what type of packet we have - evnt_buff = sSpiInformation.pRxPacket; - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type); - - switch (type) { - case HCI_TYPE_DATA:{ - // We need to read the rest of data.. - STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), - HCI_DATA_LENGTH_OFFSET, data_to_recv); - if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) { - data_to_recv++; - } - - if (data_to_recv) { - SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); - } - break; - } - case HCI_TYPE_EVNT: { - // Calculate the rest length of the data - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), - HCI_EVENT_LENGTH_OFFSET, data_to_recv); - data_to_recv -= 1; - - // Add padding byte if needed - if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) { - data_to_recv++; - } - - if (data_to_recv) { - SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); - } - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - break; - } - } - - return 0; -} - -STATIC void SSIContReadOperation(void) -{ - // The header was read - continue with the payload read - if (!SpiReadDataCont()) { - /* All the data was read - finalize handling by switching - to the task and calling from task Event Handler */ - SpiTriggerRxProcessing(); - } -} - -STATIC mp_obj_t irq_callback(mp_obj_t line) { - DEBUG_printf("<< IRQ; state=%lu >>\n", sSpiInformation.ulSpiState); - switch (sSpiInformation.ulSpiState) { - case eSPI_STATE_POWERUP: - /* This means IRQ line was low call a callback of HCI Layer to inform on event */ - DEBUG_printf(" - POWERUP\n"); - sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; - break; - case eSPI_STATE_IDLE: - DEBUG_printf(" - IDLE\n"); - sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; - - /* IRQ line goes down - we are start reception */ - CS_LOW(); - - // Wait for TX/RX Compete which will come as DMA interrupt - SpiReadHeader(); - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - - SSIContReadOperation(); - break; - case eSPI_STATE_WRITE_IRQ: - DEBUG_printf(" - WRITE IRQ\n"); - SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - CS_HIGH(); - break; - } - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(irq_callback_obj, irq_callback); - -void SpiPauseSpi(void) { - DEBUG_printf("SpiPauseSpi\n"); - extint_disable(PIN_IRQ->pin); -} - -void SpiResumeSpi(void) { - DEBUG_printf("SpiResumeSpi\n"); - extint_enable(PIN_IRQ->pin); -} diff --git a/drivers/cc3000/src/evnt_handler.c b/drivers/cc3000/src/evnt_handler.c deleted file mode 100644 index d430bbfdad55..000000000000 --- a/drivers/cc3000/src/evnt_handler.c +++ /dev/null @@ -1,849 +0,0 @@ -/***************************************************************************** -* -* evnt_handler.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -//***************************************************************************** -// -//! \addtogroup evnt_handler_api -//! @{ -// -//****************************************************************************** - -//****************************************************************************** -// INCLUDE FILES -//****************************************************************************** - -#include "cc3000_common.h" -#include "string.h" -#include "hci.h" -#include "evnt_handler.h" -#include "wlan.h" -#include "socket.h" -#include "netapp.h" -#include "ccspi.h" - - - -//***************************************************************************** -// COMMON DEFINES -//***************************************************************************** - -#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) -#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) -#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) -#define FLOW_CONTROL_EVENT_SIZE (4) - -#define BSD_RSP_PARAMS_SOCKET_OFFSET (0) -#define BSD_RSP_PARAMS_STATUS_OFFSET (4) - -#define GET_HOST_BY_NAME_RETVAL_OFFSET (0) -#define GET_HOST_BY_NAME_ADDR_OFFSET (4) - -#define ACCEPT_SD_OFFSET (0) -#define ACCEPT_RETURN_STATUS_OFFSET (4) -#define ACCEPT_ADDRESS__OFFSET (8) - -#define SL_RECEIVE_SD_OFFSET (0) -#define SL_RECEIVE_NUM_BYTES_OFFSET (4) -#define SL_RECEIVE__FLAGS__OFFSET (8) - - -#define SELECT_STATUS_OFFSET (0) -#define SELECT_READFD_OFFSET (4) -#define SELECT_WRITEFD_OFFSET (8) -#define SELECT_EXFD_OFFSET (12) - - -#define NETAPP_IPCONFIG_IP_OFFSET (0) -#define NETAPP_IPCONFIG_SUBNET_OFFSET (4) -#define NETAPP_IPCONFIG_GW_OFFSET (8) -#define NETAPP_IPCONFIG_DHCP_OFFSET (12) -#define NETAPP_IPCONFIG_DNS_OFFSET (16) -#define NETAPP_IPCONFIG_MAC_OFFSET (20) -#define NETAPP_IPCONFIG_SSID_OFFSET (26) - -#define NETAPP_IPCONFIG_IP_LENGTH (4) -#define NETAPP_IPCONFIG_MAC_LENGTH (6) -#define NETAPP_IPCONFIG_SSID_LENGTH (32) - - -#define NETAPP_PING_PACKETS_SENT_OFFSET (0) -#define NETAPP_PING_PACKETS_RCVD_OFFSET (4) -#define NETAPP_PING_MIN_RTT_OFFSET (8) -#define NETAPP_PING_MAX_RTT_OFFSET (12) -#define NETAPP_PING_AVG_RTT_OFFSET (16) - -#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) -#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) -#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) -#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) -#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) - -#define GET_MSS_VAL_RETVAL_OFFSET (0) - -//***************************************************************************** -// GLOBAL VARAIABLES -//***************************************************************************** - -UINT32 socket_active_status = SOCKET_STATUS_INIT_VAL; - - -//***************************************************************************** -// Prototypes for the static functions -//***************************************************************************** - -static INT32 hci_event_unsol_flowcontrol_handler(CHAR *pEvent); - -static void update_socket_active_status(CHAR *resp_params); - - -//***************************************************************************** -// -//! hci_unsol_handle_patch_request -//! -//! @param event_hdr event header -//! -//! @return none -//! -//! @brief Handle unsolicited event from type patch request -// -//***************************************************************************** -void hci_unsol_handle_patch_request(CHAR *event_hdr) -{ - CHAR *params = (CHAR *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - UINT32 ucLength = 0; - CHAR *patch; - - switch (*params) - { - case HCI_EVENT_PATCHES_DRV_REQ: - - if (tSLInformation.sDriverPatches) - { - patch = tSLInformation.sDriverPatches(&ucLength); - - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - - case HCI_EVENT_PATCHES_FW_REQ: - - if (tSLInformation.sFWPatches) - { - patch = tSLInformation.sFWPatches(&ucLength); - - // Build and send a patch - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - - case HCI_EVENT_PATCHES_BOOTLOAD_REQ: - - if (tSLInformation.sBootLoaderPatches) - { - patch = tSLInformation.sBootLoaderPatches(&ucLength); - - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - } -} - - - -//***************************************************************************** -// -//! hci_event_handler -//! -//! @param pRetParams incoming data buffer -//! @param from from information (in case of data received) -//! @param fromlen from information length (in case of data received) -//! -//! @return none -//! -//! @brief Parse the incoming events packets and issues corresponding -//! event handler from global array of handlers pointers -// -//***************************************************************************** - - -UINT8 * hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen) -{ - UINT8 *pucReceivedData, ucArgsize; - UINT16 usLength; - UINT8 *pucReceivedParams; - UINT16 usReceivedEventOpcode = 0; - UINT32 retValue32; - UINT8 * RecvParams; - UINT8 *RetParams; - - - while (1) - { - if (tSLInformation.usEventOrDataReceived != 0) - { - pucReceivedData = (tSLInformation.pucReceivedData); - - if (*pucReceivedData == HCI_TYPE_EVNT) - { - // Event Received - STREAM_TO_UINT16((CHAR *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, - usReceivedEventOpcode); - pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; - RecvParams = pucReceivedParams; - RetParams = pRetParams; - - // In case unsolicited event received - here the handling finished - if (hci_unsol_event_handler((CHAR *)pucReceivedData) == 0) - { - STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); - - switch(usReceivedEventOpcode) - { - case HCI_CMND_READ_BUFFER_SIZE: - { - STREAM_TO_UINT8((CHAR *)pucReceivedParams, 0, - tSLInformation.usNumberOfFreeBuffers); - STREAM_TO_UINT16((CHAR *)pucReceivedParams, 1, - tSLInformation.usSlBufferLength); - } - break; - - case HCI_CMND_WLAN_CONFIGURE_PATCH: - case HCI_NETAPP_DHCP: - case HCI_NETAPP_PING_SEND: - case HCI_NETAPP_PING_STOP: - case HCI_NETAPP_ARP_FLUSH: - case HCI_NETAPP_SET_DEBUG_LEVEL: - case HCI_NETAPP_SET_TIMERS: - case HCI_EVNT_NVMEM_READ: - case HCI_EVNT_NVMEM_CREATE_ENTRY: - case HCI_CMND_NVMEM_WRITE_PATCH: - case HCI_NETAPP_PING_REPORT: - case HCI_EVNT_MDNS_ADVERTISE: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(UINT8 *)pRetParams); - break; - - case HCI_CMND_SETSOCKOPT: - case HCI_CMND_WLAN_CONNECT: - case HCI_CMND_WLAN_IOCTL_STATUSGET: - case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: - case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: - case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: - case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: - case HCI_CMND_EVENT_MASK: - case HCI_EVNT_WLAN_DISCONNECT: - case HCI_EVNT_SOCKET: - case HCI_EVNT_BIND: - case HCI_CMND_LISTEN: - case HCI_EVNT_CLOSE_SOCKET: - case HCI_EVNT_CONNECT: - case HCI_EVNT_NVMEM_WRITE: - - STREAM_TO_UINT32((CHAR *)pucReceivedParams,0 - ,*(UINT32 *)pRetParams); - break; - - case HCI_EVNT_READ_SP_VERSION: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(UINT8 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 1; - STREAM_TO_UINT32((CHAR *)pucReceivedParams, 0, retValue32); - UINT32_TO_STREAM((UINT8 *)pRetParams, retValue32); - break; - - case HCI_EVNT_BSD_GETHOSTBYNAME: - - STREAM_TO_UINT32((CHAR *)pucReceivedParams - ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams - ,GET_HOST_BY_NAME_ADDR_OFFSET,*(UINT32 *)pRetParams); - break; - - case HCI_EVNT_GETMSSVALUE: - - STREAM_TO_UINT16((CHAR *)pucReceivedParams - ,GET_MSS_VAL_RETVAL_OFFSET,*(UINT16 *)pRetParams); - - break; - - case HCI_EVNT_ACCEPT: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,ACCEPT_SD_OFFSET - ,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams - ,ACCEPT_RETURN_STATUS_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - - //This argument returns in network order - memcpy((UINT8 *)pRetParams, - pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); - break; - } - - case HCI_EVNT_RECV: - case HCI_EVNT_RECVFROM: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(UINT32 *)pRetParams); - - if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) - { - set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); - } - break; - } - - case HCI_EVNT_SEND: - case HCI_EVNT_SENDTO: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - - break; - } - - case HCI_EVNT_SELECT: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_STATUS_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_READFD_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_EXFD_OFFSET,*(UINT32 *)pRetParams); - break; - } - - case HCI_CMND_GETSOCKOPT: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); - //This argument returns in network order - memcpy((UINT8 *)pRetParams, pucReceivedParams, 4); - break; - - case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: - - STREAM_TO_UINT32((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT16((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 2; - STREAM_TO_UINT16((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 2; - memcpy((UINT8 *)pRetParams, (CHAR *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); - break; - - case HCI_CMND_SIMPLE_LINK_START: - break; - - case HCI_NETAPP_IPCONFIG: - - //Read IP address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read subnet - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read default GW - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DHCP server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DNS server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read Mac address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); - RecvParams += 6; - - //Read SSID - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); - - } - } - - if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) - { - tSLInformation.usRxEventOpcode = 0; - } - } - else - { - pucReceivedParams = pucReceivedData; - STREAM_TO_UINT8((CHAR *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); - - STREAM_TO_UINT16((CHAR *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); - - // Data received: note that the only case where from and from length - // are not null is in recv from, so fill the args accordingly - if (from) - { - STREAM_TO_UINT32((CHAR *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(UINT32 *)fromlen); - memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); - } - - memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, - usLength - ucArgsize); - - tSLInformation.usRxDataPending = 0; - } - - tSLInformation.usEventOrDataReceived = 0; - - SpiResumeSpi(); - - // Since we are going to TX - we need to handle this event after the - // ResumeSPi since we need interrupts - if ((*pucReceivedData == HCI_TYPE_EVNT) && - (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) - { - hci_unsol_handle_patch_request((CHAR *)pucReceivedData); - } - - if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) - { - return NULL; - } - } - } - -} - -//***************************************************************************** -// -//! hci_unsol_event_handler -//! -//! @param event_hdr event header -//! -//! @return 1 if event supported and handled -//! 0 if event is not supported -//! -//! @brief Handle unsolicited events -// -//***************************************************************************** -INT32 hci_unsol_event_handler(CHAR *event_hdr) -{ - CHAR * data = NULL; - INT32 event_type; - UINT32 NumberOfReleasedPackets; - UINT32 NumberOfSentPackets; - - STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); - - if (event_type & HCI_EVNT_UNSOL_BASE) - { - switch(event_type) - { - - case HCI_EVNT_DATA_UNSOL_FREE_BUFF: - { - hci_event_unsol_flowcontrol_handler(event_hdr); - - NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets; - NumberOfSentPackets = tSLInformation.NumberOfSentPackets; - - if (NumberOfReleasedPackets == NumberOfSentPackets) - { - if (tSLInformation.InformHostOnTxComplete) - { - tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0); - } - } - return 1; - - } - } - } - - if(event_type & HCI_EVNT_WLAN_UNSOL_BASE) - { - switch(event_type) - { - case HCI_EVNT_WLAN_KEEPALIVE: - case HCI_EVNT_WLAN_UNSOL_CONNECT: - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - case HCI_EVNT_WLAN_UNSOL_INIT: - case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, 0, 0); - } - break; - - case HCI_EVNT_WLAN_UNSOL_DHCP: - { - UINT8 params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status - UINT8 *recParams = params; - - data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - - //Read IP address - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read subnet - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read default GW - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DHCP server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DNS server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - // read the status - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams); - - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (CHAR *)params, sizeof(params)); - } - } - break; - - case HCI_EVNT_WLAN_ASYNC_PING_REPORT: - { - netapp_pingreport_args_t params; - data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); - STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time); - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (CHAR *)¶ms, sizeof(params)); - } - } - break; - case HCI_EVNT_BSD_TCP_CLOSE_WAIT: - { - data = (CHAR *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - if( tSLInformation.sWlanCB ) - { - //data[0] represents the socket id, for which FIN was received by remote. - //Upon receiving this event, the user can close the socket, or else the - //socket will be closed after inacvitity timeout (by default 60 seconds) - tSLInformation.sWlanCB(event_type, data, 1); - } - } - break; - - //'default' case which means "event not supported" - default: - return (0); - } - return(1); - } - - if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) - || (event_type == HCI_EVNT_WRITE)) - { - CHAR *pArg; - INT32 status; - - pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); - STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if (ERROR_SOCKET_INACTIVE == status) - { - // The only synchronous event that can come from SL device in form of - // command complete is "Command Complete" on data sent, in case SL device - // was unable to transmit - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError); - update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); - - return (1); - } - else - return (0); - } - - //handle a case where unsolicited event arrived, but was not handled by any of the cases above - if ((event_type != tSLInformation.usRxEventOpcode) && (event_type != HCI_EVNT_PATCHES_REQ)) - { - return(1); - } - - return(0); -} - -//***************************************************************************** -// -//! hci_unsolicited_event_handler -//! -//! @param None -//! -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Parse the incoming unsolicited event packets and issues -//! corresponding event handler. -// -//***************************************************************************** -INT32 hci_unsolicited_event_handler(void) -{ - UINT32 res = 0; - UINT8 *pucReceivedData; - - if (tSLInformation.usEventOrDataReceived != 0) - { - pucReceivedData = (tSLInformation.pucReceivedData); - - if (*pucReceivedData == HCI_TYPE_EVNT) - { - - // In case unsolicited event received - here the handling finished - if (hci_unsol_event_handler((CHAR *)pucReceivedData) == 1) - { - - // There was an unsolicited event received - we can release the buffer - // and clean the event received - tSLInformation.usEventOrDataReceived = 0; - - res = 1; - SpiResumeSpi(); - } - } - } - - return res; -} - -//***************************************************************************** -// -//! set_socket_active_status -//! -//! @param Sd -//! @param Status -//! @return none -//! -//! @brief Check if the socket ID and status are valid and set -//! accordingly the global socket status -// -//***************************************************************************** -void set_socket_active_status(INT32 Sd, INT32 Status) -{ - if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status)) - { - socket_active_status &= ~(1 << Sd); /* clean socket's mask */ - socket_active_status |= (Status << Sd); /* set new socket's mask */ - } -} - - -//***************************************************************************** -// -//! hci_event_unsol_flowcontrol_handler -//! -//! @param pEvent pointer to the string contains parameters for IPERF -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Called in case unsolicited event from type -//! HCI_EVNT_DATA_UNSOL_FREE_BUFF has received. -//! Keep track on the number of packets transmitted and update the -//! number of free buffer in the SL device. -// -//***************************************************************************** -INT32 hci_event_unsol_flowcontrol_handler(CHAR *pEvent) -{ - - INT32 temp, value; - UINT16 i; - UINT16 pusNumberOfHandles=0; - CHAR *pReadPayload; - - STREAM_TO_UINT16((CHAR *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); - pReadPayload = ((CHAR *)pEvent + - HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); - temp = 0; - - for(i = 0; i < pusNumberOfHandles ; i++) - { - STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value); - temp += value; - pReadPayload += FLOW_CONTROL_EVENT_SIZE; - } - - tSLInformation.usNumberOfFreeBuffers += temp; - tSLInformation.NumberOfReleasedPackets += temp; - - return(ESUCCESS); -} - -//***************************************************************************** -// -//! get_socket_active_status -//! -//! @param Sd Socket IS -//! @return Current status of the socket. -//! -//! @brief Retrieve socket status -// -//***************************************************************************** - -INT32 get_socket_active_status(INT32 Sd) -{ - if(M_IS_VALID_SD(Sd)) - { - return (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE; - } - return SOCKET_STATUS_INACTIVE; -} - -//***************************************************************************** -// -//! update_socket_active_status -//! -//! @param resp_params Socket IS -//! @return Current status of the socket. -//! -//! @brief Retrieve socket status -// -//***************************************************************************** -void update_socket_active_status(CHAR *resp_params) -{ - INT32 status, sd; - - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if(ERROR_SOCKET_INACTIVE == status) - { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } -} - - -//***************************************************************************** -// -//! SimpleLinkWaitEvent -//! -//! @param usOpcode command operation code -//! @param pRetParams command return parameters -//! -//! @return none -//! -//! @brief Wait for event, pass it to the hci_event_handler and -//! update the event opcode in a global variable. -// -//***************************************************************************** - -void SimpleLinkWaitEvent(UINT16 usOpcode, void *pRetParams) -{ - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction - tSLInformation.usRxEventOpcode = usOpcode; - hci_event_handler(pRetParams, 0, 0); -} - -//***************************************************************************** -// -//! SimpleLinkWaitData -//! -//! @param pBuf data buffer -//! @param from from information -//! @param fromlen from information length -//! -//! @return none -//! -//! @brief Wait for data, pass it to the hci_event_handler -//! and update in a global variable that there is -//! data to read. -// -//***************************************************************************** - -void SimpleLinkWaitData(UINT8 *pBuf, UINT8 *from, UINT8 *fromlen) -{ - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction, i.e. only after data will be received - tSLInformation.usRxDataPending = 1; - hci_event_handler(pBuf, from, fromlen); -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/hci.c b/drivers/cc3000/src/hci.c deleted file mode 100644 index 4391692b8bc2..000000000000 --- a/drivers/cc3000/src/hci.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************** -* -* hci.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup hci_app -//! @{ -// -//***************************************************************************** - -#include -#include "cc3000_common.h" -#include "hci.h" -#include "ccspi.h" -#include "evnt_handler.h" -#include "wlan.h" - -#define SL_PATCH_PORTION_SIZE (1000) - - -//***************************************************************************** -// -//! hci_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param ucArgsLength length of the arguments -//! -//! @return none -//! -//! @brief Initiate an HCI command. -// -//***************************************************************************** -UINT16 hci_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength) -{ - UINT8 *stream; - - stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_CMND); - stream = UINT16_TO_STREAM(stream, usOpcode); - UINT8_TO_STREAM(stream, ucArgsLength); - - //Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); - - return(0); -} - -//***************************************************************************** -// -//! hci_data_send -//! -//! @param usOpcode command operation code -//! @param ucArgs pointer to the command's arguments buffer -//! @param usArgsLength length of the arguments -//! @param ucTail pointer to the data buffer -//! @param usTailLength buffer length -//! -//! @return none -//! -//! @brief Initiate an HCI data write operation -// -//***************************************************************************** -INT32 hci_data_send(UINT8 ucOpcode, - UINT8 *ucArgs, - UINT16 usArgsLength, - UINT16 usDataLength, - const UINT8 *ucTail, - UINT16 usTailLength) -{ - UINT8 *stream; - - stream = ((ucArgs) + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, ucOpcode); - UINT8_TO_STREAM(stream, usArgsLength); - stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); - - // Send the packet over the SPI - SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); - - return(ESUCCESS); -} - - -//***************************************************************************** -// -//! hci_data_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the data buffer -//! @param ucArgsLength arguments length -//! @param ucDataLength data length -//! -//! @return none -//! -//! @brief Prepeare HCI header and initiate an HCI data write operation -// -//***************************************************************************** -void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength,UINT16 ucDataLength) -{ - UINT8 *stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, usOpcode); - UINT8_TO_STREAM(stream, ucArgsLength); - stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); - - // Send the command over SPI on data channel - SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); - - return; -} - -//***************************************************************************** -// -//! hci_patch_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer -//! @param usDataLength data length -//! -//! @return none -//! -//! @brief Prepeare HCI header and initiate an HCI patch write operation -// -//***************************************************************************** -void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength) -{ - UINT8 *data_ptr = (pucBuff + SPI_HEADER_SIZE); - UINT16 usTransLength; - UINT8 *stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); - UINT8_TO_STREAM(stream, ucOpcode); - stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - - if (usDataLength <= SL_PATCH_PORTION_SIZE) - { - UINT16_TO_STREAM(stream, usDataLength); - stream = UINT16_TO_STREAM(stream, usDataLength); - memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); - - // Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); - } - else - { - - usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); - UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); - memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); - usDataLength -= SL_PATCH_PORTION_SIZE; - patch += SL_PATCH_PORTION_SIZE; - - // Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); - - while (usDataLength) - { - if (usDataLength <= SL_PATCH_PORTION_SIZE) - { - usTransLength = usDataLength; - usDataLength = 0; - - } - else - { - usTransLength = SL_PATCH_PORTION_SIZE; - usDataLength -= usTransLength; - } - - *(UINT16 *)data_ptr = usTransLength; - memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); - patch += usTransLength; - - // Update the opcode of the event we will be waiting for - SpiWrite((UINT8 *)data_ptr, usTransLength + sizeof(usTransLength)); - } - } -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -// -//***************************************************************************** diff --git a/drivers/cc3000/src/inet_ntop.c b/drivers/cc3000/src/inet_ntop.c deleted file mode 100644 index 83242efa00b0..000000000000 --- a/drivers/cc3000/src/inet_ntop.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include "cc3000_common.h" -#include "socket.h" -#include "inet_ntop.h" - -// We can't include stdio.h because it defines _types_fd_set, but we -// need to use the CC3000 version of this type. So we must provide -// our own declaration of snprintf. Grrr. -int snprintf(char *str, size_t size, const char *fmt, ...); - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -#define ENOSPC (28) -#define EAFNOSUPPORT (106) -#define SET_ERRNO(err) (CC3000_EXPORT(errno)=-err) - -/* - * Format an IPv4 address, more or less like inet_ntoa(). - * - * Returns `dst' (as a const) - * Note: - * - uses no statics - * - takes a unsigned char* not an in_addr as input - */ -static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size) -{ - size_t len; - char tmp[sizeof "255.255.255.255"]; - - tmp[0] = '\0'; - (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", - ((int)((unsigned char)src[3])) & 0xff, - ((int)((unsigned char)src[2])) & 0xff, - ((int)((unsigned char)src[1])) & 0xff, - ((int)((unsigned char)src[0])) & 0xff); - - len = strlen(tmp); - if(len == 0 || len >= size) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - strcpy(dst, tmp); - return dst; -} - -#ifdef ENABLE_IPV6 -/* - * Convert IPv6 binary address into presentation (printable) format. - */ -static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - char *tp; - struct { - long base; - long len; - } best, cur; - unsigned long words[IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); - - best.base = -1; - cur.base = -1; - best.len = 0; - cur.len = 0; - - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - if(words[i] == 0) - { - if(cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } - else if(cur.base != -1) - { - if(best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if(best.base != -1 && best.len < 2) - best.base = -1; - - /* Format the result. - */ - tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? - */ - if(best.base != -1 && i >= best.base && i < (best.base + best.len)) - { - if(i == best.base) - *tp++ = ':'; - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if(i != 0) - *tp++ = ':'; - - /* Is this address an encapsulated IPv4? - */ - if(i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) - { - if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - tp += strlen(tp); - break; - } - tp += snprintf(tp, 5, "%lx", words[i]); - } - - /* Was it a trailing run of 0x00's? - */ - if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* Check for overflow, copy, and we're done. - */ - if((size_t)(tp - tmp) > size) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - strcpy(dst, tmp); - return dst; -} -#endif /* ENABLE_IPV6 */ - -/* - * Convert a network format address to presentation format. - * - * Returns pointer to presentation format address (`buf'). - * Returns NULL on error and errno set with the specific - * error, EAFNOSUPPORT or ENOSPC. - * - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid loosing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this funtion sets when returning NULL, not SOCKERRNO. - */ -char *inet_ntop(int af, const void *src, char *buf, size_t size) -{ - switch (af) { - case AF_INET: - return inet_ntop4((const unsigned char*)src, buf, size); -#ifdef ENABLE_IPV6 - case AF_INET6: - return inet_ntop6((const unsigned char*)src, buf, size); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return NULL; - } -} diff --git a/drivers/cc3000/src/inet_pton.c b/drivers/cc3000/src/inet_pton.c deleted file mode 100644 index 5f5ae5f9d7f1..000000000000 --- a/drivers/cc3000/src/inet_pton.c +++ /dev/null @@ -1,216 +0,0 @@ -/* This is from the BIND 4.9.4 release, modified to compile by itself */ - -/* Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include -#include "cc3000_common.h" -#include "socket.h" -#include "inet_pton.h" - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -static int inet_pton4(const char *src, unsigned char *dst); -#ifdef ENABLE_IPV6 -static int inet_pton6(const char *src, unsigned char *dst); -#endif - -#define EAFNOSUPPORT (106) -#define SET_ERRNO(err) (CC3000_EXPORT(errno)=-err) - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * notice: - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid loosing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this funtion sets when returning (-1), not SOCKERRNO. - * author: - * Paul Vixie, 1996. - */ -int inet_pton(int af, const char *src, void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, (unsigned char *)dst)); -#ifdef ENABLE_IPV6 - case AF_INET6: - return (inet_pton6(src, (unsigned char *)dst)); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int inet_pton4(const char *src, unsigned char *dst) -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - tp = tmp; - *tp = 0; - while((ch = *src++) != '\0') { - const char *pch; - - if((pch = strchr(digits, ch)) != NULL) { - unsigned int val = *tp * 10 + (unsigned int)(pch - digits); - - if(saw_digit && *tp == 0) - return (0); - if(val > 255) - return (0); - *tp = (unsigned char)val; - if(! saw_digit) { - if(++octets > 4) - return (0); - saw_digit = 1; - } - } - else if(ch == '.' && saw_digit) { - if(octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } - else - return (0); - } - if(octets < 4) - return (0); - memcpy(dst, tmp, INADDRSZ); - return (1); -} - -#ifdef ENABLE_IPV6 -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -static int inet_pton6(const char *src, unsigned char *dst) -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - unsigned int val; - - memset((tp = tmp), 0, IN6ADDRSZ); - endp = tp + IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if(*src == ':') - if(*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while((ch = *src++) != '\0') { - const char *pch; - - if((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if(pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if(++saw_xdigit > 4) - return (0); - continue; - } - if(ch == ':') { - curtok = src; - if(!saw_xdigit) { - if(colonp) - return (0); - colonp = tp; - continue; - } - if(tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if(ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if(saw_xdigit) { - if(tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if(colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const long n = tp - colonp; - long i; - - if(tp == endp) - return (0); - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if(tp != endp) - return (0); - memcpy(dst, tmp, IN6ADDRSZ); - return (1); -} -#endif /* ENABLE_IPV6 */ diff --git a/drivers/cc3000/src/netapp.c b/drivers/cc3000/src/netapp.c deleted file mode 100644 index a6f60feda0d4..000000000000 --- a/drivers/cc3000/src/netapp.c +++ /dev/null @@ -1,459 +0,0 @@ -/***************************************************************************** -* -* netapp.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -#include -#include "netapp.h" -#include "hci.h" -#include "socket.h" -#include "evnt_handler.h" -#include "nvmem.h" - -#define MIN_TIMER_VAL_SECONDS 10 -#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ - { \ - t = MIN_TIMER_VAL_SECONDS; \ - } - - -#define NETAPP_DHCP_PARAMS_LEN (20) -#define NETAPP_SET_TIMER_PARAMS_LEN (20) -#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) -#define NETAPP_PING_SEND_PARAMS_LEN (16) - - -//***************************************************************************** -// -//! netapp_config_mac_adrress -//! -//! @param mac device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Configure device MAC address and store it in NVMEM. -//! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved -//! over resets. -// -//***************************************************************************** -INT32 netapp_config_mac_adrress(UINT8 * mac) -{ - return nvmem_set_mac_address(mac); -} - -//***************************************************************************** -// -//! netapp_dhcp -//! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, -//! aucIP, aucSubnetMask, aucDefaultGateway must be 0. -//! The default mode of CC3000 is DHCP mode. -//! Note that the configuration is saved in non volatile memory -//! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. -//! -//***************************************************************************** -INT32 netapp_dhcp(UINT32 *aucIP, UINT32 *aucSubnetMask,UINT32 *aucDefaultGateway, UINT32 *aucDNSServer) -{ - INT8 scRet; - UINT8 *ptr; - UINT8 *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - ARRAY_TO_STREAM(args,aucIP,4); - ARRAY_TO_STREAM(args,aucSubnetMask,4); - ARRAY_TO_STREAM(args,aucDefaultGateway,4); - args = UINT32_TO_STREAM(args, 0); - ARRAY_TO_STREAM(args,aucDNSServer,4); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet); - - return(scRet); -} - - -//***************************************************************************** -// -//! netapp_timeout_values -//! -//! @param aucDHCP DHCP lease time request, also impact -//! the DHCP renew timeout. Range: [0-0xffffffff] seconds, -//! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds. -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 14400 seconds. -//! -//! @param aucARP ARP refresh timeout, if ARP entry is not updated by -//! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. -//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 3600 seconds. -//! -//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout -//! Range: [0-0xffffffff] seconds, 0 == infinity timeout -//! Resolution: 10 seconds. -//! Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 10 seconds. -//! -//! @param aucInactivity Socket inactivity timeout, socket timeout is -//! refreshed by incoming or outgoing packet, by the -//! end of the socket timeout the socket will be closed -//! Range: [0-0xffffffff] sec, 0 == infinity timeout. -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 60 seconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! -//! @note If a parameter set to non zero value which is less than 10s, -//! it will be set automatically to 10s. -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_timeout_values(UINT32 *aucDHCP, UINT32 *aucARP,UINT32 *aucKeepalive, UINT32 *aucInactivity) -{ - INT8 scRet; - UINT8 *ptr; - UINT8 *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Set minimal values of timers - MIN_TIMER_SET(*aucDHCP) - MIN_TIMER_SET(*aucARP) - MIN_TIMER_SET(*aucKeepalive) - MIN_TIMER_SET(*aucInactivity) - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *aucDHCP); - args = UINT32_TO_STREAM(args, *aucARP); - args = UINT32_TO_STREAM(args, *aucKeepalive); - args = UINT32_TO_STREAM(args, *aucInactivity); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet); - - return(scRet); -} -#endif - - -//***************************************************************************** -// -//! netapp_ping_send -//! -//! @param ip destination IP address -//! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes -//! @param pingTimeout Time to wait for a response,in milliseconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report -//! event will be generated. The report structure is as defined -//! by structure netapp_pingreport_args_t. -//! -//! @warning Calling this function while a previous Ping Requests are in -//! progress will stop the previous ping request. -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 - netapp_ping_send(UINT32 *ip, UINT32 ulPingAttempts, UINT32 ulPingSize, UINT32 ulPingTimeout) -{ - INT8 scRet; - UINT8 *ptr, *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *ip); - args = UINT32_TO_STREAM(args, ulPingAttempts); - args = UINT32_TO_STREAM(args, ulPingSize); - args = UINT32_TO_STREAM(args, ulPingTimeout); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet); - - return(scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_ping_report -//! -//! @param none -//! -//! @return none -//! -//! @brief Request for ping status. This API triggers the CC3000 to send -//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. -//! This event will carry the report structure: -//! netapp_pingreport_args_t. This structure is filled in with ping -//! results up till point of triggering API. -//! netapp_pingreport_args_t:\n packets_sent - echo sent, -//! packets_received - echo reply, min_round_time - minimum -//! round time, max_round_time - max round time, -//! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure -//! fields are 0. -//! -//***************************************************************************** - - -#ifndef CC3000_TINY_DRIVER -void netapp_ping_report() -{ - UINT8 *ptr; - ptr = tSLInformation.pucTxCommandBuffer; - INT8 scRet; - - scRet = EFAIL; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_ping_stop -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief Stop any ping request. -//! -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_ping_stop() -{ - INT8 scRet; - UINT8 *ptr; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet); - - return(scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_ipconfig -//! -//! @param[out] ipconfig This argument is a pointer to a -//! tNetappIpconfigRetArgs structure. This structure is -//! filled in with the network interface configuration. -//! tNetappIpconfigRetArgs:\n aucIP - ip address, -//! aucSubnetMask - mask, aucDefaultGateway - default -//! gateway address, aucDHCPServer - dhcp server address -//! aucDNSServer - dns server address, uaMacAddr - mac -//! address, uaSSID - connected AP ssid -//! -//! @return none -//! -//! @brief Obtain the CC3000 Network interface information. -//! Note that the information is available only after the WLAN -//! connection was established. Calling this function before -//! associated, will cause non-defined values to be returned. -//! -//! @note The function is useful for figuring out the IP Configuration of -//! the device when DHCP is used and for figuring out the SSID of -//! the Wireless network the device is associated with. -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) -{ - UINT8 *ptr; - - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig ); - -} -#else -void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) -{ - -} -#endif - -//***************************************************************************** -// -//! netapp_arp_flush -//! -//! @param none -//! -//! @return none -//! -//! @brief Flushes ARP table -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_arp_flush(void) -{ - INT8 scRet; - UINT8 *ptr; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet); - - return(scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_set_debug_level -//! -//! @param[in] level debug level. Bitwise [0-8], -//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical -//! message, 1 information message, 2 - core messages, 3 - -//! HCI messages, 4 - Network stack messages, 5 - wlan -//! messages, 6 - wlan driver messages, 7 - epprom messages, -//! 8 - general messages. Default: 0x13f. Saved: no -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Debug messages sent via the UART debug channel, this function -//! enable/disable the debug level -//! -//***************************************************************************** - - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_set_debug_level(UINT32 ulLevel) -{ - INT8 scRet; - UINT8 *ptr, *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // - // Fill in temporary command buffer - // - args = UINT32_TO_STREAM(args, ulLevel); - - - // - // Initiate a HCI command - // - hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN); - - // - // Wait for command complete event - // - SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet); - - return(scRet); - -} -#endif diff --git a/drivers/cc3000/src/nvmem.c b/drivers/cc3000/src/nvmem.c deleted file mode 100644 index c6e170a74650..000000000000 --- a/drivers/cc3000/src/nvmem.c +++ /dev/null @@ -1,334 +0,0 @@ -/***************************************************************************** -* -* nvmem.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup nvmem_api -//! @{ -// -//***************************************************************************** - -#include -#include "nvmem.h" -#include "hci.h" -#include "socket.h" -#include "evnt_handler.h" - -//***************************************************************************** -// -// Prototypes for the structures for APIs. -// -//***************************************************************************** - -#define NVMEM_READ_PARAMS_LEN (12) -#define NVMEM_CREATE_PARAMS_LEN (8) -#define NVMEM_WRITE_PARAMS_LEN (16) - -//***************************************************************************** -// -//! nvmem_read -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, -//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, -//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, -//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read -//! @param buff output buffer pointer -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads data from the file referred by the ulFileId parameter. -//! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! -//***************************************************************************** - -INT32 nvmem_read(UINT32 ulFileId, UINT32 ulLength, UINT32 ulOffset, UINT8 *buff) -{ - UINT8 ucStatus = 0xFF; - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, ulLength); - args = UINT32_TO_STREAM(args, ulOffset); - - // Initiate a HCI command - hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); - SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus); - - // In case there is data - read it - even if an error code is returned - // Note: It is the user responsibility to ignore the data in case of an error code - - // Wait for the data in a synchronous way. Here we assume that the buffer is - // big enough to store also parameters of nvmem - - SimpleLinkWaitData(buff, 0, 0); - - return(ucStatus); -} - -//***************************************************************************** -// -//! nvmem_write -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from -//! @param buff data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be -//! marked invalid till the write is done. The file entry doesn't -//! need to be valid - only allocated. -//! -//***************************************************************************** - -INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff) -{ - INT32 iRes; - UINT8 *ptr; - UINT8 *args; - - iRes = EFAIL; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, 12); - args = UINT32_TO_STREAM(args, ulLength); - args = UINT32_TO_STREAM(args, ulEntryOffset); - - memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + - NVMEM_WRITE_PARAMS_LEN),buff,ulLength); - - // Initiate a HCI command but it will come on data channel - hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, - ulLength); - - SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes); - - return(iRes); -} - - -//***************************************************************************** -// -//! nvmem_set_mac_address -//! -//! @param mac mac address to be set -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write MAC address to EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** - -UINT8 nvmem_set_mac_address(UINT8 *mac) -{ - return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); -} - -//***************************************************************************** -// -//! nvmem_get_mac_address -//! -//! @param[out] mac mac address -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read MAC address from EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** - -UINT8 nvmem_get_mac_address(UINT8 *mac) -{ - return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); -} - -//***************************************************************************** -// -//! nvmem_write_patch -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write -//! @param spData SP data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief program a patch to a specific file ID. -//! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is -//! applied in SP_PORTION_SIZE bytes portions. -//! -//***************************************************************************** - -UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData) -{ - UINT8 status = 0; - UINT16 offset = 0; - UINT8* spDataPtr = (UINT8*)spData; - - while ((status == 0) && (spLength >= SP_PORTION_SIZE)) - { - status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); - offset += SP_PORTION_SIZE; - spLength -= SP_PORTION_SIZE; - spDataPtr += SP_PORTION_SIZE; - } - - if (status !=0) - { - // NVMEM error occurred - return status; - } - - if (spLength != 0) - { - // if reached here, a reminder is left - status = nvmem_write(ulFileId, spLength, offset, spDataPtr); - } - - return status; -} - -//***************************************************************************** -// -//! nvmem_read_sp_version -//! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read patch version. read package version (WiFi FW patch, -//! driver-supplicant-NS patch, bootloader patch) -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -UINT8 nvmem_read_sp_version(UINT8* patchVer) -{ - UINT8 *ptr; - // 1st byte is the status and the rest is the SP version - UINT8 retBuf[5]; - - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command, no args are required - hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); - SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf); - - // package ID - *patchVer = retBuf[3]; - // package build number - *(patchVer+1) = retBuf[4]; - - return(retBuf[0]); -} -#endif - -//***************************************************************************** -// -//! nvmem_create_entry -//! -//! @param ulFileId nvmem file Id:\n -//! * NVMEM_AES128_KEY_FILEID: 12 -//! * NVMEM_SHARED_MEM_FILEID: 13 -//! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength -//! -//! @return on success 0, error otherwise. -//! -//! @brief Create new file entry and allocate space on the NVMEM. -//! Applies only to user files. -//! Modify the size of file. -//! If the entry is unallocated - allocate it to size -//! ulNewLen (marked invalid). -//! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - -//! set ulNewLen=0. -//! -//***************************************************************************** - -INT32 nvmem_create_entry(UINT32 ulFileId, UINT32 ulNewLen) -{ - UINT8 *ptr; - UINT8 *args; - UINT8 retval; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, ulNewLen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); - - SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); - - return(retval); -} - - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/patch.c b/drivers/cc3000/src/patch.c deleted file mode 100644 index 227be3c9f2a3..000000000000 --- a/drivers/cc3000/src/patch.c +++ /dev/null @@ -1,117 +0,0 @@ -/***************************************************************************** - * - * {PatchProgrammer_DR_Patch.c} - * - * Burn Patches to EEPROM - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ - * ALL RIGHTS RESERVED - * - *****************************************************************************/ -// -// Service Pack version P1.13.7.15.28 - Driver patches -// This file contains the CC3K driver and firmware patches -// From CC3000-FRAM-PATCH V:1.13.7 15-MAY-2014 - -unsigned short fw_length = 5700; -unsigned short drv_length = 8024; - -const unsigned char wlan_drv_patch[8024] = { 0x00, 0x01, 0x00, 0x00, 0x50, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x00, 0xE4, 0x62, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7A, 0x63, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x64, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, 0x0C, 0x49, 0x08, 0x60, 0x0C, 0x48, 0x19, 0x30, 0xF7, 0x46, 0x30, 0xB5, 0x05, 0x1C, 0xAC, 0x69, 0x68, 0x68, 0x5F, 0x30, 0x09, 0xD1, 0x60, 0x6B, 0x0C, 0x38, 0x01, 0x21, 0x8E, 0x46, 0x06, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x00, 0x20, 0x60, 0x63, 0xAC, 0x69, 0x6C, 0x60, 0x04, 0x48, 0x5B, 0x30, 0x30, 0xBD, 0x40, 0x3B, 0x08, 0x00, 0x49, 0xD0, 0x01, 0x00, 0x09, 0xEA, 0x02, 0x00, 0x91, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x64, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3C, 0x65, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xB5, 0x85, 0xB0, 0x05, 0x1C, 0xA8, 0x88, 0x00, 0x90, 0x28, 0x89, 0x01, 0x90, 0xE9, 0x68, 0x02, 0x91, 0x28, 0x7C, 0x03, 0x90, 0x2A, 0x6A, 0x00, 0x20, 0x17, 0x56, 0x68, 0x60, 0x00, 0x29, 0x4C, 0xD0, 0x00, 0x2F, 0x4A, 0xDC , -0xCA, 0x49, 0x0C, 0x1C, 0x08, 0x26, 0x04, 0x90, 0x21, 0x88, 0x00, 0x98, 0x81, 0x42, 0x0C, 0xD1, 0x62, 0x88, 0x01, 0x98, 0x82, 0x42, 0x08, 0xD1, 0x46, 0x20, 0x02, 0x5D, 0x03, 0x98, 0x82, 0x42, 0x03, 0xD1, 0x0E, 0x20, 0x00, 0x57, 0xB8, 0x42, 0x0A, 0xD0, 0x46, 0x20, 0x00, 0x5D, 0x11, 0x28, 0x22, 0xD1, 0x00, 0x98, 0x81, 0x42, 0x1F, 0xD1, 0x0E, 0x20, 0x00, 0x57, 0xFF, 0xFF, 0xD2, 0x65, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xB8, 0x42, 0x1B, 0xD1, 0x04, 0x20, 0x02, 0x1C, 0x02, 0x98, 0xB9, 0x49, 0x01, 0x23, 0x9E, 0x46, 0xEC, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x17, 0xD0, 0x20, 0x1D, 0x02, 0x99, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xE7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x0D, 0xD0, 0x46, 0x20, 0x00, 0x5D, 0x11, 0x28, 0x09, 0xD0, 0xA0, 0x6D, 0x00, 0x28, 0x06, 0xD0, 0xAC, 0x34, 0x04, 0x98, 0x01, 0x30, 0x04, 0x90, 0x01, 0x3E, 0xC1, 0xD1, 0x07, 0xE0, 0x04, 0x98, 0x00, 0x06, 0x00, 0x0E , -0xAC, 0x21, 0x41, 0x43, 0xA6, 0x48, 0x40, 0x18, 0x68, 0x60, 0xA6, 0x48, 0xAD, 0x30, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0xB5, 0xC2, 0x68, 0x90, 0x69, 0x02, 0x21, 0x01, 0x23, 0x9E, 0x46, 0xA2, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xA2, 0x48, 0x61, 0x30, 0x00, 0xBD, 0x01, 0x79, 0x0B, 0x29, 0x03, 0xD0, 0x89, 0x00, 0x9F, 0x4A, 0x51, 0x5A, 0x01, 0xE0, 0x01, 0x21, 0x49, 0x02, 0x41, 0x60, 0x9D, 0x48, 0x0D, 0x30, 0xF7, 0x46, 0x01, 0x1C, 0xFF, 0xFF, 0x68, 0x66, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x9C, 0x48, 0x02, 0x68, 0x9C, 0x48, 0x01, 0x2A, 0x01, 0xD1, 0x25, 0x30, 0xF7, 0x46, 0x9B, 0x4A, 0x12, 0x68, 0x4A, 0x60, 0x19, 0x30, 0xF7, 0x46, 0x00, 0x21, 0x41, 0x60, 0x99, 0x48, 0x98, 0x49, 0x08, 0x18, 0xF7, 0x46, 0x00, 0x21, 0x41, 0x60, 0x97, 0x48, 0xE7, 0x49, 0x08, 0x18, 0xF7, 0x46, 0xFF, 0xB5, 0x46, 0x69, 0x40, 0x68, 0x01, 0x90, 0x94, 0x49, 0x0A, 0x7C, 0x9A, 0x4F, 0x01, 0x2A, 0x63, 0xD0, 0x09, 0x7C, 0x03, 0x29 , -0x60, 0xD0, 0x91, 0x4A, 0x92, 0x4B, 0x00, 0x21, 0x02, 0x91, 0x59, 0x56, 0x24, 0x23, 0x59, 0x43, 0x53, 0x18, 0x03, 0x93, 0x01, 0x28, 0x17, 0xD1, 0x8A, 0x18, 0x04, 0x23, 0x6C, 0x46, 0x8C, 0x49, 0x15, 0x79, 0x08, 0x78, 0xC0, 0x43, 0x28, 0x43, 0x20, 0x70, 0x01, 0x32, 0x01, 0x31, 0x01, 0x34, 0x01, 0x3B, 0xF5, 0xD1, 0x31, 0x1D, 0x68, 0x46, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xA9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x40, 0xD0, 0x35, 0x1D, 0x82, 0x48, 0x00, 0x78, 0xFF, 0x28, 0xFF, 0xFF, 0xFE, 0x66, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x11, 0xD0, 0x00, 0x28, 0x0F, 0xD0, 0x03, 0x98, 0x01, 0x1D, 0x28, 0x1C, 0x01, 0x24, 0xA6, 0x46, 0x7E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x00, 0x28, 0x05, 0xD1, 0x7A, 0x48, 0xA6, 0x46, 0x7B, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x05, 0xE0, 0x28, 0x1C, 0x01, 0x21, 0x8E, 0x46, 0x78, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x99, 0x01, 0x29, 0x01, 0xD1, 0x00, 0x28, 0x1E, 0xD1 , -0x01, 0x99, 0x5F, 0x31, 0x01, 0xD0, 0x00, 0x28, 0x0F, 0xD1, 0xA8, 0x20, 0x81, 0x5D, 0x00, 0x29, 0x08, 0xD0, 0x49, 0x1E, 0x81, 0x55, 0x80, 0x5D, 0x00, 0x28, 0x09, 0xD1, 0x38, 0x1C, 0xFF, 0x30, 0x08, 0x30, 0x11, 0xE0, 0x03, 0x21, 0x02, 0x91, 0x00, 0xE0, 0xA8, 0x20, 0x02, 0x99, 0x81, 0x55, 0x38, 0x1C, 0xFF, 0x30, 0x16, 0x30, 0x07, 0xE0, 0x01, 0x98, 0x01, 0x28, 0x02, 0xD1, 0x38, 0x1C, 0xA3, 0x30, 0x01, 0xE0, 0x38, 0x1C, 0x9F, 0x30, 0x00, 0x90, 0xFF, 0xBD, 0x00, 0xB5, 0x02, 0x1C, 0x10, 0x6A, 0xD1, 0x69, 0x52, 0x69, 0xC3, 0x69, 0x5A, 0x60, 0xFF, 0xFF, 0x94, 0x67, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x22, 0x96, 0x46, 0x5E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x5E, 0x48, 0xFF, 0x30, 0x6E, 0x30, 0x00, 0xBD, 0x10, 0xB5, 0x0A, 0x1C, 0x41, 0x69, 0x00, 0x6A, 0x93, 0x69, 0xDB, 0x69, 0x58, 0x60, 0x90, 0x69, 0x01, 0x24, 0xA6, 0x46, 0x56, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0xA6, 0x46, 0x56, 0x48, 0xFE, 0x44 , -0x00, 0x47, 0x55, 0x48, 0xFF, 0x30, 0xB6, 0x30, 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x1C, 0x6E, 0x69, 0x53, 0x48, 0x02, 0x68, 0x5C, 0x21, 0x88, 0x5D, 0x04, 0x28, 0x15, 0xD1, 0x07, 0x20, 0x88, 0x55, 0x10, 0x0B, 0x11, 0xD2, 0x01, 0x24, 0xA6, 0x46, 0x4E, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x00, 0x28, 0x0A, 0xD0, 0x47, 0x21, 0x89, 0x57, 0xC1, 0x60, 0x11, 0x21, 0xC9, 0x02, 0x00, 0x22, 0x04, 0x23, 0xA6, 0x46, 0xE8, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x01, 0x20, 0x68, 0x60, 0x43, 0x48, 0xED, 0x49, 0x08, 0x18, 0x70, 0xBD, 0x70, 0xB5, 0x05, 0x1C, 0xAE, 0x69, 0x9C, 0x20, 0x80, 0x19, 0x4B, 0x21, 0x89, 0x00, 0x01, 0x24, 0xFF, 0xFF, 0x2A, 0x68, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA6, 0x46, 0xE8, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x5C, 0x21, 0x88, 0x5D, 0x07, 0x28, 0x01, 0xD1, 0x09, 0x20, 0x00, 0xE0, 0x05, 0x20, 0xAA, 0x69, 0x88, 0x54, 0x30, 0x1C, 0xA6, 0x46, 0xE9, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x68, 0x60, 0xE8, 0x48 , -0x4D, 0x30, 0x70, 0xBD, 0xF0, 0xB5, 0x41, 0x68, 0x82, 0x68, 0x88, 0x23, 0x5E, 0x18, 0x37, 0x88, 0x0B, 0x6F, 0x00, 0x2B, 0x01, 0xD1, 0x00, 0x2F, 0x10, 0xD1, 0x06, 0x2F, 0x02, 0xDD, 0x00, 0x21, 0xC9, 0x43, 0x07, 0xE0, 0x33, 0x88, 0x9B, 0x00, 0xC9, 0x18, 0x0A, 0x67, 0x31, 0x88, 0x01, 0x31, 0x31, 0x80, 0x01, 0x21, 0x81, 0x60, 0xE1, 0x48, 0x1D, 0x30, 0xF0, 0xBD, 0x0B, 0x1C, 0x01, 0x24, 0x5D, 0x6F, 0x1D, 0x67, 0x04, 0x33, 0x01, 0x34, 0x06, 0x2C, 0xE1, 0xDA, 0xF8, 0xE7, 0x00, 0xB5, 0x00, 0x21, 0xC1, 0x60, 0xE9, 0x48, 0x01, 0x68, 0x10, 0x31, 0xE6, 0x48, 0x20, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xE7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE5, 0x48, 0xFB, 0x30, 0x00, 0xBD, 0xFF, 0xFF, 0xC0, 0x68, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x14, 0x0D, 0x1B, 0x00, 0x54, 0x19, 0x1B, 0x00, 0x91, 0x1A, 0x01, 0x00, 0x4B, 0xAD, 0x03, 0x00, 0x61, 0x4E, 0x01, 0x00, 0x06, 0x32, 0x08, 0x00, 0x1F, 0x0B, 0x02, 0x00, 0x54, 0x3F , -0x08, 0x00, 0x45, 0xC1, 0x00, 0x00, 0x84, 0x3C, 0x08, 0x00, 0x1B, 0x02, 0x00, 0x00, 0xED, 0x17, 0x00, 0x00, 0xF3, 0xC1, 0x01, 0x00, 0x34, 0x19, 0x1B, 0x00, 0x08, 0x19, 0x1B, 0x00, 0xA6, 0x44, 0x08, 0x00, 0x1C, 0x17, 0x1B, 0x00, 0x18, 0x17, 0x1B, 0x00, 0xCB, 0x67, 0x03, 0x00, 0x0D, 0x47, 0x02, 0x00, 0x39, 0x42, 0x03, 0x00, 0xBD, 0xE7, 0x02, 0x00, 0xB1, 0x40, 0x03, 0x00, 0xB9, 0xEA, 0x01, 0x00, 0x45, 0xDA, 0x00, 0x00, 0x24, 0x41, 0x08, 0x00, 0x71, 0xC0, 0x02, 0x00, 0xF0, 0xB5, 0x88, 0xB0, 0x06, 0x91, 0x07, 0x90, 0x86, 0x69, 0xF0, 0x1C, 0xD9, 0xA1, 0x04, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x14, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x32, 0xD1, 0xF2, 0x79, 0xD7, 0x48, 0x02, 0x70, 0x35, 0x7A, 0x77, 0x7A, 0x78, 0x1B, 0xFF, 0xFF, 0x56, 0x69, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x43, 0x1C, 0x93, 0x42, 0x1D, 0xD0, 0x16, 0x2A, 0x0C, 0xDB, 0x00, 0x2D, 0x0A, 0xD1, 0xD6, 0x48, 0x04, 0x70, 0x0A, 0x20 , -0x81, 0x19, 0xD0, 0x48, 0x1A, 0x1C, 0xA6, 0x46, 0xB8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x74, 0xE0, 0xD2, 0x48, 0x04, 0x70, 0xCC, 0x48, 0x40, 0x19, 0x0A, 0x21, 0x89, 0x19, 0x7A, 0x1B, 0x52, 0x1C, 0xA6, 0x46, 0xB1, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x67, 0xE0, 0x8F, 0xC6, 0x03, 0x00, 0xC9, 0x48, 0x04, 0x70, 0xC9, 0x48, 0x04, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xC2, 0x48, 0xA6, 0x46, 0xAA, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x59, 0xE0, 0xF0, 0x1C, 0x03, 0x21, 0x0A, 0x1C, 0xBC, 0xA1, 0xA6, 0x46, 0xC6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x4F, 0xD1, 0xF1, 0x79, 0xBB, 0x48, 0x01, 0x70, 0xBB, 0x4D, 0xB2, 0x79, 0x2A, 0x70, 0x03, 0x20, 0x17, 0x49, 0xF4, 0x31, 0xA6, 0x46, 0xB8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x28, 0x78, 0x00, 0x28, 0x0B, 0xD1, 0xFF, 0xE7, 0xB8, 0x49, 0x0C, 0x70, 0xB8, 0x49, 0xFF, 0xFF, 0xEC, 0x69, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0C, 0x70, 0x03, 0x20, 0x0F, 0x49, 0xF5, 0x31, 0xA6, 0x46 , -0xB6, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x20, 0x1C, 0xF2, 0x79, 0x35, 0x7A, 0x77, 0x7A, 0x79, 0x1B, 0x4B, 0x1C, 0x93, 0x42, 0x20, 0xD0, 0xA9, 0x49, 0x09, 0x78, 0x16, 0x29, 0x0F, 0xDB, 0x00, 0x2D, 0x0D, 0xD1, 0xAB, 0x49, 0x08, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xE9, 0x48, 0x1A, 0x1C, 0xA6, 0x46, 0x8B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x1A, 0xE0, 0xC0, 0x46, 0xC7, 0x04, 0x00, 0x00, 0xA5, 0x49, 0x08, 0x70, 0xE3, 0x48, 0x40, 0x19, 0x0A, 0x21, 0x89, 0x19, 0x7A, 0x1B, 0x52, 0x1C, 0xA6, 0x46, 0x83, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x0A, 0xE0, 0x9E, 0x49, 0x08, 0x70, 0x9E, 0x49, 0x08, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xDB, 0x48, 0xA6, 0x46, 0x7D, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x96, 0x48, 0x00, 0x78, 0x00, 0x28, 0x0A, 0xD0, 0x95, 0x48, 0x00, 0x78, 0x00, 0x28, 0x06, 0xD0, 0x94, 0x48, 0x00, 0x78, 0x00, 0x28, 0x02, 0xD0, 0x93, 0x48, 0x00, 0x78, 0x00, 0x28, 0xFF, 0xFF, 0x82, 0x6A, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00 , -0x00, 0xD1, 0x8C, 0xE0, 0x03, 0x20, 0x17, 0x21, 0x89, 0x01, 0xA6, 0x46, 0x90, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x87, 0x48, 0x01, 0x78, 0x87, 0x48, 0x07, 0x78, 0x84, 0x4E, 0x83, 0x4D, 0xE0, 0x48, 0x00, 0x68, 0x00, 0x28, 0x2E, 0xD1, 0x07, 0x98, 0x41, 0x61, 0x06, 0x62, 0xC6, 0x48, 0x06, 0x9A, 0x10, 0x64, 0x02, 0x2F, 0x01, 0xD0, 0x03, 0x2F, 0x01, 0xD1, 0x03, 0x22, 0x00, 0xE0, 0x3A, 0x1C, 0x06, 0x9B, 0xDA, 0x63, 0x2A, 0x78, 0x9A, 0x63, 0x01, 0x2F, 0x03, 0xD1, 0x05, 0x29, 0x04, 0xD0, 0x0D, 0x29, 0x02, 0xD0, 0xEC, 0x48, 0xDB, 0x30, 0x64, 0xE0, 0x00, 0x25, 0x00, 0x95, 0x01, 0x91, 0x02, 0x96, 0x03, 0x95, 0x04, 0x90, 0x2B, 0x1C, 0x20, 0x1C, 0x01, 0x1C, 0x8E, 0x46, 0xE6, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0xE6, 0x48, 0x04, 0x60, 0x28, 0x1C, 0xA6, 0x46, 0xE5, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x4C, 0xE0, 0x0D, 0x27, 0x00, 0x20, 0x39, 0x1C, 0x05, 0xAA, 0xA6, 0x46, 0xE3, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x68, 0x46 , -0xFF, 0xFF, 0x18, 0x6B, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x80, 0x8A, 0x40, 0x08, 0x05, 0xD2, 0x38, 0x1C, 0x50, 0x21, 0xA6, 0x46, 0xDC, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x38, 0x1C, 0x21, 0x1C, 0x0B, 0x1C, 0x29, 0x1C, 0x00, 0x22, 0xA6, 0x46, 0xD9, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x2B, 0x78, 0x0D, 0x20, 0x31, 0x1C, 0x22, 0x1C, 0xA6, 0x46, 0xD5, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x28, 0x78, 0x01, 0x30, 0x02, 0x1C, 0x0D, 0x20, 0x57, 0x49, 0x23, 0x1C, 0xA6, 0x46, 0xD0, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x55, 0x4E, 0x28, 0x78, 0x02, 0x30, 0x02, 0x1C, 0x0D, 0x20, 0x31, 0x1C, 0x23, 0x1C, 0xA6, 0x46, 0xCA, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x30, 0x78, 0x00, 0x28, 0x0A, 0xD0, 0x28, 0x78, 0x03, 0x30, 0x02, 0x1C, 0x4C, 0x48, 0x03, 0x78, 0x0D, 0x20, 0x8F, 0x49, 0xA6, 0x46, 0xC3, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0xBF, 0x48, 0x04, 0x60, 0x00, 0x20, 0xA6, 0x46, 0xBE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xB9, 0x48, 0xEC, 0x49 , -0x08, 0x18, 0x08, 0xB0, 0xF0, 0xBD, 0xC0, 0x46, 0x7B, 0xC0, 0xFF, 0xFF, 0xAE, 0x6B, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x1C, 0xE9, 0x48, 0x02, 0x68, 0xE9, 0x48, 0x00, 0x2A, 0x04, 0xD0, 0x00, 0x22, 0x0A, 0x62, 0x8A, 0x61, 0x1D, 0x30, 0xF7, 0x46, 0xD7, 0x30, 0xF7, 0x46, 0xC0, 0x46, 0x9F, 0x03, 0x00, 0x00, 0x7D, 0xB8, 0x03, 0x00, 0x01, 0x1C, 0xE2, 0x48, 0x02, 0x68, 0xE2, 0x48, 0x00, 0x2A, 0x02, 0xD0, 0xFF, 0x30, 0xB4, 0x30, 0xF7, 0x46, 0x00, 0x22, 0xCA, 0x61, 0x8A, 0x61, 0x4F, 0x30, 0xF7, 0x46, 0xC9, 0x21, 0x01, 0x00, 0x91, 0xE1, 0x00, 0x00, 0xDB, 0x48, 0x01, 0x68, 0x8A, 0x69, 0x01, 0x20, 0xC0, 0x03, 0x10, 0x43, 0x88, 0x61, 0x00, 0x20, 0x08, 0x61, 0xD8, 0x48, 0x23, 0x30, 0xF7, 0x46, 0x89, 0x17, 0x02, 0x00, 0x70, 0xB5, 0x05, 0x1C, 0xD5, 0x4E, 0x29, 0x6A, 0xEA, 0x69, 0x30, 0x1C, 0x01, 0x24, 0xA6, 0x46, 0x0B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x68, 0x69, 0xA6, 0x46, 0xD1, 0x49 , -0xFE, 0x44, 0x08, 0x47, 0xA8, 0x69, 0x06, 0x30, 0xA8, 0x60, 0xCF, 0x48, 0x00, 0x68, 0x68, 0x60, 0xEE, 0x60, 0xCE, 0x48, 0xFF, 0xFF, 0x44, 0x6C, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x6D, 0x30, 0x70, 0xBD, 0x46, 0x17, 0x1B, 0x00, 0x30, 0x3F, 0x08, 0x00, 0x41, 0xEB, 0x00, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x30, 0xB5, 0xEE, 0x48, 0x01, 0x6D, 0x80, 0x6C, 0x08, 0x43, 0x18, 0xD0, 0xEC, 0x49, 0x08, 0x1C, 0x07, 0x22, 0xFF, 0x23, 0x09, 0x33, 0x1B, 0x58, 0x00, 0x2B, 0x04, 0xD0, 0xFF, 0x30, 0x1D, 0x30, 0x01, 0x3A, 0xF6, 0xD1, 0x0B, 0xE0, 0x02, 0x20, 0xF0, 0x4A, 0xF1, 0x4B, 0x01, 0x24, 0xA6, 0x46, 0xF0, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0xA6, 0x46, 0xEF, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xEF, 0x48, 0xFF, 0x30, 0x5C, 0x30, 0x30, 0xBD, 0xC0, 0x46, 0x53, 0x53, 0x49, 0x44, 0x00, 0xC0, 0x46, 0xC0, 0x4B, 0x45, 0x59, 0x00, 0xEE, 0x62, 0x08, 0x00, 0xF0, 0x62, 0x08, 0x00, 0xEC, 0x62, 0x08, 0x00, 0xED, 0x62, 0x08, 0x00 , -0xE7, 0x7E, 0x03, 0x00, 0xE8, 0x62, 0x08, 0x00, 0xE9, 0x62, 0x08, 0x00, 0xEA, 0x62, 0x08, 0x00, 0xEB, 0x62, 0x08, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0xF0, 0xB5, 0xFF, 0xFF, 0xDA, 0x6C, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x87, 0xB0, 0x00, 0x91, 0x01, 0x90, 0x6B, 0x48, 0x01, 0x68, 0xCC, 0x4A, 0x14, 0x1C, 0x02, 0x94, 0x07, 0x26, 0x00, 0x25, 0x03, 0x95, 0x04, 0x94, 0x05, 0x95, 0xDF, 0x48, 0x00, 0x68, 0x08, 0x43, 0x27, 0xD0, 0xE0, 0x68, 0x03, 0x99, 0x88, 0x42, 0x0A, 0xDD, 0x03, 0x90, 0x40, 0x1C, 0x00, 0x99, 0x88, 0x60, 0xC2, 0x49, 0xFF, 0x20, 0x1D, 0x30, 0x68, 0x43, 0x0C, 0x18, 0xE0, 0x68, 0x04, 0x91, 0x02, 0x99, 0xC9, 0x68, 0x88, 0x42, 0x10, 0xDB, 0x88, 0x42, 0x10, 0xD1, 0x02, 0x98, 0x01, 0x27, 0xBE, 0x46, 0xCE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x06, 0x90, 0x20, 0x1C, 0xBE, 0x46, 0xCB, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x06, 0x99, 0x88, 0x42, 0x01, 0xDA, 0x05, 0x95, 0x02, 0x94 , -0x51, 0x48, 0x01, 0x68, 0xFF, 0x27, 0x09, 0x37, 0x38, 0x59, 0x00, 0x28, 0x06, 0xD0, 0xC7, 0x48, 0x00, 0x68, 0x07, 0x2E, 0x00, 0xD1, 0x2E, 0x1C, 0x08, 0x43, 0x04, 0xD0, 0xFF, 0x34, 0x1D, 0x34, 0x01, 0x35, 0x07, 0x2D, 0xC2, 0xDB, 0x07, 0x2E, 0xFF, 0xFF, 0x70, 0x6D, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0A, 0xD1, 0xC0, 0x48, 0x00, 0x68, 0x08, 0x43, 0x06, 0xD0, 0x05, 0x9E, 0x30, 0x1C, 0x01, 0x21, 0x8E, 0x46, 0xBA, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x98, 0x47, 0x61, 0x00, 0x21, 0x81, 0x61, 0xFF, 0x22, 0x1D, 0x32, 0x72, 0x43, 0x04, 0x99, 0x89, 0x18, 0xC1, 0x61, 0x06, 0x62, 0xB4, 0x48, 0x39, 0x30, 0x07, 0xB0, 0xF0, 0xBD, 0x10, 0xB5, 0x04, 0x1C, 0x00, 0x20, 0x01, 0x21, 0x8E, 0x46, 0xB1, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x40, 0x1E, 0x00, 0xD5, 0x00, 0x20, 0x60, 0x60, 0xE0, 0x61, 0xAE, 0x48, 0x21, 0x30, 0x10, 0xBD, 0xC0, 0x46, 0x10, 0x63, 0x08, 0x00, 0x70, 0xB5, 0x04, 0x1C, 0xE5, 0x69, 0x66, 0x69 , -0x00, 0x20, 0x01, 0x21, 0x8E, 0x46, 0xA7, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x60, 0x60, 0xAB, 0x19, 0xA6, 0x4A, 0xA5, 0x49, 0x93, 0x42, 0x02, 0xD3, 0x9A, 0x1A, 0x82, 0x42, 0x02, 0xD9, 0x08, 0x1C, 0x99, 0x30, 0x70, 0xBD, 0x08, 0x1C, 0xAB, 0x30, 0x70, 0xBD, 0x08, 0x6B, 0x41, 0x7D, 0x02, 0x88, 0x92, 0x00, 0xFF, 0xFF, 0x06, 0x6E, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x51, 0x1A, 0x3C, 0x39, 0xFF, 0x22, 0x5F, 0x32, 0x91, 0x42, 0x03, 0xD9, 0x65, 0x21, 0x01, 0x80, 0x02, 0x21, 0x81, 0x73, 0x9B, 0x48, 0x99, 0x49, 0x08, 0x18, 0xF7, 0x46, 0xC0, 0x46, 0x30, 0x63, 0x08, 0x00, 0xF8, 0xB5, 0x40, 0x68, 0x24, 0x21, 0x41, 0x43, 0x97, 0x48, 0x45, 0x18, 0x28, 0x1D, 0x0C, 0x21, 0x49, 0x19, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x94, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x91, 0x4C, 0x00, 0x28, 0x1B, 0xD0, 0x2B, 0x1C, 0x04, 0x22, 0x6E, 0x46, 0x91, 0x49, 0x1F, 0x7B, 0x08, 0x78, 0xC0, 0x43, 0x38, 0x43, 0x30, 0x70, 0x01, 0x33 , -0x01, 0x31, 0x01, 0x36, 0x01, 0x3A, 0xF5, 0xD1, 0x0C, 0x20, 0x41, 0x19, 0x68, 0x46, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x87, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x02, 0xD0, 0x20, 0x1C, 0x4A, 0x30, 0xF8, 0xBD, 0x20, 0x1C, 0xF8, 0xBD, 0xB1, 0xBD, 0x00, 0x00, 0x15, 0x95, 0x00, 0x00, 0x58, 0x3F, 0x08, 0x00, 0xF3, 0xF8, 0x00, 0x00, 0xE9, 0x09, 0x02, 0x00, 0xFF, 0xFF, 0x9C, 0x6E, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x2B, 0x09, 0x02, 0x00, 0xDD, 0x0A, 0x02, 0x00, 0xF8, 0xB5, 0x05, 0x1C, 0xAA, 0x69, 0x7D, 0x49, 0x00, 0x20, 0x08, 0x56, 0x24, 0x21, 0x41, 0x43, 0x76, 0x48, 0x43, 0x18, 0x04, 0x24, 0x6E, 0x46, 0x76, 0x49, 0x1F, 0x79, 0x08, 0x78, 0xC0, 0x43, 0x38, 0x43, 0x30, 0x70, 0x01, 0x33, 0x01, 0x31, 0x01, 0x36, 0x01, 0x3C, 0xF5, 0xD1, 0x11, 0x1D, 0x68, 0x46, 0x04, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x6D, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x01, 0x1C, 0x6D, 0x48, 0x04, 0xD0, 0x6E, 0x49, 0x09, 0x78 , -0x69, 0x60, 0x45, 0x30, 0xF8, 0xBD, 0xEC, 0x61, 0xAF, 0x30, 0xF8, 0xBD, 0x70, 0xB5, 0xC5, 0x68, 0x81, 0x68, 0x0A, 0x89, 0x6D, 0x4E, 0x00, 0x2A, 0x22, 0xD0, 0x01, 0x24, 0xC2, 0x6D, 0xA2, 0x18, 0xC2, 0x65, 0x08, 0x89, 0x0D, 0x28, 0x1B, 0xD1, 0x68, 0x6B, 0x21, 0x1C, 0xA6, 0x46, 0x63, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x22, 0x1C, 0x28, 0x1C, 0x00, 0x21, 0xA6, 0x46, 0x60, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x2C, 0x60, 0xE9, 0x6B, 0xFF, 0xFF, 0x32, 0x6F, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x28, 0x1C, 0xA6, 0x46, 0x5E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x28, 0x1C, 0xA6, 0x46, 0x5C, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x30, 0x1C, 0x3D, 0x30, 0x70, 0xBD, 0x30, 0x1C, 0x23, 0x30, 0x70, 0xBD, 0xC0, 0x46, 0xB1, 0x02, 0x00, 0x00, 0x74, 0x3F, 0x08, 0x00, 0x19, 0xC6, 0x00, 0x00, 0x5C, 0x3F, 0x08, 0x00, 0x1D, 0xC2, 0x00, 0x00, 0x68, 0x44, 0x08, 0x00, 0x43, 0x12, 0x03, 0x00, 0x34, 0x63, 0x08, 0x00, 0x2F, 0x7A, 0x02, 0x00 , -0xB4, 0x36, 0x08, 0x00, 0x8F, 0xF4, 0x01, 0x00, 0xF0, 0xB5, 0x05, 0x1C, 0xAB, 0x69, 0xEC, 0x69, 0x60, 0x68, 0x00, 0x68, 0x2A, 0x30, 0x01, 0x78, 0x0A, 0x06, 0x41, 0x78, 0x09, 0x04, 0x8A, 0x18, 0x81, 0x78, 0x09, 0x02, 0x8A, 0x18, 0xC1, 0x78, 0x8A, 0x18, 0x8E, 0x26, 0xF1, 0x5A, 0x09, 0x0A, 0x01, 0x70, 0xF0, 0x5C, 0x61, 0x68, 0x09, 0x68, 0x2B, 0x26, 0x70, 0x54, 0x8C, 0x20, 0xC0, 0x18, 0x61, 0x68, 0x0E, 0x68, 0x01, 0x88, 0x09, 0x0A, 0x2C, 0x27, 0xB9, 0x55, 0x61, 0x68, 0x09, 0x68, 0xFF, 0xFF, 0xC8, 0x6F, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x2D, 0x26, 0x00, 0x78, 0x70, 0x54, 0x60, 0x68, 0x01, 0x68, 0x32, 0x31, 0x08, 0x78, 0x00, 0x02, 0x49, 0x78, 0x08, 0x18, 0x00, 0x04, 0x00, 0x0C, 0x8C, 0x21, 0xCB, 0x58, 0x35, 0x49, 0x41, 0x40, 0x08, 0x04, 0x00, 0x0C, 0xC0, 0x18, 0x80, 0x1A, 0x01, 0x21, 0x8E, 0x46, 0x32, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x61, 0x68, 0x0A, 0x68, 0x32, 0x23, 0x01, 0x0A, 0x99, 0x54 , -0x61, 0x68, 0x09, 0x68, 0x33, 0x22, 0x50, 0x54, 0x60, 0x68, 0x68, 0x60, 0x2C, 0x48, 0xF0, 0xBD, 0x00, 0x00, 0x1B, 0x00, 0x34, 0x04, 0x1B, 0x00, 0x02, 0x6A, 0x8B, 0x69, 0xDB, 0x69, 0x1B, 0x68, 0x83, 0x60, 0x88, 0x69, 0xC0, 0x69, 0x41, 0x68, 0x8A, 0x42, 0x00, 0xDA, 0x42, 0x60, 0x25, 0x48, 0x79, 0x30, 0xF7, 0x46, 0x24, 0x48, 0x57, 0x30, 0xF7, 0x46, 0x24, 0x48, 0x91, 0x30, 0xF7, 0x46, 0x32, 0x04, 0x00, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x15, 0x09, 0x02, 0x00, 0xC5, 0x93, 0x00, 0x00, 0x0D, 0x91, 0x00, 0x00, 0x40, 0x1E, 0x80, 0x00, 0x1E, 0x4B, 0xFF, 0xFF, 0x5E, 0x70, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x19, 0x50, 0x1C, 0x49, 0x0A, 0x50, 0xF7, 0x46, 0xC0, 0x46, 0xBD, 0xB5, 0x00, 0x00, 0x95, 0x92, 0x00, 0x00, 0xFD, 0x93, 0x00, 0x00, 0x54, 0x3F, 0x08, 0x00, 0x29, 0x4F, 0x03, 0x00, 0xDF, 0xE8, 0x02, 0x00, 0x36, 0x89, 0x41, 0x00, 0x81, 0x06, 0x00, 0x00, 0xB1, 0x78, 0x00, 0x00, 0x94, 0xEC, 0x01, 0x00 , -0x08, 0x19, 0x1B, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0x1C, 0x17, 0x1B, 0x00, 0x67, 0x66, 0x03, 0x00, 0xA6, 0x44, 0x08, 0x00, 0x18, 0x17, 0x1B, 0x00, 0xA7, 0x2F, 0x02, 0x00, 0x91, 0x44, 0x03, 0x00, 0x91, 0x63, 0x03, 0x00, 0x5B, 0x44, 0x03, 0x00, 0xE7, 0x44, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x61, 0xA2, 0x03, 0x00, 0x6A, 0x1E, 0x01, 0x00, 0x45, 0xDA, 0x00, 0x00, 0xD7, 0xE8, 0x01, 0x00, 0xE9, 0x78, 0x02, 0x00, 0x04, 0xF3, 0x1A, 0x00, 0x80, 0x7B, 0x08, 0x00, 0xFC, 0xB5, 0x04, 0x1C, 0xA5, 0x69, 0x60, 0x6A, 0x01, 0x90, 0x20, 0x69, 0x00, 0x28, 0x35, 0xD4, 0x08, 0x28, 0x33, 0xDA, 0xE1, 0x69, 0x09, 0x68, 0xFF, 0xFF, 0xF4, 0x70, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x10, 0x29, 0x2F, 0xD1, 0xAC, 0x21, 0x41, 0x43, 0x9E, 0x4A, 0x51, 0x5C, 0x49, 0x08, 0x27, 0xD3, 0x00, 0x06, 0x00, 0x16, 0xA2, 0x68, 0x69, 0x46, 0x01, 0x23, 0x9E, 0x46, 0x9A, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x06, 0x1C, 0x39, 0x30, 0x1F, 0xD0 , -0x00, 0x2E, 0x1D, 0xD0, 0x00, 0x98, 0x07, 0x68, 0x00, 0x99, 0x0C, 0x39, 0x01, 0x98, 0x01, 0x60, 0x28, 0x1D, 0x10, 0x21, 0x79, 0x1A, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x91, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x22, 0x2A, 0x80, 0xA8, 0x1C, 0x08, 0x21, 0x79, 0x1A, 0x01, 0x23, 0x9E, 0x46, 0x8C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x03, 0xE0, 0x38, 0x20, 0x00, 0xE0, 0x00, 0x20, 0xC6, 0x43, 0x26, 0x60, 0x89, 0x48, 0x7C, 0x30, 0x20, 0x62, 0xFC, 0xBD, 0x30, 0xB5, 0x05, 0x1C, 0x28, 0x69, 0xA9, 0x69, 0x90, 0x29, 0x1D, 0xD1, 0x69, 0x69, 0x09, 0x78, 0x04, 0x29, 0x19, 0xD0, 0x05, 0x29, 0x17, 0xD0, 0x0A, 0x29, 0x15, 0xD0, 0x06, 0x29, 0x13, 0xD0, 0x0C, 0x29, 0x01, 0xDB, 0xFF, 0xFF, 0x8A, 0x71, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x10, 0x29, 0x0F, 0xD1, 0x01, 0x24, 0xA6, 0x46, 0x7D, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x7C, 0x48, 0x7D, 0x49, 0x00, 0x22, 0xA6, 0x46, 0x7C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x7C, 0x48 , -0xFF, 0x30, 0x5F, 0x30, 0x28, 0x62, 0x30, 0xBD, 0xF0, 0xB5, 0x89, 0xB0, 0x05, 0x90, 0x41, 0x69, 0x02, 0x69, 0x75, 0x48, 0x79, 0x4E, 0x82, 0x42, 0x3A, 0xD0, 0x04, 0x30, 0x82, 0x42, 0x25, 0xD0, 0x74, 0x4D, 0xAA, 0x42, 0x00, 0xD0, 0xCC, 0xE0, 0x08, 0x68, 0x06, 0x1C, 0x0C, 0x22, 0x8F, 0x1A, 0x4A, 0x68, 0x89, 0x18, 0x09, 0x1D, 0x10, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x6E, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x01, 0x1C, 0x09, 0xD1, 0xAC, 0x22, 0x72, 0x43, 0xCB, 0x48, 0x80, 0x18, 0x46, 0x22, 0x12, 0x5C, 0x11, 0x2A, 0x01, 0xD1, 0x44, 0x22, 0x14, 0x54, 0x28, 0x1C, 0x3A, 0x1C, 0xA6, 0x46, 0x62, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x69, 0x48, 0xEC, 0x30, 0xAB, 0xE0, 0x08, 0x68, 0xC0, 0x00, 0x30, 0x18, 0x8A, 0x68, 0x02, 0x2A, 0x02, 0xD0, 0xFF, 0xFF, 0x20, 0x72, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xE7, 0x20, 0x80, 0x00, 0xA2, 0xE0, 0xCA, 0x68, 0x89, 0x18, 0x09, 0x7B, 0x41, 0x60, 0x80, 0x21, 0x01, 0x60, 0x3B, 0x20 , -0x00, 0x01, 0x99, 0xE0, 0x08, 0x68, 0x06, 0x90, 0xC0, 0x00, 0x34, 0x58, 0x10, 0x20, 0x04, 0x90, 0x01, 0x25, 0xAE, 0x46, 0x57, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x07, 0x90, 0x00, 0x28, 0x00, 0xD1, 0x89, 0xE0, 0x0C, 0x21, 0x07, 0x98, 0x0F, 0x18, 0xB0, 0x49, 0xAC, 0x20, 0x06, 0x9A, 0x50, 0x43, 0x08, 0x18, 0x48, 0x22, 0x13, 0x5C, 0x5B, 0x06, 0x5B, 0x0E, 0x13, 0x54, 0x06, 0x9A, 0xD2, 0x00, 0xB6, 0x18, 0x71, 0x68, 0x00, 0x29, 0x47, 0xD1, 0x00, 0x2C, 0x01, 0xDD, 0x08, 0x2C, 0x21, 0xDB, 0x00, 0x22, 0x69, 0x46, 0x0A, 0x70, 0x01, 0x92, 0x0A, 0x81, 0x8A, 0x72, 0xCD, 0x72, 0x0D, 0x73, 0x4D, 0x73, 0x01, 0x88, 0x44, 0x48, 0x06, 0x23, 0xAE, 0x46, 0x44, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x04, 0x1C, 0x02, 0xDC, 0x00, 0x20, 0xC0, 0x43, 0x36, 0xE0, 0x34, 0x60, 0xAC, 0x20, 0x60, 0x43, 0x9A, 0x49, 0xFF, 0xFF, 0xB6, 0x72, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x09, 0x18, 0x5C, 0x22, 0x28, 0x1C, 0x50, 0x54, 0x48, 0x20 , -0x42, 0x5C, 0x52, 0x06, 0x52, 0x0E, 0x42, 0x54, 0xAC, 0x20, 0x60, 0x43, 0x94, 0x49, 0x08, 0x18, 0x5C, 0x21, 0x09, 0x5C, 0x49, 0x1E, 0x02, 0x29, 0x16, 0xD9, 0x03, 0x39, 0x08, 0xD0, 0x00, 0x20, 0x30, 0x56, 0xAE, 0x46, 0xEA, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x80, 0x20, 0x30, 0x60, 0xDB, 0xE7, 0x08, 0x94, 0x80, 0x21, 0x31, 0x60, 0x48, 0x22, 0x13, 0x5C, 0x19, 0x43, 0x11, 0x54, 0xAE, 0x46, 0xE4, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x0A, 0xE0, 0x01, 0x20, 0xCE, 0xE7, 0x06, 0x98, 0x39, 0x1C, 0x04, 0xAA, 0xAE, 0x46, 0xE0, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x1C, 0x08, 0x90, 0x06, 0x98, 0x38, 0x60, 0x08, 0x98, 0x78, 0x60, 0x00, 0x28, 0x15, 0xD0, 0xAC, 0x20, 0x60, 0x43, 0x7C, 0x49, 0x09, 0x18, 0x48, 0x88, 0x02, 0x04, 0x02, 0x20, 0x10, 0x43, 0xB8, 0x60, 0x48, 0x68, 0x02, 0x0E, 0x01, 0x02, 0x09, 0x0E, 0x09, 0x02, 0x11, 0x43, 0x02, 0x04, 0x12, 0x0E, 0xFF, 0xFF, 0x4C, 0x73, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00 , -0x12, 0x04, 0x0A, 0x43, 0x00, 0x06, 0x10, 0x43, 0xF8, 0x60, 0x07, 0x98, 0x0D, 0x49, 0x00, 0x22, 0x10, 0x23, 0xAE, 0x46, 0xCE, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x13, 0x48, 0x00, 0xE0, 0x16, 0x20, 0xCC, 0x49, 0x09, 0x18, 0x05, 0x98, 0x01, 0x62, 0x09, 0xB0, 0xF0, 0xBD, 0x5D, 0x0D, 0x1B, 0x00, 0x81, 0xE7, 0x02, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x27, 0x1A, 0x02, 0x00, 0x2F, 0x7A, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0xD5, 0xF4, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x91, 0x19, 0x02, 0x00, 0x50, 0x65, 0x08, 0x00, 0x71, 0xC0, 0x02, 0x00, 0x50, 0x19, 0x1B, 0x00, 0x29, 0x16, 0x01, 0x00, 0x2A, 0x03, 0x00, 0x00, 0xF0, 0xB5, 0x8B, 0xB0, 0x07, 0x90, 0x05, 0x69, 0x47, 0x69, 0x0C, 0x20, 0x38, 0x1A, 0x08, 0x90, 0xB6, 0x49, 0x8D, 0x42, 0x16, 0xD1, 0x78, 0x68, 0x0F, 0x30, 0x00, 0x11, 0x00, 0x01, 0x78, 0x60, 0x38, 0x68, 0x0B, 0x28, 0x0E, 0xD8, 0x00, 0x23, 0x68, 0x46 , -0xFF, 0xFF, 0xE2, 0x73, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x03, 0x70, 0x08, 0x98, 0x05, 0x22, 0x01, 0x24, 0xA6, 0x46, 0xAE, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0xAE, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0x08, 0x62, 0xAC, 0x48, 0x85, 0x42, 0x23, 0xD1, 0xAC, 0x48, 0x02, 0x78, 0x6C, 0x46, 0x22, 0x72, 0x43, 0x78, 0x63, 0x72, 0x81, 0x78, 0xA1, 0x72, 0xC0, 0x78, 0xE0, 0x72, 0x00, 0x91, 0x01, 0x90, 0x03, 0x20, 0xA6, 0x49, 0x01, 0x39, 0x01, 0x26, 0xB6, 0x46, 0xF3, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x04, 0x20, 0x20, 0x70, 0x08, 0x98, 0x9F, 0x49, 0x00, 0x22, 0x02, 0xAB, 0x01, 0x24, 0xA6, 0x46, 0x9B, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x9A, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0x08, 0x62, 0xEB, 0x49, 0x8D, 0x42, 0x14, 0xD1, 0x02, 0x22, 0x68, 0x46, 0x02, 0x70, 0x3A, 0x68, 0xAC, 0x20, 0x42, 0x43, 0x30, 0x48, 0x68, 0x30, 0x83, 0x18, 0x08, 0x98, 0x00, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x8F, 0x4C, 0xFE, 0x44 , -0x20, 0x47, 0x8E, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0xFF, 0xFF, 0x78, 0x74, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x08, 0x62, 0xEF, 0x48, 0x85, 0x42, 0x00, 0xD0, 0x04, 0xE1, 0x03, 0x20, 0x8C, 0x49, 0x01, 0x22, 0x96, 0x46, 0xEC, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x86, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x09, 0x90, 0x38, 0x68, 0xEA, 0x4D, 0x00, 0x28, 0x00, 0xD1, 0xE2, 0xE0, 0x01, 0x24, 0xA6, 0x46, 0xE6, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x00, 0x28, 0x00, 0xD1, 0xD6, 0xE0, 0xE4, 0x48, 0x02, 0x68, 0x03, 0x20, 0x7F, 0x49, 0x01, 0x31, 0xA6, 0x46, 0xE2, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xDF, 0x48, 0x00, 0x68, 0x00, 0x28, 0x5A, 0xD1, 0xDF, 0x4D, 0x2E, 0x20, 0x41, 0x19, 0xB8, 0x68, 0x03, 0x30, 0x08, 0x70, 0x38, 0x7A, 0x48, 0x70, 0x2E, 0x1C, 0x30, 0x36, 0xB8, 0x68, 0x28, 0x18, 0x30, 0x30, 0xDA, 0x49, 0x0A, 0x68, 0x30, 0x3A, 0x31, 0x1C, 0xA6, 0x46, 0xD8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x78, 0x68, 0x38, 0x18 , -0x01, 0x1D, 0xBA, 0x68, 0x30, 0x1C, 0xA6, 0x46, 0xD9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xB8, 0x68, 0x41, 0x19, 0x97, 0x22, 0xFF, 0xFF, 0x0E, 0x75, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x09, 0x30, 0x50, 0x54, 0xB8, 0x68, 0x46, 0x19, 0x9E, 0x36, 0x30, 0x70, 0x01, 0x36, 0xB8, 0x68, 0x01, 0xE0, 0x14, 0x0D, 0x1B, 0x00, 0x30, 0x18, 0xCA, 0x49, 0x0A, 0x68, 0x9E, 0x3A, 0x31, 0x1C, 0xA6, 0x46, 0xC8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x78, 0x68, 0x38, 0x18, 0x01, 0x1D, 0xBA, 0x68, 0x30, 0x1C, 0xA6, 0x46, 0xC9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xB8, 0x68, 0x40, 0x00, 0xC0, 0x49, 0x09, 0x68, 0x08, 0x18, 0x28, 0x18, 0xC0, 0x49, 0x0A, 0x79, 0x02, 0x70, 0x4A, 0x79, 0x42, 0x70, 0x8A, 0x79, 0x82, 0x70, 0xC9, 0x79, 0xC1, 0x70, 0x04, 0x30, 0x0F, 0x21, 0x41, 0x1A, 0x0A, 0x78, 0xBB, 0x68, 0x9A, 0x18, 0x0A, 0x70, 0x40, 0x1B, 0x00, 0x04, 0x00, 0x0C, 0xB5, 0x49, 0x08, 0x60, 0xB1, 0x48, 0x04, 0x60, 0x02, 0x20, 0x01, 0x1C , -0x11, 0x22, 0xA6, 0x46, 0xB4, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x06, 0x1C, 0x63, 0xD4, 0x03, 0x20, 0xA6, 0x46, 0xB1, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x0A, 0x90, 0x00, 0x25, 0x01, 0x1C, 0xFF, 0xFF, 0xA4, 0x75, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x8D, 0x42, 0x50, 0xD0, 0x29, 0x1C, 0x2B, 0x22, 0xA6, 0x46, 0xAD, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x0C, 0x20, 0x0A, 0x99, 0x40, 0x18, 0xAC, 0x22, 0x72, 0x43, 0xAB, 0x49, 0x8F, 0x18, 0x78, 0x63, 0x29, 0x1C, 0x18, 0x22, 0xA6, 0x46, 0xA6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x9F, 0x48, 0x02, 0x68, 0x79, 0x6B, 0x4A, 0x60, 0x0A, 0x98, 0xAC, 0x30, 0x08, 0x60, 0x08, 0x68, 0x9A, 0x49, 0xA6, 0x46, 0xA0, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x29, 0x1C, 0x03, 0xA8, 0x10, 0x22, 0xA6, 0x46, 0x9C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE0, 0x21, 0x68, 0x46, 0x01, 0x74, 0x45, 0x74, 0x85, 0x74, 0xFB, 0x21, 0xC1, 0x74, 0xEE, 0x49, 0xC1, 0x81, 0x02, 0x21, 0x81, 0x81, 0x79, 0x6B, 0xCA, 0x68 , -0x01, 0x20, 0xC0, 0x03, 0x10, 0x43, 0xC8, 0x60, 0x48, 0x68, 0x00, 0x90, 0x2A, 0x1C, 0x30, 0x1C, 0x0A, 0x9D, 0x29, 0x1C, 0x03, 0xAB, 0xA6, 0x46, 0xE6, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x07, 0x1C, 0x30, 0x06, 0x00, 0x16, 0xA6, 0x46, 0xEF, 0x49, 0xFF, 0xFF, 0x3A, 0x76, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xFE, 0x44, 0x08, 0x47, 0x28, 0x1C, 0xA6, 0x46, 0xEE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x11, 0xE0, 0x30, 0x06, 0x00, 0x16, 0xA6, 0x46, 0xE9, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x20, 0xC7, 0x43, 0x08, 0xE0, 0x07, 0x1C, 0x06, 0xE0, 0x00, 0x20, 0x00, 0x21, 0xCF, 0x43, 0x01, 0xE0, 0x00, 0x20, 0x07, 0x1C, 0x28, 0x60, 0x00, 0x23, 0x68, 0x46, 0x03, 0x70, 0x3A, 0x06, 0x12, 0x0E, 0x08, 0x98, 0x6F, 0x49, 0x01, 0x24, 0xA6, 0x46, 0x09, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x07, 0x98, 0x09, 0x99, 0x01, 0x62, 0x0B, 0xB0, 0xF0, 0xBD, 0xC1, 0x18, 0x01, 0x00, 0xF1, 0x1B, 0x01, 0x00, 0xF3, 0x1C, 0x02, 0x00, 0x7B, 0xC0 , -0x02, 0x00, 0x91, 0xF0, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0xA3, 0xC0, 0x02, 0x00, 0xA9, 0xE9, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00, 0xE4, 0x62, 0x08, 0x00, 0xAC, 0x05, 0x00, 0x00, 0xFE, 0xB5, 0x07, 0x1C, 0x7D, 0x69, 0xBE, 0x69, 0x0C, 0x20, 0x30, 0x1A, 0x01, 0x90, 0xDF, 0x4C, 0x0A, 0x2D, 0x13, 0xD1, 0xFF, 0xFF, 0xD0, 0x76, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x30, 0x68, 0xDB, 0x49, 0x08, 0x60, 0x01, 0x20, 0x86, 0x46, 0xDA, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x0A, 0x20, 0x00, 0x21, 0x01, 0x9A, 0x01, 0x23, 0x9E, 0x46, 0xE6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xF5, 0x20, 0x80, 0x00, 0x00, 0x19, 0x38, 0x62, 0x03, 0x2D, 0x79, 0xD1, 0xF5, 0x20, 0x80, 0x00, 0x00, 0x19, 0x02, 0x90, 0x70, 0x68, 0x00, 0x28, 0x0C, 0xD1, 0x00, 0x21, 0xCF, 0x48, 0x01, 0x60, 0xCF, 0x48, 0x00, 0x68, 0x00, 0x28, 0x61, 0xD0, 0x01, 0x21, 0x8E, 0x46, 0xCD, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x5B, 0xE0, 0xCC, 0x48, 0xB1, 0x68, 0x01, 0x60 , -0xF1, 0x68, 0x41, 0x60, 0x31, 0x69, 0x81, 0x60, 0x71, 0x69, 0xC1, 0x60, 0xB1, 0x69, 0xC1, 0x63, 0xF1, 0x69, 0x01, 0x64, 0x31, 0x6A, 0xC1, 0x64, 0x01, 0x24, 0xA6, 0x46, 0xC5, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xA6, 0x46, 0xC4, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x70, 0x68, 0x7D, 0x25, 0xED, 0x00, 0xA8, 0x42, 0x21, 0xD8, 0x01, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0xFF, 0xFF, 0x66, 0x77, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x28, 0x1C, 0xA6, 0x46, 0xBE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x1C, 0xE0, 0xB9, 0x48, 0x00, 0x23, 0x19, 0x1C, 0x59, 0x43, 0x3E, 0x22, 0x4A, 0x43, 0x82, 0x83, 0x02, 0x30, 0x01, 0x33, 0x10, 0x2B, 0xF6, 0xDB, 0xA6, 0x46, 0xB4, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xB5, 0x48, 0x0D, 0xE0, 0xB5, 0x4D, 0x28, 0x1C, 0xA6, 0x46, 0xB2, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x04, 0xE0, 0xA6, 0x46, 0xAF, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x75, 0x68, 0xAE, 0x48, 0x05, 0x60, 0x05, 0x1C, 0xA7, 0x4E, 0x30, 0x68 , -0x00, 0x28, 0x06, 0xD1, 0xAD, 0x48, 0x00, 0x68, 0xA6, 0x46, 0xAC, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x30, 0x60, 0x00, 0x94, 0x2B, 0x68, 0xAA, 0x49, 0xAB, 0x4A, 0xA6, 0x46, 0xAB, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0x9C, 0x48, 0x04, 0x60, 0x03, 0x20, 0x00, 0x21, 0x01, 0x9A, 0x01, 0x23, 0x9E, 0x46, 0xA7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x98, 0x38, 0x62, 0xFE, 0xBD, 0xC0, 0x46, 0x13, 0x7F, 0x03, 0x00, 0x12, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x77, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x30, 0xB5, 0x05, 0x1C, 0x00, 0x20, 0x01, 0x24, 0xA6, 0x46, 0xA0, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xA6, 0x46, 0x9F, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xA6, 0x46, 0x9E, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x7D, 0x21, 0xC9, 0x00, 0xA6, 0x46, 0x9E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x9B, 0x49, 0x08, 0x18, 0x99, 0x49, 0x08, 0x80, 0x9B, 0x48, 0x0A, 0x30, 0x28, 0x62, 0x30, 0xBD, 0x11, 0x10, 0x00, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0xB9, 0x90 , -0x00, 0x00, 0x6C, 0x64, 0x08, 0x00, 0xE7, 0x7E, 0x03, 0x00, 0x74, 0x64, 0x08, 0x00, 0x70, 0x64, 0x08, 0x00, 0x6D, 0xC6, 0x03, 0x00, 0x08, 0x19, 0x1B, 0x00, 0x11, 0x18, 0x02, 0x00, 0xD1, 0x78, 0x02, 0x00, 0xC9, 0xBA, 0x03, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x14, 0x0D, 0x1B, 0x00, 0xFE, 0xB5, 0x02, 0x90, 0x45, 0x69, 0x68, 0x46, 0x01, 0x21, 0x8E, 0x46, 0x89, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x89, 0x48, 0x04, 0x1C, 0x68, 0x68, 0x01, 0x69, 0x4A, 0x78, 0x00, 0x27, 0x3E, 0x1C, 0x20, 0x88, 0xFF, 0xFF, 0x92, 0x78, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x40, 0x08, 0x22, 0xD3, 0x20, 0x1D, 0x89, 0x1C, 0x01, 0x23, 0x9E, 0x46, 0x83, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x07, 0xD1, 0x68, 0x68, 0x00, 0x69, 0x40, 0x78, 0x21, 0x88, 0x09, 0x04, 0x89, 0x16, 0x81, 0x42, 0x3D, 0xD0, 0x02, 0x20, 0x00, 0x5F, 0x00, 0x99, 0x08, 0x1A, 0x00, 0x04, 0x00, 0x14, 0x3C, 0x28, 0x03, 0xDD, 0x20, 0x88, 0x40, 0x10, 0x40, 0x00 , -0x20, 0x80, 0x78, 0x1C, 0x07, 0x06, 0x3F, 0x0E, 0x68, 0x68, 0x01, 0x69, 0x4A, 0x78, 0x2A, 0x34, 0x01, 0x36, 0x14, 0x2E, 0xD5, 0xDB, 0x00, 0x2A, 0x02, 0xD1, 0xAB, 0x20, 0x40, 0x00, 0x50, 0xE0, 0x00, 0x9B, 0x6D, 0x48, 0x14, 0x21, 0x00, 0x22, 0x04, 0x88, 0x64, 0x08, 0x03, 0xD3, 0x2A, 0x30, 0x01, 0x32, 0x01, 0x39, 0xF8, 0xD1, 0x12, 0x06, 0x12, 0x0E, 0x14, 0x2F, 0x16, 0xD1, 0x66, 0x48, 0x00, 0x88, 0x00, 0x06, 0x44, 0x16, 0x64, 0x49, 0x00, 0x22, 0x01, 0x20, 0x4E, 0x8D, 0x36, 0x06, 0x76, 0x16, 0xA6, 0x42, 0x02, 0xDD, 0x34, 0x1C, 0x02, 0x06, 0xFF, 0xFF, 0x28, 0x79, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x12, 0x0E, 0x2A, 0x31, 0x01, 0x30, 0x14, 0x28, 0xF3, 0xDB, 0x02, 0xE0, 0x32, 0x06, 0x12, 0x0E, 0x00, 0x9B, 0x2A, 0x20, 0x42, 0x43, 0x5A, 0x48, 0x11, 0x18, 0x0C, 0x88, 0x01, 0x20, 0x20, 0x43, 0x00, 0x04, 0x00, 0x0C, 0x08, 0x80, 0xFE, 0x24, 0xA0, 0x43, 0x14, 0x24, 0x64, 0x57, 0x64, 0x06, 0x24, 0x0E , -0x04, 0x43, 0x52, 0x48, 0x14, 0x52, 0x14, 0x18, 0x63, 0x80, 0x08, 0x88, 0x80, 0x05, 0x82, 0x0D, 0x68, 0x68, 0x00, 0x69, 0x40, 0x78, 0x80, 0x02, 0x10, 0x43, 0x08, 0x80, 0x68, 0x68, 0x02, 0x69, 0x20, 0x1D, 0x91, 0x1C, 0x52, 0x78, 0x01, 0x23, 0x9E, 0x46, 0x4B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x98, 0x04, 0x61, 0xFE, 0x20, 0x47, 0x49, 0x09, 0x18, 0x02, 0x98, 0x01, 0x62, 0xFE, 0xBD, 0x82, 0x69, 0x41, 0x69, 0x03, 0x69, 0x02, 0x2B, 0x0A, 0xD1, 0x01, 0x2A, 0x01, 0xD1, 0x00, 0x29, 0x05, 0xD0, 0x02, 0x2A, 0x04, 0xD1, 0x00, 0x29, 0x02, 0xD1, 0x11, 0x21, 0x00, 0xE0, 0x06, 0x21, 0x41, 0x61, 0xF7, 0x46, 0xFF, 0xFF, 0xBE, 0x79, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xC0, 0x46, 0x14, 0xE9, 0x00, 0x00, 0xC9, 0x18, 0x02, 0x00, 0x30, 0xB5, 0x05, 0x1C, 0x3A, 0x48, 0x00, 0x78, 0x00, 0x28, 0x04, 0xD0, 0x01, 0x20, 0x86, 0x46, 0x38, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x01, 0x24, 0xA6, 0x46, 0x37, 0x48, 0xFE, 0x44 , -0x00, 0x47, 0xA6, 0x46, 0x36, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x35, 0x48, 0x0E, 0x30, 0x28, 0x62, 0x30, 0xBD, 0x49, 0x19, 0x01, 0x00, 0x2F, 0x7A, 0x02, 0x00, 0x18, 0xB5, 0x43, 0x69, 0x81, 0x69, 0x31, 0x48, 0x81, 0x29, 0x00, 0xD1, 0x0B, 0x38, 0x00, 0x21, 0x00, 0x91, 0x1A, 0x68, 0x9B, 0x68, 0x01, 0x24, 0xA6, 0x46, 0x2D, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x18, 0xBD, 0x18, 0xB5, 0x40, 0x69, 0x00, 0x21, 0x00, 0x91, 0x02, 0x68, 0x83, 0x68, 0x27, 0x48, 0x01, 0x30, 0x01, 0x24, 0xA6, 0x46, 0x26, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x18, 0xBD, 0xC0, 0x46, 0x30, 0x63, 0x08, 0x00, 0x19, 0x9E, 0x00, 0x00, 0xB9, 0xEC, 0x00, 0x00, 0x74, 0x3F, 0x08, 0x00, 0x80, 0x3F, 0x08, 0x00, 0xFF, 0xFF, 0x54, 0x7A, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xB7, 0x5D, 0x03, 0x00, 0x00, 0x00, 0x1B, 0x00, 0xD3, 0x8E, 0x00, 0x00, 0xF7, 0xC6, 0x00, 0x00, 0xE5, 0x90, 0x00, 0x00, 0x68, 0x64, 0x08, 0x00, 0xC0, 0x27, 0x09, 0x00, 0xA0, 0x3B , -0x08, 0x00, 0x3D, 0x5D, 0x03, 0x00, 0x19, 0xC6, 0x00, 0x00, 0xE8, 0x3A, 0x08, 0x00, 0x81, 0x5D, 0x03, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0x4B, 0x4F, 0x03, 0x00, 0x6B, 0xC0, 0x03, 0x00, 0x95, 0x1E, 0x01, 0x00, 0xDA, 0x40, 0x08, 0x00, 0xDC, 0x05, 0x00, 0x00, 0x55, 0xAA, 0x03, 0x00, 0x0D, 0x91, 0x00, 0x00, 0xD7, 0x56, 0x03, 0x00, 0x08, 0x51, 0x08, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0x65, 0xB8, 0x00, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x84, 0x17, 0x1B, 0x00, 0xB5, 0x86, 0x01, 0x00, 0x3D, 0x47, 0x02, 0x00, 0x73, 0x49, 0x02, 0x00, 0x5F, 0x90, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x00, 0xF7, 0xF6, 0x00, 0x00, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x76, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x5A, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0xFF, 0xFF, 0xEA, 0x7A, 0x08, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x46, 0xFF, 0xF7, 0x99, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x83, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5 , -0x68, 0x46, 0xFF, 0xF7, 0xB6, 0xFE, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x55, 0xFC, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x27, 0xFB, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0xDD, 0xFA, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x68, 0xFE, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x3D, 0xFB, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0xBE, 0xFD, 0xFF, 0xBD, 0x78, 0x7B, 0x08, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0xB5, 0xF8, 0xF0, 0x43, 0xFA, 0x00, 0xBD, 0x35, 0x66, 0x08, 0x00, 0x67, 0x66, 0x08, 0x00, 0x71, 0x65, 0x08, 0x00, 0x4D, 0x66, 0x08, 0x00, 0x25, 0x64, 0x08, 0x00, 0x81, 0x66, 0x08, 0x00, 0x8D, 0x66, 0x08, 0x00, 0x99, 0x66, 0x08, 0x00, 0x87, 0x67, 0x08, 0x00, 0xA7, 0x67, 0x08, 0x00, 0xD1, 0x67, 0x08, 0x00, 0x1B, 0x68, 0x08, 0x00, 0x57, 0x68, 0x08, 0x00, 0x2D, 0x69, 0x08, 0x00, 0xB1, 0x6B, 0x08, 0x00, 0xD5, 0x6B, 0x08, 0x00, 0xF9, 0x6B , -0x08, 0x00, 0x15, 0x6C, 0x08, 0x00, 0xA1, 0x68, 0x08, 0x00, 0x59, 0x6C, 0x08, 0x00, 0xA7, 0x6D, 0x08, 0x00, 0xFF, 0x6D, 0x08, 0x00, 0x29, 0x6E, 0x08, 0x00, 0xF9, 0x6E, 0x08, 0x00, 0xD9, 0x6C, 0x08, 0x00, 0xA5, 0x6E, 0x08, 0x00, 0xCD, 0x6D, 0x08, 0x00, 0x81, 0x6F, 0x08, 0x00, 0x1D, 0x70, 0x08, 0x00, 0x31, 0x64, 0x08, 0x00, 0x39, 0x70, 0x08, 0x00, 0x3F, 0x70, 0x08, 0x00, 0x04, 0xF3, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x00, 0xB2, 0x4E, 0x01, 0x00, 0x5A, 0xC1, 0x00, 0x00, 0x96, 0x1A, 0x01, 0x00, 0x22, 0x0B, 0x02, 0x00, 0x60, 0xD0, 0x01, 0x00, 0x06, 0x1A, 0x00, 0x00, 0xB8, 0xC6, 0x01, 0x00, 0xD8, 0x42, 0x03, 0x00, 0x16, 0x42, 0x03, 0x00, 0xEE, 0xDB, 0x00, 0x00, 0x62, 0xDC, 0x00, 0x00, 0xC8, 0xE1, 0x00, 0x00, 0x8A, 0x17, 0x02, 0x00, 0x38, 0xBE, 0x00, 0x00, 0x26, 0xC6, 0x00, 0x00, 0x56, 0xC2, 0x00, 0x00, 0x62, 0x12, 0x03, 0x00, 0xE4, 0xF4, 0x01, 0x00, 0x3A, 0xEC, 0x00, 0x00, 0x5E, 0x92, 0x00, 0x00 , -0xFE, 0xE8, 0x02, 0x00, 0x18, 0x7F, 0x00, 0x00, 0x64, 0xEC, 0x01, 0x00, 0xFE, 0x44, 0x03, 0x00, 0x1C, 0x94, 0x00, 0x00, 0xA8, 0x66, 0x03, 0x00, 0x74, 0xE9, 0x02, 0x00, 0x68, 0x1E, 0x01, 0x00, 0xBC, 0xDA, 0x00, 0x00, 0xEA, 0xE1, 0x00, 0x00, 0x24, 0xE9, 0x01, 0x00, 0x70, 0x79, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x1C, 0xF0, 0xB5, 0x88, 0xB0, 0xCA, 0x4C, 0x03, 0x20, 0x22, 0x78, 0x63, 0x78, 0xCA, 0x4E, 0x31, 0x1C, 0x01, 0x39, 0x01, 0x25, 0xAE, 0x46, 0xC7, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0xA2, 0x78, 0xE3, 0x78, 0x03, 0x20, 0x31, 0x1C, 0xAE, 0x46, 0xC3, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x03, 0x20, 0x31, 0x1C, 0x01, 0x31, 0xAE, 0x46, 0xC1, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0xC1, 0x48, 0x21, 0x78, 0x01, 0x70, 0x61, 0x78, 0x41, 0x70, 0xE1, 0x78, 0xC1, 0x70, 0xA1, 0x78, 0x81, 0x70, 0xBF, 0x48, 0x04, 0x1C, 0x33, 0x3C, 0x20, 0x1C, 0x00, 0x21, 0xDC, 0x22, 0xAE, 0x46 , -0xBA, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x84, 0x20, 0xA0, 0x70, 0x05, 0x27, 0xE7, 0x71, 0x0C, 0x26, 0x26, 0x73, 0x0D, 0x20, 0x00, 0x19, 0x98, 0xA1, 0x32, 0x1C, 0xAE, 0x46, 0xB4, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x20, 0x60, 0x76, 0x1A, 0x20, 0x00, 0x19, 0x97, 0xA1, 0x06, 0x91, 0x04, 0x22, 0xAE, 0x46, 0xAE, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xFF, 0xFF, 0x96, 0x00, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA7, 0x77, 0x1F, 0x34, 0x95, 0xA1, 0x07, 0x91, 0x20, 0x1C, 0x3A, 0x1C, 0xAE, 0x46, 0xA9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE6, 0x71, 0x28, 0x1C, 0x60, 0x72, 0x11, 0x20, 0x20, 0x73, 0x94, 0x20, 0x60, 0x73, 0xC0, 0x25, 0x65, 0x74, 0xA6, 0x74, 0x09, 0x22, 0xE2, 0x74, 0xA3, 0x4C, 0x20, 0x1C, 0x8C, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x9F, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x07, 0x22, 0x62, 0x72, 0x9E, 0x4C, 0x0A, 0x34, 0x20, 0x1C, 0x89, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x9A, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x20 , -0xE0, 0x71, 0x98, 0x4C, 0x12, 0x34, 0x20, 0x1C, 0x06, 0x99, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x94, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x27, 0x71, 0x93, 0x4C, 0x17, 0x34, 0x20, 0x1C, 0x07, 0x99, 0x3A, 0x1C, 0x01, 0x23, 0x9E, 0x46, 0x8E, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE6, 0x71, 0x01, 0x20, 0x60, 0x72, 0x11, 0x20, 0x20, 0x73, 0x94, 0x20, 0x60, 0x73, 0x02, 0x20, 0xE0, 0x73, 0x25, 0x74, 0x66, 0x74, 0xFF, 0xFF, 0x2C, 0x01, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA5, 0x74, 0x2F, 0x27, 0xE7, 0x74, 0x10, 0x20, 0x60, 0x75, 0x80, 0x26, 0xA6, 0x75, 0x01, 0x20, 0xE0, 0x75, 0x11, 0x20, 0xA0, 0x76, 0x94, 0x20, 0xE0, 0x76, 0x24, 0x20, 0x60, 0x77, 0x0A, 0x22, 0xA2, 0x77, 0x80, 0x4C, 0x36, 0x34, 0x20, 0x1C, 0x6D, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x7C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x18, 0x22, 0xA2, 0x72, 0x7A, 0x4C, 0x41, 0x34, 0x20, 0x1C, 0x6B, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x76, 0x4B, 0xFE, 0x44, 0x18, 0x47 , -0x25, 0x76, 0x67, 0x76, 0x21, 0x20, 0xE0, 0x76, 0x26, 0x77, 0x01, 0x20, 0x60, 0x77, 0x72, 0x48, 0x61, 0x30, 0x11, 0x21, 0x01, 0x70, 0x94, 0x21, 0x41, 0x70, 0x04, 0x21, 0x01, 0x72, 0xD2, 0x21, 0x41, 0x72, 0xC5, 0x72, 0x1E, 0x21, 0x01, 0x73, 0x45, 0x73, 0x9E, 0x21, 0x81, 0x73, 0x01, 0x21, 0x01, 0x74, 0x46, 0x74, 0x81, 0x74, 0x11, 0x21, 0x41, 0x75, 0x94, 0x21, 0x81, 0x75, 0x04, 0x21, 0x01, 0x76, 0xAD, 0x20, 0x66, 0x49, 0x08, 0x60, 0x00, 0x24, 0x0F, 0x25, 0xFF, 0xFF, 0xC2, 0x01, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x29, 0x06, 0x09, 0x0E, 0x00, 0x20, 0x6A, 0x46, 0x01, 0x23, 0x9E, 0x46, 0x62, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x6B, 0x46, 0x18, 0x88, 0x40, 0x08, 0x0E, 0xD3, 0xA0, 0x00, 0x0F, 0x21, 0xCA, 0x43, 0x69, 0x46, 0x0E, 0x88, 0x16, 0x40, 0x01, 0xAF, 0x3E, 0x52, 0x49, 0x88, 0x11, 0x40, 0x68, 0x44, 0xC1, 0x80, 0x60, 0x1C, 0x04, 0x04, 0x24, 0x0C, 0x01, 0x3D, 0x0B, 0x2D, 0xE0, 0xDA, 0x60, 0x1E , -0x00, 0x04, 0x00, 0x0C, 0x1D, 0xD0, 0x86, 0x46, 0x01, 0x1C, 0x01, 0xAD, 0x01, 0x22, 0xAE, 0x88, 0x90, 0x00, 0xC7, 0x5A, 0xB7, 0x42, 0x0A, 0xDA, 0xBC, 0x46, 0x07, 0x1C, 0x6F, 0x44, 0x7F, 0x88, 0x68, 0x44, 0x06, 0x80, 0xEE, 0x88, 0x46, 0x80, 0x60, 0x46, 0xA8, 0x80, 0xEF, 0x80, 0x04, 0x35, 0x50, 0x1C, 0x02, 0x04, 0x12, 0x0C, 0x01, 0x39, 0xE9, 0xD1, 0x70, 0x46, 0x01, 0x38, 0x86, 0x46, 0xE2, 0xD1, 0x99, 0x88, 0x68, 0x46, 0xC0, 0x88, 0x40, 0x18, 0x00, 0x04, 0x00, 0x0C, 0x42, 0x4B, 0x18, 0x80, 0x42, 0x49, 0x08, 0x1A, 0xFF, 0xFF, 0x58, 0x02, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x58, 0x80, 0x02, 0x2C, 0x1E, 0xDB, 0x65, 0x1E, 0x01, 0xAA, 0x01, 0x20, 0x01, 0x1C, 0x8C, 0x00, 0x6B, 0x46, 0xE6, 0x5A, 0x93, 0x88, 0xD4, 0x88, 0xE7, 0x18, 0xB7, 0x42, 0x0C, 0xDA, 0x06, 0x24, 0x44, 0x43, 0x38, 0x4B, 0x1B, 0x19, 0x1F, 0x80, 0x1C, 0x88, 0x34, 0x1B, 0x5C, 0x80, 0x01, 0x24, 0x1C, 0x71, 0x40, 0x1C, 0x00, 0x04 , -0x00, 0x0C, 0x04, 0x32, 0x49, 0x1C, 0x09, 0x06, 0x09, 0x0E, 0x01, 0x3D, 0xE4, 0xD1, 0x00, 0x24, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x01, 0x20, 0x86, 0x46, 0x30, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x2F, 0x49, 0x22, 0x1C, 0x08, 0x68, 0x00, 0x28, 0x02, 0xD0, 0x01, 0x20, 0x90, 0x40, 0x04, 0x43, 0x04, 0x31, 0x01, 0x32, 0x20, 0x2A, 0xF5, 0xD3, 0x2A, 0x48, 0x04, 0x60, 0x08, 0xB0, 0xF0, 0xBD, 0x5F, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2D, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0xC0, 0x46, 0xC0, 0x5F, 0x75, 0x64, 0x70, 0x00, 0xC0, 0xFF, 0xFF, 0xEE, 0x02, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x46, 0xC0, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x00, 0xC0, 0x46, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, 0xC0, 0x46, 0x5F, 0x64, 0x6E, 0x73, 0x2D, 0x73, 0x64, 0x00, 0x64, 0x65, 0x76, 0x3D, 0x43, 0x43, 0x33, 0x30, 0x30, 0x30, 0x00, 0xC0, 0x76, 0x65 , -0x6E, 0x64, 0x6F, 0x72, 0x3D, 0x54, 0x65, 0x78, 0x61, 0x73, 0x2D, 0x49, 0x6E, 0x73, 0x74, 0x72, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x00, 0xC0, 0x46, 0xC0, 0x00, 0x00, 0x18, 0x00, 0xF3, 0x7E, 0x03, 0x00, 0xC6, 0x05, 0x00, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0xE4, 0x62, 0x08, 0x00, 0xC9, 0xBA, 0x03, 0x00, 0x09, 0xB4, 0x03, 0x00, 0xA7, 0x64, 0x08, 0x00, 0x70, 0x64, 0x08, 0x00, 0xDD, 0x0A, 0x02, 0x00, 0x48, 0x32, 0x08, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xE8, 0x62, 0x08, 0x00, 0xE9, 0x62, 0x08, 0x00, 0xEA, 0x62, 0x08, 0x00, 0xEB, 0x62, 0x08, 0x00, 0x81, 0x03, 0x18, 0x00, 0x80, 0x7B, 0x08, 0x00, 0x84, 0xF3, 0x1A, 0x00, 0x0D, 0x49, 0x0E, 0x48, 0xFF, 0xFF, 0x84, 0x03, 0x18, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x88, 0x67, 0x0E, 0x48, 0x88, 0x64, 0x0E, 0x48, 0x48, 0x64, 0x0E, 0x48, 0xC8, 0x64, 0x0E, 0x48, 0x08, 0x65, 0x11, 0x48, 0x02, 0x1C, 0x04, 0x32, 0x0C, 0x4B, 0x13, 0x60, 0x0C, 0x4B, 0x93, 0x62, 0x0C, 0x4A , -0x8A, 0x66, 0x0D, 0x49, 0x01, 0x60, 0x0D, 0x48, 0x0E, 0x49, 0x01, 0x60, 0x0E, 0x49, 0x41, 0x60, 0xF7, 0x46, 0x1C, 0x21, 0x08, 0x00, 0x1B, 0x7B, 0x08, 0x00, 0x11, 0x7B, 0x08, 0x00, 0x07, 0x7B, 0x08, 0x00, 0x39, 0x7B, 0x08, 0x00, 0x2F, 0x7B, 0x08, 0x00, 0x25, 0x7B, 0x08, 0x00, 0xFD, 0x7A, 0x08, 0x00, 0xDF, 0x7A, 0x08, 0x00, 0x50, 0x23, 0x08, 0x00, 0xD5, 0x7A, 0x08, 0x00, 0x58, 0x26, 0x08, 0x00, 0xF3, 0x7A, 0x08, 0x00, 0xE9, 0x7A, 0x08, 0x00 }; - - -const unsigned char cRMdefaultParams[128] = { 0x03, 0x00, 0x01, 0x01, 0x14, 0x14, 0x00, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x23, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x01, 0x77, 0x80, 0x1D, 0x1F, 0x22, 0x26, 0x28, 0x29, 0x1A, 0x1F, 0x22, 0x24, 0x26, 0x28, 0x16, 0x1D, 0x1E, 0x20, 0x24, 0x25, 0x1E, 0x2D, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x15, 0x15, 0x15, 0x11, 0x15, 0x15, 0x0E, 0x00}; - -// -//Service Pack version P1.13.7.15.15 - FW patches -// -const unsigned char fw_patch[5700] = { 0x00, 0x01, 0x00, 0x00, 0x3C, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x14, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x46, 0x25, 0xF0, 0x95, 0xFB, 0xE0, 0x6B, 0xD0, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x38, 0xFB, 0x2C, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x0A, 0xFB, 0x04, 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB8, 0xF1, 0x90, 0x0F, 0xA4, 0x16, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x66, 0xE0, 0x04, 0xA8, 0x35, 0x1D, 0x21, 0xF0, 0x99, 0xFC, 0x68, 0x46, 0x23, 0xF0, 0x28, 0xFB, 0x9A, 0xF8, 0x00, 0x00, 0x01, 0x28, 0x07, 0xD1, 0x28, 0x46, 0x05, 0xF0, 0xC3, 0xFE, 0x01, 0x46, 0x01, 0xAA, 0x00, 0x20, 0x21, 0xF0, 0x50, 0xF9, 0x28, 0x46, 0x05, 0xF0, 0xBB, 0xFE, 0x01, 0xA9, 0x21, 0xF0, 0x2A, 0xFA, 0xE9, 0x79, 0x4F, 0xEA, 0xE0, 0x00, 0x40, 0xB2, 0x11, 0xB1, 0x00, 0xF1, 0x06, 0x00, 0x40, 0xB2, 0xA8, 0x71, 0x1F, 0x38, 0x40, 0x00, 0xE8, 0x71, 0x30, 0x46 , -0x01, 0xF0, 0x0D, 0xFF, 0x10, 0xF1, 0x00, 0x09, 0x4F, 0xF0, 0x00, 0x01, 0x09, 0xD0, 0x28, 0x68, 0x40, 0x0C, 0x09, 0xD3, 0xE8, 0x68, 0xC0, 0x0B, 0x03, 0xD2, 0x48, 0x46, 0xFF, 0xF7, 0xDD, 0xFE, 0x01, 0x21, 0x28, 0x68, 0x40, 0x0C, 0x0A, 0xD2, 0x38, 0x68, 0x40, 0x1C, 0x38, 0x60, 0x20, 0x68, 0x6F, 0xF3, 0x0F, 0x00, 0x20, 0x60, 0x22, 0x68, 0x38, 0x68, 0x10, 0x43, 0x20, 0x60, 0xE8, 0x68, 0xC0, 0x0B, 0x0F, 0xD3, 0xD8, 0xF8, 0x00, 0x00, 0x00, 0xF1, 0x01, 0x00, 0xC8, 0xF8, 0x00, 0x00, 0x20, 0x68, 0x6F, 0xF3, 0x1F, 0x40, 0x20, 0x60, 0xD8, 0xF8, 0x00, 0x20, 0x20, 0x68, 0x40, 0xEA, 0x02, 0x40, 0x20, 0x60, 0x49, 0xB9, 0xB9, 0xF1, 0x00, 0x0F, 0x03, 0xD1, 0x30, 0x46, 0x07, 0xF0, 0xBE, 0xF9, 0x02, 0xE0, 0x48, 0x46, 0x07, 0xF0, 0x06, 0xFA, 0x6C, 0x17, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x46, 0x0E, 0xF0, 0x85, 0xFB, 0x00, 0x9E, 0x00, 0x2E, 0x96, 0xD1, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xC0, 0x46 , -0x9C, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0xF0, 0x2A, 0xFE, 0x74, 0x47, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x21, 0x21, 0xF0, 0x41, 0xFA, 0x20, 0x68, 0x18, 0x4B, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0xF0, 0x1C, 0xF9, 0x0A, 0xE0, 0x20, 0x68, 0x00, 0x68, 0x0C, 0x21, 0x40, 0xF0, 0x20, 0x00, 0x21, 0xF0, 0x14, 0xF9, 0x10, 0x57, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xA8, 0x20, 0xF0, 0x97, 0xF9, 0x01, 0x98, 0x5C, 0x57, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x20, 0xF0, 0x71, 0xF9, 0x03, 0x98, 0x00, 0x58, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xF0, 0x20, 0xF9, 0x1C, 0x58, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xF0, 0x12, 0xF9, 0x54, 0x58, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0xA8, 0x20, 0xF0, 0xF5, 0xF8, 0x04, 0xAB, 0x04, 0x62, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x79, 0x1F, 0xF0, 0x1B, 0xFD, 0x69, 0xE0, 0x60, 0x93, 0x00, 0x00, 0x40, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xA6, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1B, 0xF0, 0x39, 0xFB, 0x28, 0x46, 0x90, 0xA8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1B, 0xF0, 0x69, 0xF9, 0x1E, 0x48, 0x34, 0xAD, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x68, 0xFF, 0x29, 0x98, 0xAD, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xD4, 0x21, 0xD4, 0xB2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0xD0, 0x1A, 0xF0, 0x47, 0xFC, 0x20, 0x98, 0xAC, 0xC5, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0xF0 , -0xDB, 0xFA, 0x09, 0x49, 0x28, 0xC6, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0xF0, 0x9E, 0xFA, 0xDC, 0xD3, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x18, 0xF0, 0xAB, 0xFC, 0x00, 0xF0, 0x03, 0xF8, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xDF, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x17, 0xF0, 0xA8, 0xFD, 0xCC, 0xEB, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x38, 0x78, 0x17, 0xF0, 0x77, 0xF8, 0x38, 0x78, 0x16, 0xF0, 0xF0, 0xFF, 0xA8, 0xF7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0E, 0x49, 0x09, 0x68, 0x23, 0x22, 0x41, 0x61, 0xC8, 0xF7, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x31, 0x39, 0x2E, 0x33, 0x31, 0x34, 0x5F, 0x4E, 0x65, 0x77, 0x5F, 0x43, 0x43, 0x41, 0x5F, 0x61, 0x6C, 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 0xC0, 0x74, 0x56, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xF9, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x16, 0xF0, 0x79, 0xF8 , -0x12, 0xE0, 0x38, 0xFA, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xA8, 0x16, 0xF0, 0x03, 0xF8, 0x32, 0x20, 0x94, 0xFB, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0C, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x14, 0xF0, 0x05, 0xFF, 0x01, 0xF0, 0x10, 0x1B, 0x01, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0xF0, 0x46, 0xBF, 0x18, 0x30, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x30, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0xF0, 0xD8, 0xFC, 0x9C, 0x31, 0x01, 0x00, 0x08, 0x00 , -0x00, 0x00, 0x68, 0x46, 0x12, 0xF0, 0x51, 0xFC, 0xFE, 0xF7, 0xF0, 0x35, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x46, 0x12, 0xF0, 0x27, 0xFA, 0xFE, 0xF7, 0xF0, 0x3D, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0xA9, 0x11, 0xF0, 0x27, 0xFE, 0x20, 0x6F, 0xD0, 0x62, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0xB8, 0xFB, 0x80, 0x7E, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xDF, 0xF8, 0x58, 0x82, 0xE0, 0x7E, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0x6A, 0xFE, 0x0B, 0xF0, 0x9A, 0xF9, 0x03, 0x20, 0xA8, 0xF5, 0x88, 0x71, 0x08, 0x60, 0xF2, 0xF7, 0x16, 0xF9, 0x7A, 0x48, 0x6B, 0x49, 0x9C, 0x7F, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x70, 0x51, 0x4D, 0xC4, 0x7F, 0x01, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x40, 0x49, 0x00, 0xF1, 0x52, 0x00, 0x3A, 0x4A, 0xA8, 0x81, 0x28, 0x83, 0xE8, 0x83, 0xE8, 0x84, 0xA8, 0x85, 0x2A, 0x60, 0x39, 0x48, 0x41, 0xF2, 0x11, 0x12, 0x2A, 0x85, 0x18, 0x90, 0x19, 0x91 , -0x39, 0x49, 0x1A, 0x91, 0x39, 0x49, 0x1B, 0x91, 0x39, 0x49, 0x20, 0x46, 0xDF, 0xF8, 0xC4, 0x90, 0x1C, 0x91, 0x38, 0x49, 0xDF, 0xF8, 0xC0, 0xB0, 0x31, 0x4E, 0x1D, 0x91, 0x48, 0x80, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0x7C, 0xFA, 0xB4, 0x80, 0x01, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x12, 0x66, 0x09, 0x84, 0x6B, 0x00, 0x20, 0x94, 0x70, 0x00, 0x20, 0xB4, 0x70, 0x00, 0x20, 0xC4, 0x78, 0x00, 0x20, 0x50, 0x7A, 0x00, 0x20, 0xFE, 0xFF, 0x03, 0x00, 0xA4, 0x70, 0x00, 0x20, 0xB0, 0x70, 0x00, 0x20, 0xB8, 0x70, 0x00, 0x20, 0x60, 0x55, 0x30, 0x80, 0x3C, 0x5C, 0x00, 0x20, 0x04, 0x74, 0x00, 0x20, 0xB8, 0xE4, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x78, 0x07, 0xF0, 0x01, 0xFC, 0x20, 0x78, 0x07, 0xF0, 0x7A, 0xFB, 0x04, 0x4D, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xAD, 0xF1, 0x8C, 0x0D, 0x04, 0x68, 0x0F, 0x30, 0x03, 0x94, 0xFE, 0xF7, 0xDB, 0xFA, 0x04, 0xF1, 0x14, 0x00 , -0x04, 0x90, 0x21, 0x7D, 0x00, 0x20, 0x21, 0xF0, 0x73, 0x01, 0x88, 0x29, 0x08, 0xBF, 0x01, 0x20, 0x05, 0x90, 0x03, 0x98, 0x00, 0x1D, 0x06, 0x90, 0x5D, 0x48, 0x00, 0x68, 0x01, 0x28, 0x40, 0xF0, 0xFA, 0x83, 0x5B, 0x4D, 0x5C, 0x48, 0xDF, 0xF8, 0x70, 0x91, 0x29, 0x68, 0xDF, 0xF8, 0x70, 0x81, 0xDF, 0xF8, 0x74, 0xA1, 0x88, 0x42, 0x21, 0xD1, 0x10, 0x22, 0x00, 0x21, 0x48, 0x46, 0x4F, 0x46, 0xFB, 0xF7, 0xB7, 0xFE, 0x10, 0x22, 0x00, 0x21, 0x40, 0x46, 0xFB, 0xF7, 0xB2, 0xFE, 0x54, 0x49, 0x08, 0x68, 0x40, 0xF4, 0x80, 0x10, 0x08, 0x60, 0x01, 0x20, 0x51, 0x46, 0x08, 0x60, 0x00, 0x21, 0x29, 0x60, 0x39, 0x78, 0x46, 0x46, 0x00, 0x91, 0x31, 0x78, 0x41, 0xF2, 0x11, 0x13, 0x04, 0x22, 0x01, 0x91, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF3, 0xF7, 0x41, 0xFC, 0x51, 0x46, 0x07, 0x91, 0x08, 0x68, 0x56, 0x49, 0xDF, 0xF8, 0x5C, 0xB1, 0x01, 0x28, 0x08, 0x91, 0x56, 0x49, 0xDF, 0xF8, 0x48, 0xA1, 0x09, 0x91, 0x55, 0x49 , -0x0A, 0x91, 0x44, 0x49, 0x0B, 0x91, 0x44, 0x49, 0x0C, 0x91, 0x44, 0x49, 0x0D, 0x91, 0x44, 0x49, 0x0E, 0x91, 0x44, 0x49, 0x0F, 0x91, 0x44, 0x49, 0x10, 0x91, 0x44, 0x49, 0xCC, 0x4D, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x11, 0x91, 0x44, 0x49, 0x12, 0x91, 0x44, 0x49, 0x13, 0x91, 0x44, 0x49, 0x14, 0x91, 0x44, 0x49, 0x15, 0x91, 0x44, 0x49, 0x16, 0x91, 0x9F, 0x49, 0x17, 0x91, 0x9F, 0x49, 0x18, 0x91, 0x9F, 0x49, 0x19, 0x91, 0x9F, 0x49, 0x1A, 0x91, 0x9F, 0x49, 0x1B, 0x91, 0x9F, 0x49, 0x1C, 0x91, 0x9F, 0x49, 0x1D, 0x91, 0x9F, 0x49, 0x1E, 0x91, 0x9F, 0x49, 0x1F, 0x91, 0x40, 0xF0, 0x00, 0x81, 0x04, 0x98, 0x40, 0x78, 0x00, 0xF0, 0x03, 0x01, 0x01, 0x29, 0x40, 0xF0, 0xF9, 0x80, 0x04, 0x99, 0x09, 0x78, 0x01, 0xF0, 0x0C, 0x01, 0x08, 0x29, 0x40, 0xF0, 0xF2, 0x80, 0x06, 0x99, 0x09, 0x88, 0xA1, 0xF1, 0x3C, 0x01, 0x0E, 0xB2, 0x05, 0x99, 0x11, 0xB1, 0xA6, 0xF1, 0x02, 0x06, 0x36, 0xB2, 0xC0, 0x09, 0x4F, 0xF0 , -0x00, 0x07, 0x15, 0xD3, 0x08, 0x3E, 0x36, 0xB2, 0x03, 0x2E, 0x10, 0xD0, 0x17, 0x2E, 0x0E, 0xD0, 0x08, 0x3E, 0x36, 0xB2, 0x03, 0x2E, 0x08, 0xD0, 0x17, 0x2E, 0x06, 0xD0, 0x36, 0x1F, 0x36, 0xB2, 0x03, 0x2E, 0x14, 0xBF, 0x17, 0x2E, 0x02, 0x27, 0x02, 0xE0, 0x03, 0x27, 0x00, 0xE0, 0x01, 0x27, 0x03, 0x2E, 0x18, 0xBF, 0x17, 0x2E, 0x04, 0x9A, 0x40, 0xF0, 0xC8, 0x80, 0x0A, 0x32, 0x12, 0xF8, 0x01, 0x1B, 0x05, 0x24, 0x12, 0xF8, 0x01, 0x3B, 0x4B, 0x40, 0x64, 0x1E, 0xD9, 0xB2, 0xF9, 0xD1, 0x81, 0xEA, 0x21, 0x11, 0x03, 0x2E, 0x94, 0x4E, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x0F, 0x01, 0x48, 0x46, 0x35, 0xD0, 0x43, 0x46, 0xCA, 0x5C, 0x52, 0x1C, 0xCA, 0x54, 0x0C, 0x18, 0x33, 0xE0, 0x50, 0x57, 0x02, 0x00, 0x04, 0x74, 0x00, 0x20, 0x34, 0x12, 0x66, 0x09, 0x60, 0x57, 0x02, 0x00, 0x70, 0x57, 0x02, 0x00, 0xC8, 0x48, 0x30, 0x80, 0x4C, 0x57, 0x02, 0x00, 0x88, 0x57, 0x02, 0x00, 0x80, 0x57, 0x02, 0x00 , -0x18, 0x58, 0x02, 0x00, 0x20, 0x58, 0x02, 0x00, 0x28, 0x58, 0x02, 0x00, 0x30, 0x58, 0x02, 0x00, 0x38, 0x58, 0x02, 0x00, 0x40, 0x58, 0x02, 0x00, 0xE4, 0x58, 0x02, 0x00, 0xE2, 0x58, 0x02, 0x00, 0x14, 0x58, 0x02, 0x00, 0xEF, 0x58, 0x02, 0x00, 0xE0, 0x58, 0x02, 0x00, 0xEE, 0x58, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0xE6, 0x58, 0x02, 0x00, 0xE8, 0x58, 0x02, 0x00, 0x0C, 0x18, 0x20, 0x78, 0x40, 0x1C, 0x20, 0x70, 0x20, 0x78, 0x43, 0x46, 0x03, 0xEB, 0x01, 0x08, 0x0A, 0x28, 0x76, 0xDB, 0x98, 0xF8, 0x00, 0x00, 0x0A, 0x28, 0x72, 0xDB, 0x94, 0x48, 0x00, 0x25, 0x01, 0x60, 0x04, 0x98, 0x00, 0xF1, 0x0A, 0x09, 0x40, 0x78, 0x41, 0x08, 0x24, 0xBF, 0x04, 0x99, 0x09, 0x1D, 0x04, 0xD2, 0x80, 0x08, 0x2E, 0xBF, 0x49, 0x46, 0x04, 0x99, 0x10, 0x31, 0x0B, 0x98, 0x06, 0x22, 0xFA, 0xF7, 0xB9, 0xFC, 0x0C, 0x98, 0x06, 0x22, 0x49, 0x46, 0xFA, 0xF7, 0xB4, 0xFC, 0x9B, 0x48, 0x9A, 0x49, 0x5C, 0x4F, 0x02, 0x00, 0xC8, 0x00 , -0x00, 0x00, 0x00, 0x78, 0x08, 0x22, 0x08, 0x60, 0x58, 0x46, 0x07, 0x60, 0x0D, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xAF, 0xFD, 0x08, 0x22, 0x0E, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xAA, 0xFD, 0x08, 0x22, 0x0F, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xA5, 0xFD, 0x08, 0x22, 0x10, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xA0, 0xFD, 0x08, 0x22, 0x11, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0x9B, 0xFD, 0x08, 0x22, 0x12, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0x96, 0xFD, 0x07, 0x99, 0x02, 0x20, 0x08, 0x60, 0x13, 0x99, 0x28, 0x46, 0x08, 0x80, 0x08, 0x99, 0x08, 0x70, 0x14, 0x99, 0x08, 0x70, 0x15, 0x99, 0x08, 0x60, 0x16, 0x99, 0x08, 0x70, 0x17, 0x99, 0x08, 0x60, 0x18, 0x99, 0x08, 0x60, 0x19, 0x99, 0x08, 0x60, 0x09, 0x99, 0x08, 0x80, 0x0A, 0x99, 0x08, 0x80, 0x1A, 0x99, 0x08, 0x80, 0x7D, 0x49, 0x0D, 0x60, 0x1B, 0x99, 0x08, 0x70, 0x1C, 0x99, 0x08, 0x70, 0x1D, 0x99, 0x08, 0x70, 0x1E, 0x99, 0x08, 0x80, 0x1F, 0x99, 0x08, 0x80, 0x51, 0x46, 0x08, 0x80 , -0x20, 0x78, 0x00, 0x96, 0x04, 0x22, 0x01, 0x90, 0x98, 0xF8, 0x00, 0x00, 0x41, 0xF2, 0x14, 0x13, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF3, 0xF7, 0x07, 0xFB, 0x07, 0x98, 0xA2, 0x49, 0x00, 0x68, 0x20, 0x91, 0xA2, 0x49, 0x05, 0x28, 0x21, 0x91, 0x9E, 0x49, 0x22, 0x91, 0x40, 0xF0, 0x37, 0x82, 0x04, 0x98, 0x40, 0x78, 0x24, 0x50, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x41, 0x08, 0x24, 0xBF, 0x04, 0x99, 0x09, 0x1D, 0x05, 0xD2, 0x80, 0x08, 0x27, 0xBF, 0x04, 0x99, 0x0A, 0x31, 0x04, 0x99, 0x10, 0x31, 0x0B, 0x98, 0xF8, 0xF7, 0x2D, 0xFC, 0x01, 0x28, 0x04, 0x98, 0x40, 0xF0, 0x23, 0x82, 0x40, 0x78, 0x00, 0xF0, 0x03, 0x00, 0x03, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x07, 0xBF, 0x04, 0x99, 0x10, 0x31, 0x04, 0x99, 0x0A, 0x31, 0x13, 0xE0, 0x48, 0x58, 0x02, 0x00, 0x4C, 0x58, 0x02, 0x00, 0x50, 0x58, 0x02, 0x00, 0xF0, 0x58, 0x02, 0x00, 0xF2, 0x58, 0x02, 0x00, 0xF3, 0x58, 0x02, 0x00, 0xF4, 0x58, 0x02, 0x00, 0xEA, 0x58 , -0x02, 0x00, 0xEC, 0x58, 0x02, 0x00, 0x04, 0x99, 0x18, 0x31, 0x0C, 0x98, 0xF8, 0xF7, 0x06, 0xFC, 0x04, 0x99, 0x01, 0x28, 0x40, 0xF0, 0xFC, 0x81, 0x49, 0x78, 0x01, 0xF0, 0x03, 0x01, 0x01, 0x29, 0x40, 0xF0, 0xF6, 0x81, 0x59, 0x46, 0x09, 0x68, 0x04, 0x9A, 0x8E, 0x46, 0x51, 0x46, 0xD2, 0x8A, 0x0B, 0x88, 0x12, 0x11, 0x93, 0x42, 0x00, 0xF0, 0x37, 0x82, 0x0A, 0x80, 0x06, 0x99, 0x09, 0x88, 0x3C, 0x39, 0x0B, 0xB2, 0x71, 0x46, 0x49, 0x1E, 0x09, 0xD0, 0x49, 0x1E, 0x04, 0xD0, 0x49, 0x1E, 0x08, 0xD1, 0xA3, 0xF1, 0x10, 0x03, 0x04, 0xE0, 0xA3, 0xF1, 0x14, 0x03, 0x01, 0xE0, 0xA3, 0xF1, 0x08, 0x03, 0x1B, 0xB2, 0x05, 0x98, 0x10, 0xB1, 0xA3, 0xF1, 0x02, 0x03, 0x1B, 0xB2, 0xEC, 0x50, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0xF1, 0xCE, 0x81, 0x16, 0x98, 0x40, 0xF2, 0x77, 0x51, 0x99, 0x42, 0x0B, 0x90, 0x14, 0x98, 0x05, 0x90, 0x00, 0xF0, 0xA3, 0x81, 0x08, 0x46, 0x00, 0xF1, 0x3C, 0x00, 0x98, 0x42 , -0x05, 0x9A, 0x00, 0xF0, 0x9A, 0x81, 0xDF, 0xF8, 0x48, 0x82, 0x14, 0x78, 0x0B, 0x9A, 0xBB, 0x2C, 0x12, 0x78, 0x0C, 0x92, 0x63, 0xD1, 0xDD, 0xF8, 0x68, 0xC0, 0xBC, 0xF9, 0x00, 0x20, 0x91, 0x42, 0x18, 0xBF, 0x90, 0x42, 0x5B, 0xD1, 0x1C, 0x2B, 0x4F, 0xF0, 0x00, 0x00, 0xC0, 0xF2, 0x82, 0x81, 0x3D, 0x2B, 0x13, 0x9D, 0x80, 0xF2, 0x7E, 0x81, 0xA3, 0xF1, 0x1C, 0x01, 0x09, 0xB2, 0x29, 0x80, 0x1E, 0x9A, 0xDD, 0xF8, 0x30, 0x90, 0xB2, 0xF9, 0x00, 0x60, 0xB9, 0xF1, 0x01, 0x0F, 0x15, 0xD1, 0xDD, 0xF8, 0x24, 0x90, 0x03, 0x2E, 0x0D, 0xDA, 0xB9, 0xF9, 0x00, 0x70, 0xB9, 0x42, 0x07, 0xD0, 0x01, 0x26, 0x16, 0x80, 0x4A, 0x46, 0x0E, 0x46, 0x03, 0xE0, 0xC0, 0x46, 0x90, 0x57, 0x02, 0x00, 0x76, 0x1C, 0x16, 0x80, 0x1B, 0x9A, 0x16, 0x78, 0x1D, 0x9A, 0x16, 0x70, 0x0C, 0x9A, 0x1F, 0x9E, 0x02, 0x2A, 0x28, 0xD1, 0xB6, 0xF9, 0x00, 0x20, 0xBE, 0xF1, 0x00, 0x0F, 0x1A, 0xD0, 0x03, 0x2A, 0x35, 0x46, 0x0B, 0xDA, 0x0A, 0x9E , -0xB6, 0xF9, 0x00, 0x70, 0xB9, 0x42, 0x04, 0xD0, 0x01, 0x22, 0x2A, 0x80, 0x0A, 0x46, 0x35, 0x46, 0x00, 0xE0, 0xB4, 0x51, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x52, 0x1C, 0x2A, 0x80, 0x1C, 0x99, 0x0A, 0x78, 0x1D, 0x99, 0x0A, 0x70, 0x0F, 0xE0, 0xC0, 0x46, 0x58, 0x57, 0x02, 0x00, 0xA6, 0x64, 0x00, 0x20, 0x54, 0x57, 0x02, 0x00, 0x28, 0x80, 0x05, 0x99, 0x08, 0x70, 0x08, 0x9A, 0x11, 0x78, 0x41, 0xF0, 0x04, 0x01, 0x11, 0x70, 0x04, 0x46, 0x45, 0x46, 0xAC, 0xF8, 0x00, 0x00, 0x28, 0x70, 0xCC, 0x2C, 0x09, 0x9A, 0x40, 0xF0, 0x00, 0x81, 0xDD, 0xF8, 0x7C, 0xC0, 0x0A, 0x99, 0x1E, 0x9F, 0x45, 0x46, 0xB1, 0xF9, 0x00, 0x60, 0xB2, 0xF9, 0x00, 0x90, 0x28, 0x78, 0xCD, 0xF8, 0x50, 0xC0, 0x16, 0x91, 0x0A, 0x97, 0x13, 0x92, 0x09, 0x95, 0x0C, 0x99, 0x01, 0x29, 0x05, 0xD1, 0x05, 0x9A, 0xB0, 0xEB, 0x49, 0x0F, 0x01, 0xD1, 0x00, 0x21, 0x11, 0x70, 0x0C, 0x99, 0x02, 0x29, 0x05, 0xD1, 0x05, 0x9A, 0xB0, 0xEB, 0x46, 0x0F , -0x01, 0xD1, 0x00, 0x21, 0x11, 0x70, 0xB3, 0xF5, 0x14, 0x7F, 0x40, 0xF3, 0xBA, 0x80, 0x40, 0xF2, 0x51, 0x31, 0x99, 0x42, 0x08, 0x99, 0x40, 0xF3, 0xB4, 0x80, 0x09, 0x78, 0x06, 0x29, 0x00, 0xF0, 0xB0, 0x80, 0xA3, 0xF2, 0x51, 0x21, 0x0B, 0xB2, 0x4F, 0xEA, 0xE3, 0x01, 0x03, 0xEB, 0x11, 0x71, 0x4F, 0xEA, 0x21, 0x11, 0xCA, 0xB2, 0x4F, 0xEA, 0xE3, 0x01, 0x03, 0xEB, 0x11, 0x71, 0x15, 0x9D, 0x21, 0xF0, 0x0F, 0x01, 0xA3, 0xEB, 0x01, 0x03, 0x1D, 0x99, 0x2E, 0x68, 0x7C, 0x52, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x91, 0xF8, 0x00, 0xE0, 0x5F, 0xFA, 0x83, 0xF8, 0x60, 0xB1, 0x31, 0x18, 0x11, 0xF8, 0x01, 0x1C, 0x51, 0x40, 0xCB, 0xB2, 0x07, 0xE0, 0xC0, 0x46, 0x58, 0x58, 0x02, 0x00, 0x54, 0x58, 0x02, 0x00, 0xDC, 0x58, 0x02, 0x00, 0x13, 0x46, 0x19, 0x99, 0xDD, 0xF8, 0x6C, 0xA0, 0xDD, 0xF8, 0x70, 0xB0, 0xD1, 0xF8, 0x00, 0xC0, 0x00, 0xF0, 0x0F, 0x01, 0x99, 0x42, 0x22, 0xD0, 0x0A, 0x9B, 0x86, 0x45, 0x9A, 0xF8 , -0x00, 0x10, 0xB3, 0xF9, 0x00, 0x30, 0x9B, 0xF8, 0x00, 0x50, 0x15, 0xDD, 0x37, 0x5C, 0x44, 0x1C, 0x82, 0xEA, 0x07, 0x0C, 0x04, 0xF0, 0x0F, 0x07, 0x67, 0x45, 0x0B, 0xD0, 0xA6, 0x45, 0x06, 0x44, 0x0A, 0xDD, 0x76, 0x78, 0x72, 0x40, 0x86, 0x1C, 0x06, 0xF0, 0x0F, 0x06, 0x96, 0x42, 0x03, 0xD1, 0xC0, 0x1C, 0x4D, 0xE0, 0x80, 0x1C, 0x4B, 0xE0, 0x05, 0x9E, 0x00, 0x22, 0x32, 0x70, 0x4A, 0xE0, 0x00, 0xF0, 0x1F, 0x01, 0x01, 0x22, 0x8A, 0x40, 0x17, 0x99, 0xC4, 0x10, 0x0B, 0x68, 0x24, 0xF0, 0x03, 0x01, 0x5C, 0xF8, 0x01, 0x70, 0x3A, 0x42, 0x32, 0xD1, 0x5F, 0x58, 0x3A, 0x42, 0x06, 0x44, 0x1F, 0xD0, 0x18, 0x9B, 0x37, 0x78, 0x1B, 0x68, 0xB8, 0x45, 0x04, 0xD1, 0x58, 0x58, 0x02, 0x42, 0x19, 0xD0, 0x63, 0x46, 0x15, 0xE0, 0xA1, 0x10, 0x8C, 0x00, 0x19, 0x59, 0x91, 0x43, 0x19, 0x51, 0x00, 0x90, 0x30, 0x78, 0x01, 0x90, 0x44, 0x53, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x03, 0x20, 0x06, 0x21, 0x02, 0x46, 0x4D, 0xF6 , -0x80, 0x53, 0xF3, 0xF7, 0x63, 0xF9, 0x09, 0x99, 0x28, 0x68, 0x0E, 0x78, 0x36, 0x18, 0x06, 0xE0, 0xE3, 0x58, 0x02, 0x00, 0xA0, 0x10, 0x81, 0x00, 0x58, 0x58, 0x02, 0x43, 0x5A, 0x50, 0x86, 0xF8, 0x00, 0x80, 0x0B, 0x98, 0x00, 0x78, 0x0C, 0x90, 0x13, 0x98, 0xB0, 0xF9, 0x00, 0x90, 0x09, 0x98, 0x00, 0x78, 0x0A, 0x9A, 0x40, 0x1C, 0x9B, 0xF8, 0x00, 0x50, 0x9A, 0xF8, 0x00, 0x10, 0xB2, 0xF9, 0x00, 0x30, 0x09, 0x9A, 0xC0, 0xB2, 0x10, 0x70, 0x0C, 0x9A, 0x01, 0x2A, 0x03, 0xD1, 0x88, 0x42, 0xC8, 0xBF, 0x8A, 0xF8, 0x00, 0x00, 0x0C, 0x99, 0x02, 0x29, 0x07, 0xD1, 0xA8, 0x42, 0xC8, 0xBF, 0x8B, 0xF8, 0x00, 0x00, 0x02, 0xE0, 0x0A, 0x98, 0xB0, 0xF9, 0x00, 0x30, 0xB9, 0xF1, 0x00, 0x0F, 0x06, 0xDD, 0x03, 0x2B, 0x04, 0xD1, 0x11, 0x98, 0x01, 0x22, 0x49, 0x46, 0x00, 0xF0, 0x72, 0xFB, 0x16, 0x98, 0xB0, 0xF9, 0x00, 0x10, 0x14, 0x98, 0x00, 0x29, 0xB0, 0xF9, 0x00, 0x00, 0x05, 0xDD, 0x03, 0x28, 0x03, 0xD1, 0x12, 0x98 , -0x02, 0x22, 0x00, 0xF0, 0x64, 0xFB, 0x05, 0x98, 0x04, 0x78, 0x0B, 0x98, 0x00, 0x78, 0x0C, 0x90, 0x08, 0x98, 0xBB, 0x2C, 0x01, 0x78, 0x02, 0xD0, 0xAA, 0x2C, 0x2F, 0xD0, 0x31, 0xE0, 0x0C, 0x98, 0x01, 0x28, 0x0B, 0xD1, 0x0D, 0x98, 0x17, 0x9A, 0x10, 0x60, 0x0C, 0x54, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x0F, 0x98, 0x18, 0x9A, 0x10, 0x60, 0x19, 0x9A, 0x11, 0x98, 0x10, 0x60, 0x47, 0x4A, 0x15, 0x98, 0x02, 0x60, 0x0C, 0x98, 0x02, 0x28, 0x0B, 0xD1, 0x0E, 0x98, 0x17, 0x9A, 0x10, 0x60, 0x10, 0x98, 0x18, 0x9A, 0x10, 0x60, 0x19, 0x9A, 0x12, 0x98, 0x10, 0x60, 0x41, 0x4A, 0x15, 0x98, 0x02, 0x60, 0xCC, 0x20, 0x0F, 0xE0, 0x08, 0x99, 0x09, 0x78, 0x0C, 0xE0, 0x02, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x0B, 0x99, 0x08, 0x70, 0x1A, 0x99, 0x0B, 0x80, 0x13, 0x99, 0x00, 0x20, 0x08, 0x80, 0x08, 0x98, 0x01, 0x78, 0xBB, 0x20, 0x05, 0x9A, 0x10, 0x70, 0x06, 0x29, 0x07, 0x99, 0x11, 0xD1, 0x06, 0x20, 0x08, 0x60, 0x20, 0x98 , -0x00, 0x25, 0x05, 0x70, 0x21, 0x98, 0x29, 0x46, 0x04, 0x22, 0xFB, 0xF7, 0x27, 0xFB, 0x01, 0x20, 0x00, 0xF0, 0x3A, 0xFA, 0x02, 0x20, 0x00, 0xF0, 0x37, 0xFA, 0x22, 0x98, 0x05, 0x60, 0x07, 0x98, 0x04, 0x99, 0x00, 0x68, 0x07, 0x28, 0x44, 0xD1, 0x09, 0x78, 0x03, 0x9C, 0x80, 0x29, 0x40, 0xD1, 0x38, 0x34, 0x21, 0x78, 0x64, 0x1C, 0x22, 0x46, 0x00, 0x29, 0x3A, 0xD1, 0x20, 0x98, 0x90, 0xF8, 0x00, 0xA0, 0x22, 0x98, 0x05, 0x90, 0xD0, 0xF8, 0x00, 0x90, 0x51, 0x46, 0x48, 0x46, 0xFD, 0xF7, 0x79, 0xF9, 0x5F, 0xFA, 0x80, 0xF8, 0x21, 0x9F, 0x15, 0x78, 0x51, 0x46, 0x48, 0x46, 0x17, 0xF8, 0x08, 0x30, 0xFD, 0xF7, 0xD4, 0x54, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x6F, 0xF9, 0x1E, 0x46, 0x1B, 0x1D, 0xC0, 0xB2, 0x38, 0x5C, 0x00, 0x1D, 0xA8, 0x42, 0x28, 0x46, 0x07, 0xDD, 0x80, 0x18, 0x82, 0x1C, 0x10, 0x78, 0x2D, 0x18, 0xAD, 0x1C, 0xAD, 0xB2, 0xAB, 0x42, 0xF7, 0xDC, 0x04, 0xF8, 0x01, 0x6B, 0x11, 0x49, 0x32, 0x46 , -0x20, 0x46, 0x01, 0xEB, 0x48, 0x11, 0xFA, 0xF7, 0xDC, 0xF9, 0xAD, 0x1B, 0xFF, 0x20, 0x34, 0x19, 0xAD, 0x1E, 0x04, 0xF8, 0x01, 0x0B, 0x25, 0x70, 0x05, 0x98, 0x01, 0x68, 0x49, 0x1C, 0x01, 0x60, 0x07, 0x98, 0x00, 0x68, 0x07, 0x28, 0x04, 0xD0, 0x06, 0x99, 0x08, 0x68, 0x20, 0xF4, 0x80, 0x30, 0x08, 0x60, 0x23, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC0, 0x46, 0x94, 0x57, 0x02, 0x00, 0xD4, 0x57, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x6E, 0x48, 0x2D, 0xE9, 0xF0, 0x47, 0x6E, 0x4D, 0x82, 0x89, 0x4A, 0xF6, 0x55, 0x21, 0xAD, 0xF5, 0xFE, 0x7D, 0x91, 0x42, 0x4F, 0xF0, 0x00, 0x01, 0xAD, 0xF1, 0x38, 0x0D, 0x12, 0xD1, 0x29, 0x60, 0x68, 0x4A, 0x11, 0x70, 0x41, 0xF2, 0x10, 0x41, 0x81, 0x81, 0x4F, 0xF6, 0xFF, 0x70, 0x66, 0x49, 0x08, 0x60, 0x28, 0x68, 0x00, 0x90, 0x02, 0x22, 0x05, 0x21, 0x03, 0x20, 0x41, 0xF2, 0x34, 0x23, 0xF3, 0xF7, 0x48, 0xF8, 0x29, 0x68, 0x61, 0x4C, 0x01, 0x29, 0x20, 0x68, 0x40, 0xF0, 0xAF, 0x80 , -0x5F, 0x4D, 0x02, 0x28, 0x29, 0x68, 0x23, 0xD1, 0x9C, 0x55, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x5E, 0x48, 0x00, 0x68, 0x5F, 0x4A, 0x12, 0x5C, 0x00, 0x92, 0x01, 0x91, 0x5E, 0x49, 0x09, 0x68, 0x02, 0x91, 0x5B, 0x49, 0x0B, 0x5C, 0x03, 0x20, 0x07, 0x21, 0x04, 0x22, 0xF3, 0xF7, 0x2E, 0xF8, 0x5B, 0x49, 0x4A, 0x79, 0x59, 0x48, 0x00, 0x92, 0x02, 0x79, 0x01, 0x92, 0x40, 0x79, 0x04, 0x22, 0x02, 0x90, 0x03, 0x20, 0x0B, 0x79, 0x07, 0x21, 0xF3, 0xF7, 0x20, 0xF8, 0x03, 0x20, 0x20, 0x60, 0xEC, 0xF7, 0x1A, 0xFF, 0x20, 0x68, 0x29, 0x68, 0x04, 0x28, 0x15, 0xD1, 0x0D, 0x20, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x25, 0x8D, 0xF8, 0x14, 0x50, 0x8D, 0xF8, 0x15, 0x10, 0x28, 0x46, 0x63, 0x21, 0x00, 0xF0, 0xAA, 0xFB, 0x63, 0x21, 0x28, 0x46, 0x00, 0xF0, 0xFA, 0xFA, 0x03, 0xA9, 0x04, 0xA8, 0xE0, 0xF7, 0xCA, 0xFC, 0x05, 0x20, 0x20, 0x60, 0x46, 0x4D, 0x05, 0x28, 0x29, 0x68, 0x01, 0xF1, 0x01, 0x01, 0x29, 0x60, 0x1D, 0xD1 , -0x44, 0x4A, 0x8A, 0x42, 0x1A, 0xD1, 0x43, 0x48, 0x01, 0x68, 0x00, 0x91, 0x40, 0x68, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0x06, 0x21, 0x41, 0x4E, 0x33, 0x46, 0x22, 0x3B, 0xF2, 0xF7, 0xEB, 0xFF, 0x3E, 0x48, 0x01, 0x68, 0x00, 0x91, 0x40, 0x68, 0x33, 0x46, 0x06, 0x21, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0xF2, 0xF7, 0xE0, 0xFF, 0x00, 0x20, 0x28, 0x60, 0x20, 0x68, 0x06, 0x28, 0x47, 0xD1, 0x4F, 0xF0, 0x64, 0x56, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x07, 0x0A, 0xC4, 0xF8, 0x00, 0xA0, 0x03, 0x20, 0x48, 0xF2, 0x70, 0x53, 0x01, 0x22, 0x04, 0x21, 0xF2, 0xF7, 0xD0, 0xFF, 0xDF, 0xF8, 0xCC, 0x80, 0x31, 0x4F, 0x48, 0xF2, 0x70, 0x59, 0x01, 0x25, 0x49, 0xEA, 0x05, 0x03, 0x01, 0x22, 0x04, 0x21, 0x03, 0x20, 0xF2, 0xF7, 0xC3, 0xFF, 0x00, 0x24, 0x17, 0xF8, 0x02, 0x0F, 0x20, 0xE0, 0x69, 0x01, 0x04, 0xEB, 0x08, 0x02, 0x88, 0x18, 0xC6, 0x1C, 0x43, 0x78, 0x00, 0x93, 0x80, 0x78, 0x01, 0x90, 0x30, 0x78, 0x02, 0x90 , -0x53, 0x5C, 0x51, 0x46, 0x04, 0x22, 0x03, 0x20, 0xF2, 0xF7, 0xAE, 0xFF, 0x38, 0x78, 0x01, 0x1B, 0xB1, 0xF1, 0xFF, 0x3F, 0x08, 0xD1, 0xF0, 0x78, 0x00, 0x90, 0xB3, 0x78, 0x03, 0x20, 0x02, 0x22, 0x05, 0x21, 0xF2, 0xF7, 0xA1, 0xFF, 0x38, 0x78, 0x24, 0x1D, 0xE4, 0xB2, 0xA0, 0x42, 0xDC, 0xDC, 0xAD, 0x1C, 0xED, 0xB2, 0x04, 0x2D, 0xCD, 0xDB, 0x63, 0x21, 0x4F, 0xF4, 0x05, 0x70, 0xF1, 0xF7, 0xA3, 0xFC, 0xE1, 0xF7, 0x85, 0xFD, 0x7F, 0xB0, 0x0E, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xC0, 0x46, 0x04, 0x74, 0x00, 0x20, 0x50, 0x57, 0x02, 0x00, 0x6C, 0x5D, 0x02, 0x00, 0x40, 0x00, 0x3D, 0x80, 0x4C, 0x57, 0x02, 0x00, 0x58, 0x57, 0x02, 0x00, 0x90, 0x57, 0x02, 0x00, 0x60, 0x57, 0x02, 0x00, 0x70, 0x57, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0x80, 0x57, 0x02, 0x00, 0x2C, 0x57, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x88, 0x57, 0x02, 0x00, 0x54, 0x57, 0x02, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x38, 0x58, 0x02, 0x00, 0x40, 0x58 , -0x02, 0x00, 0x66, 0x55, 0xDD, 0xEE, 0xDB, 0x58, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x57, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x58, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x4A, 0x4A, 0x49, 0x4D, 0x00, 0x90, 0xB2, 0xF9, 0x00, 0x20, 0x43, 0xA3, 0x29, 0x78, 0x01, 0x93, 0x43, 0xA3, 0x01, 0x28, 0x02, 0x93, 0x47, 0x4E, 0xDF, 0xF8, 0x1C, 0x81, 0xDF, 0xF8, 0x1C, 0x91, 0x1E, 0xD0, 0x43, 0x48, 0x04, 0x78, 0x48, 0x01, 0x87, 0x19, 0x30, 0x18, 0x01, 0x99, 0x06, 0x22, 0xF9, 0xF7, 0xC8, 0xFF, 0x40, 0x46, 0x01, 0x78, 0x00, 0x68, 0x07, 0xF1, 0x06, 0x07, 0x07, 0xF8, 0x01, 0x1B, 0x07, 0xF8, 0x01, 0x4B, 0x4F, 0xF0, 0x00, 0x01, 0x07, 0xF8, 0x01, 0x1B, 0x20, 0xB9, 0x39, 0x70, 0x28, 0x78, 0x4E, 0x46, 0x0A, 0x21, 0x58, 0xE0, 0xDF, 0xF8, 0xE4, 0xB0, 0x0F, 0xE0, 0xD4, 0xB2, 0x48, 0x01, 0x87, 0x19, 0x30, 0x18, 0x02, 0x99, 0x07, 0x22, 0xF9, 0xF7, 0xAA, 0xFF, 0xFF, 0x1D, 0x00, 0x20, 0xDF, 0xF8, 0xCC, 0xB0, 0x07, 0xF8, 0x01, 0x4B, 0x07, 0xF8, 0x01, 0x0B, 0x16, 0x2C, 0xB2, 0x46, 0xAE, 0xBF, 0x14, 0x20, 0x84, 0x59 , -0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x60, 0x1E, 0xC0, 0xB2, 0x38, 0x70, 0x4E, 0x46, 0x7F, 0x1C, 0x40, 0x1C, 0xC2, 0xB2, 0x28, 0x78, 0x5B, 0x46, 0x00, 0x21, 0x32, 0x54, 0x38, 0x46, 0x00, 0xF0, 0xBC, 0xF9, 0x28, 0x78, 0x16, 0x2C, 0x31, 0x5C, 0x01, 0xF1, 0x0A, 0x01, 0x31, 0x54, 0x00, 0xF1, 0x01, 0x00, 0xC0, 0xB2, 0x28, 0x70, 0x2B, 0xDB, 0x00, 0x99, 0x0A, 0xEB, 0x40, 0x10, 0x07, 0x46, 0x01, 0x29, 0xA4, 0xF1, 0x01, 0x09, 0x09, 0xD0, 0x01, 0x99, 0x06, 0x22, 0xF9, 0xF7, 0x79, 0xFF, 0x40, 0x46, 0x00, 0x78, 0xBF, 0x1D, 0x07, 0xF8, 0x01, 0x0B, 0x04, 0xE0, 0x02, 0x99, 0x07, 0x22, 0xF9, 0xF7, 0x6F, 0xFF, 0xFF, 0x1D, 0x07, 0xF8, 0x01, 0x4B, 0x15, 0x3C, 0x15, 0x21, 0x28, 0x78, 0xE2, 0xB2, 0x5B, 0x46, 0x07, 0xF8, 0x01, 0x1B, 0x32, 0x54, 0x07, 0xF8, 0x01, 0x9B, 0x38, 0x46, 0x00, 0xF0, 0x8B, 0xF9, 0x28, 0x78, 0x31, 0x5C, 0x0A, 0x31, 0x31, 0x54, 0x40, 0x1C, 0x28, 0x70, 0xBD, 0xE8, 0xFE, 0x8F, 0xC0, 0x46 , -0x54, 0x54, 0x54, 0x4B, 0x45, 0x59, 0x00, 0xC0, 0x54, 0x54, 0x54, 0x53, 0x53, 0x49, 0x44, 0x00, 0x54, 0x58, 0x02, 0x00, 0xE6, 0x58, 0x02, 0x00, 0xE8, 0x58, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0xDC, 0x58, 0x02, 0x00, 0xD4, 0x57, 0x02, 0x00, 0x94, 0x57, 0x02, 0x00, 0xFF, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0xF7, 0xF7, 0x4C, 0x5A, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE3, 0xFE, 0x15, 0x49, 0x15, 0x4A, 0x0D, 0x68, 0x01, 0xA9, 0x92, 0xE8, 0x8C, 0x00, 0x81, 0xE8, 0x8C, 0x00, 0xF7, 0xF7, 0xFD, 0xFE, 0x01, 0x98, 0x11, 0x49, 0x28, 0x1A, 0x03, 0x9D, 0x25, 0x60, 0x02, 0x9A, 0x80, 0x18, 0x82, 0x42, 0x30, 0x60, 0x0E, 0xD8, 0x08, 0x46, 0x00, 0x68, 0x22, 0x68, 0x82, 0x42, 0x0E, 0xD2, 0x68, 0x46, 0xE8, 0xF7, 0xB9, 0xFF, 0x9D, 0xF8, 0x00, 0x00, 0x05, 0xF1, 0x01, 0x05, 0x30, 0xB9, 0x03, 0x95, 0x03, 0xE0, 0x25, 0x68, 0x6D, 0x1C, 0x25, 0x60, 0x0C, 0x46, 0x25, 0x60, 0x00, 0x20, 0x00, 0x90 , -0xFF, 0xBD, 0x60, 0x55, 0x30, 0x80, 0x24, 0x5D, 0x00, 0x20, 0x6C, 0x5D, 0x02, 0x00, 0x70, 0xB5, 0x4D, 0x00, 0x20, 0x2D, 0x4F, 0xF0, 0x00, 0x01, 0x0C, 0x46, 0x4F, 0xEA, 0x55, 0x13, 0x09, 0xD3, 0x50, 0xF8, 0x21, 0x60, 0xB6, 0xF1, 0xFF, 0x3F, 0x04, 0xD1, 0x49, 0x1C, 0xC9, 0xB2, 0x20, 0x3D, 0x5B, 0x1E, 0xF5, 0xD1, 0x4D, 0xB1, 0x20, 0x2D, 0x09, 0xD2, 0x01, 0x23, 0xAB, 0x40, 0x5B, 0x1E, 0x50, 0xF8, 0x21, 0x00, 0x18, 0x40, 0x83, 0x42, 0x01, 0xD1, 0x4F, 0xF0, 0x01, 0x04, 0x07, 0x48, 0x03, 0x78, 0x2C, 0xB9, 0x01, 0x21, 0x91, 0x40, 0xC9, 0x43, 0xC9, 0xB2, 0x0B, 0x40, 0x03, 0xE0, 0x01, 0x21, 0x91, 0x40, 0xC9, 0xB2, 0x0B, 0x43, 0x03, 0x70, 0x70, 0xBD, 0xC0, 0x46, 0xEE, 0x58, 0x02, 0x00, 0x14, 0x5B, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x7E, 0xB5, 0x05, 0x46, 0x95, 0xF8, 0x36, 0x20, 0x0E, 0x46, 0x0F, 0x49, 0x07, 0x2A, 0x12, 0xBF, 0x08, 0x68, 0x01, 0x20, 0x08, 0x60, 0x0D, 0x4C, 0x00, 0x92, 0x21, 0x68 , -0x41, 0xF2, 0x12, 0x13, 0x04, 0x22, 0x01, 0x91, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF2, 0xF7, 0x6B, 0xFD, 0x31, 0x46, 0x28, 0x46, 0xE7, 0xF7, 0x21, 0xFC, 0x21, 0x68, 0x00, 0x22, 0x05, 0x29, 0x02, 0xD1, 0x04, 0x49, 0x08, 0x31, 0x0A, 0x60, 0x7E, 0xBD, 0xC0, 0x46, 0x50, 0x57, 0x02, 0x00, 0x4C, 0x57, 0x02, 0x00, 0x00, 0x7C, 0x00, 0x20, 0x0E, 0x49, 0x09, 0x68, 0x49, 0x08, 0x15, 0xD2, 0x0D, 0x49, 0x09, 0x78, 0x91, 0xB1, 0x44, 0xF2, 0xE9, 0x21, 0x68, 0xB9, 0x0B, 0x48, 0x01, 0x78, 0x07, 0x48, 0x01, 0x29, 0x03, 0xD1, 0x0A, 0x49, 0x09, 0x78, 0x0E, 0x29, 0x02, 0xD0, 0x44, 0xF2, 0xDE, 0x21, 0x41, 0x60, 0x01, 0x21, 0x00, 0xE0, 0x06, 0x48, 0x01, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x00, 0x97, 0x3C, 0x80, 0x10, 0x0C, 0x30, 0x80, 0xDD, 0x6A, 0x00, 0x20, 0xE0, 0x7C, 0x00, 0x20, 0xA6, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x00, 0xB5, 0xAD, 0xF1, 0x18, 0x0D, 0x4F, 0xF0, 0x09, 0x00, 0x00, 0x90, 0x4F, 0xF4 , -0x0C, 0x60, 0x03, 0x90, 0x4F, 0xF0, 0x00, 0x00, 0x01, 0x90, 0x02, 0x90, 0x08, 0x48, 0x08, 0x49, 0x05, 0x90, 0x08, 0x68, 0x20, 0xB9, 0xDC, 0x5B, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x68, 0x46, 0x03, 0x22, 0xED, 0xF7, 0x3A, 0xFA, 0x03, 0xE0, 0x68, 0x46, 0x03, 0x22, 0xED, 0xF7, 0xC1, 0xFC, 0x06, 0xB0, 0x00, 0xBD, 0xC0, 0x46, 0x81, 0x5C, 0x02, 0x00, 0xDC, 0x7C, 0x00, 0x20, 0x1C, 0xB5, 0x0F, 0x4C, 0x22, 0x68, 0x01, 0x2A, 0x15, 0xD1, 0x0C, 0x48, 0x00, 0x68, 0x07, 0x28, 0x14, 0xBF, 0x40, 0x20, 0x4F, 0xF4, 0x05, 0x70, 0x63, 0x21, 0xF1, 0xF7, 0x0F, 0xFA, 0x20, 0x68, 0x00, 0x90, 0x43, 0xF2, 0x33, 0x33, 0x06, 0x21, 0x40, 0x20, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0xF2, 0xF7, 0xF4, 0xFC, 0x1C, 0xBD, 0xF1, 0xF7, 0x01, 0xFA, 0x1C, 0xBD, 0x4C, 0x57, 0x02, 0x00, 0x50, 0x57, 0x02, 0x00, 0x1E, 0xB5, 0x04, 0x46, 0x0A, 0x49, 0x00, 0x20, 0x0A, 0x4A, 0x08, 0x60, 0x0A, 0x49, 0x00, 0x90, 0x01, 0x90, 0x11, 0x60 , -0x09, 0x4A, 0x45, 0xF2, 0x55, 0x53, 0x02, 0x91, 0x10, 0x60, 0x07, 0x21, 0x04, 0x22, 0x03, 0x20, 0xF2, 0xF7, 0xD8, 0xFC, 0x20, 0x46, 0xE7, 0xF7, 0x59, 0xFD, 0x1E, 0xBD, 0x50, 0x57, 0x02, 0x00, 0x04, 0x74, 0x00, 0x20, 0x34, 0x12, 0x66, 0x09, 0x4C, 0x57, 0x02, 0x00, 0x00, 0xB5, 0x0B, 0x49, 0x00, 0x20, 0x08, 0x60, 0xE0, 0x20, 0xF7, 0xF7, 0xAA, 0xFD, 0x09, 0x49, 0x09, 0x78, 0x49, 0xB1, 0x08, 0x49, 0x0A, 0x78, 0x08, 0x49, 0x00, 0x2A, 0x06, 0xBF, 0x01, 0x22, 0x09, 0x1F, 0x44, 0xF2, 0xA4, 0x5C, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE9, 0x22, 0x0A, 0x60, 0xF7, 0xF7, 0xA1, 0xFD, 0x00, 0xBD, 0xC0, 0x46, 0xDC, 0x7C, 0x00, 0x20, 0xDD, 0x6A, 0x00, 0x20, 0xA7, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x50, 0xB9, 0x09, 0x48, 0x00, 0x78, 0x01, 0x28, 0x06, 0xD1, 0x08, 0x48, 0x00, 0x78, 0x0E, 0x28, 0x08, 0xBF, 0x44, 0xF2, 0xCB, 0x20, 0x01, 0xD0, 0x44, 0xF2, 0xDE, 0x20, 0x04, 0x49, 0x08, 0x60, 0x01, 0x20 , -0x41, 0xF8, 0x04, 0x0C, 0x70, 0x47, 0xE0, 0x7C, 0x00, 0x20, 0xA6, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x30, 0xB5, 0x0D, 0x46, 0x84, 0x69, 0xDC, 0xF7, 0x97, 0xFB, 0x24, 0x1D, 0x01, 0x28, 0x04, 0xEB, 0x45, 0x01, 0x06, 0xD1, 0x89, 0x8E, 0x04, 0xEB, 0x85, 0x04, 0x11, 0xB9, 0x21, 0x69, 0x01, 0xB9, 0x00, 0x20, 0x30, 0xBD, 0x30, 0xB5, 0x05, 0x46, 0x5A, 0xB1, 0x03, 0xEB, 0x41, 0x03, 0x1C, 0x78, 0x59, 0x78, 0x41, 0xEA, 0x04, 0x11, 0x52, 0x1E, 0x03, 0xF1, 0x02, 0x03, 0x05, 0xF8, 0x01, 0x1B, 0xF5, 0xD1, 0x30, 0xBD, 0x00, 0xB5, 0x00, 0x20, 0xE7, 0xF7, 0xD6, 0xFE, 0x03, 0x48, 0x01, 0x68, 0x03, 0x29, 0x04, 0xBF, 0x04, 0x21, 0x01, 0x60, 0x00, 0xBD, 0xC0, 0x46, 0x4C, 0x57, 0x02, 0x00, 0x03, 0x4A, 0x12, 0x68, 0x01, 0x2A, 0x04, 0xBF, 0x02, 0x48, 0x63, 0x21, 0xF1, 0xF7, 0x76, 0xB9, 0x50, 0x57, 0x02, 0x00, 0x02, 0x20, 0x01, 0x00, 0x6C, 0x5D, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/drivers/cc3000/src/patch_prog.c b/drivers/cc3000/src/patch_prog.c deleted file mode 100644 index fd128928fbaf..000000000000 --- a/drivers/cc3000/src/patch_prog.c +++ /dev/null @@ -1,414 +0,0 @@ -#include -#include -#include "cc3000_common.h" -#include "nvmem.h" -#include "ccspi.h" -#include "hci.h" -#include "wlan.h" -#include "patch_prog.h" -#define BIT0 0x1 -#define BIT1 0x2 -#define BIT2 0x4 -#define BIT3 0x8 -#define BIT4 0x10 -#define BIT5 0x20 -#define BIT6 0x40 -#define BIT7 0x80 - -static unsigned char ucStatus_Dr; -static unsigned char ucStatus_FW; -static unsigned char return_status = 0xFF; - -static signed char mac_status = -1; -static unsigned char counter = 0; - -// Array to store RM parameters from EEPROM. -static unsigned char cRMParamsFromEeprom[128]; -// Array to store MAC address from EEPROM. -static unsigned char cMacFromEeprom[MAC_ADDR_LEN]; -// Smart Config Prefix -static const char aucCC3000_prefix[] = {'T', 'T', 'T'}; - -static void systick_sleep(unsigned long ms) { - extern void HAL_Delay(volatile uint32_t Delay); - HAL_Delay(ms); -} - -// 2 dim array to store address and length of new FAT -static const unsigned short aFATEntries[2][NVMEM_RM_FILEID + 1] = -/* address */ {{0x50, 0x1f0, 0x390, 0x1390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830}, -/* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200}}; -/* 0. NVS */ -/* 1. NVS Shadow */ -/* 2. Wireless Conf */ -/* 3. Wireless Conf Shadow */ -/* 4. BT (WLAN driver) Patches */ -/* 5. WiLink (Firmware) Patches */ -/* 6. MAC addr */ -/* 7. Frontend Vars */ -/* 8. IP config */ -/* 9. IP config Shadow */ -/* 10. Bootloader Patches */ -/* 11. Radio Module params */ -/* 12. AES128 for smart config */ -/* 13. user file */ -/* 14. user file */ -/* 15. user file */ - -//***************************************************************************** -// -//! sendDriverPatch -//! -//! \param pointer to the length -//! -//! \return none -//! -//! \brief The function returns a pointer to the driver patch: -//! since there is no patch yet - it returns 0 -// -//***************************************************************************** - -static char *sendDriverPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - - -//***************************************************************************** -// -//! sendBootLoaderPatch -//! -//! \param pointer to the length -//! -//! \return none -//! -//! \brief The function returns a pointer to the boot loader patch: -//! since there is no patch yet - it returns 0 -// -//***************************************************************************** - -static char *sendBootLoaderPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -//***************************************************************************** -// -//! sendWLFWPatch -//! -//! \param pointer to the length -//! -//! \return none -//! -//! \brief The function returns a pointer to the FW patch: -//! since there is no patch yet - it returns 0 -// -//***************************************************************************** - -static char *sendWLFWPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -//***************************************************************************** -// -//! CC3000_UsynchCallback -//! -//! \param Event type -//! -//! \return none -//! -//! \brief The function handles asynchronous events that come from CC3000 -//! device and operates a LED4 to have an on-board indication -// -//***************************************************************************** - -static void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length) -{ - -} - -//***************************************************************************** -// -//! initDriver -//! -//! \param[in] cRequestPatch 0 to load with EEPROM patches -//! and 1 to load with no patches -//! -//! \return none -//! -//! \brief The function initializes a CC3000 device -//! and triggers it to start operation -// -//***************************************************************************** -static int initDriver(unsigned short cRequestPatch) -{ - // WLAN On API Implementation - wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, - ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin); - - // Trigger a WLAN device - wlan_start(cRequestPatch); - wlan_smart_config_set_prefix((char*)aucCC3000_prefix); - wlan_ioctl_set_connection_policy(0, 0, 0); - wlan_ioctl_del_profile(255); - - // Mask out all non-required events from CC3000 - wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE| - HCI_EVNT_WLAN_UNSOL_INIT| - HCI_EVNT_WLAN_ASYNC_PING_REPORT); - - //unsolicicted_events_timer_init(); - systick_sleep(100); - return(0); -} - - -//***************************************************************************** -// -//! fat_read_content -//! -//! \param[out] is_allocated array of is_allocated in FAT table:\n -//! an allocated entry implies the address and length of the -//! file are valid. -//! 0: not allocated; 1: allocated. -//! \param[out] is_valid array of is_valid in FAT table:\n -//! a valid entry implies the content of the file is relevant. -//! 0: not valid; 1: valid. -//! \param[out] write_protected array of write_protected in FAT table:\n -//! a write protected entry implies it is not possible to write -//! into this entry. -//! 0: not protected; 1: protected. -//! \param[out] file_address array of file address in FAT table:\n -//! this is the absolute address of the file in the EEPROM. -//! \param[out] file_length array of file length in FAT table:\n -//! this is the upper limit of the file size in the EEPROM. -//! -//! \return on succes 0, error otherwise -//! -//! \brief parse the FAT table from eeprom -// -//***************************************************************************** -static unsigned char __attribute__ ((unused)) -fat_read_content(unsigned char *is_allocated, unsigned char *is_valid, - unsigned char *write_protected, unsigned short *file_address, unsigned short *file_length) -{ - unsigned short index; - unsigned char ucStatus; - unsigned char fatTable[48]; - unsigned char* fatTablePtr = fatTable; - - // - // Read in 6 parts to work with tiny driver - // - for (index = 0; index < 6; index++) - { - ucStatus = nvmem_read(16, 8, 4 + 8*index, fatTablePtr); - fatTablePtr += 8; - } - - fatTablePtr = fatTable; - - for (index = 0; index <= NVMEM_RM_FILEID; index++) - { - *is_allocated++ = (*fatTablePtr) & BIT0; - *is_valid++ = ((*fatTablePtr) & BIT1) >> 1; - *write_protected++ = ((*fatTablePtr) & BIT2) >> 2; - *file_address++ = ((*(fatTablePtr+1)<<8) | (*fatTablePtr)) & (BIT4|BIT5|BIT6|BIT7); - *file_length++ = ((*(fatTablePtr+3)<<8) | (*(fatTablePtr+2))) & (BIT4|BIT5|BIT6|BIT7); - - // - // Move to next file ID - // - fatTablePtr += 4; - } - - return ucStatus; -} - -//***************************************************************************** -// -//! fat_write_content -//! -//! \param[in] file_address array of file address in FAT table:\n -//! this is the absolute address of the file in the EEPROM. -//! \param[in] file_length array of file length in FAT table:\n -//! this is the upper limit of the file size in the EEPROM. -//! -//! \return on succes 0, error otherwise -//! -//! \brief parse the FAT table from eeprom -// -//***************************************************************************** -static unsigned char fat_write_content(unsigned short const *file_address, - unsigned short const *file_length) -{ - unsigned short index = 0; - unsigned char ucStatus; - unsigned char fatTable[48]; - unsigned char* fatTablePtr = fatTable; - - // - // First, write the magic number. - // - ucStatus = nvmem_write(16, 2, 0, (unsigned char*)"LS"); - - for (; index <= NVMEM_RM_FILEID; index++) - { - // - // Write address low char and mark as allocated. - // - *fatTablePtr++ = (unsigned char)(file_address[index] & 0xff) | BIT0; - - // - // Write address high char. - // - *fatTablePtr++ = (unsigned char)((file_address[index]>>8) & 0xff); - - // - // Write length low char. - // - *fatTablePtr++ = (unsigned char)(file_length[index] & 0xff); - - // - // Write length high char. - // - *fatTablePtr++ = (unsigned char)((file_length[index]>>8) & 0xff); - } - - // - // Second, write the FAT. - // Write in two parts to work with tiny driver. - // - ucStatus = nvmem_write(16, 24, 4, fatTable); - ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]); - - // - // Third, we want to erase any user files. - // - memset(fatTable, 0, sizeof(fatTable)); - ucStatus = nvmem_write(16, 16, 52, fatTable); - - return ucStatus; -} - -void patch_prog_start() -{ - unsigned short index; - unsigned char *pRMParams; - - printf("Initializing module...\n"); - - // Init module and request to load with no patches. - // This is in order to overwrite restrictions to - // write to specific places in EEPROM. - initDriver(1); - - // Read MAC address. - mac_status = nvmem_get_mac_address(cMacFromEeprom); - - return_status = 1; - - printf("Reading RM parameters...\n"); - while ((return_status) && (counter < 3)) { - // Read RM parameters. - // Read in 16 parts to work with tiny driver. - return_status = 0; - pRMParams = cRMParamsFromEeprom; - for (index = 0; index < 16; index++) { - return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams); - pRMParams += 8; - } - counter++; - } - - // If RM file is not valid, load the default one. - if (counter == 3) { - printf("RM is not valid, loading default one...\n"); - pRMParams = (unsigned char *)cRMdefaultParams; - } else { - printf("RM is valid.\n"); - pRMParams = cRMParamsFromEeprom; - } - - return_status = 1; - - printf("Writing new FAT\n"); - while (return_status) { - // Write new FAT. - return_status = fat_write_content(aFATEntries[0], aFATEntries[1]); - } - - return_status = 1; - - printf("Writing RM parameters...\n"); - while (return_status) { - // Write RM parameters. - // Write in 4 parts to work with tiny driver. - return_status = 0; - - for (index = 0; index < 4; index++) { - return_status |= nvmem_write(NVMEM_RM_FILEID, - 32, - 32*index, - (pRMParams + 32*index)); - } - } - - return_status = 1; - - // Write back the MAC address, only if exists. - if (mac_status == 0) { - // Zero out MCAST bit if set. - cMacFromEeprom[0] &= 0xfe; - printf("Writing back MAC address..\n"); - while (return_status) { - return_status = nvmem_set_mac_address(cMacFromEeprom); - } - } - - // Update driver - ucStatus_Dr = 1; - printf("Updating driver patch...\n"); - while (ucStatus_Dr) { - // Writing driver patch to EEPRROM - PROTABLE CODE - // Note that the array itself is changing between the - // different Service Packs. - ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, - drv_length, - wlan_drv_patch); - } - - // Update firmware - ucStatus_FW = 1; - printf("Updating firmware patch...\n"); - while (ucStatus_FW) { - // Writing FW patch to EEPRROM - PROTABLE CODE - // Note that the array itself is changing between the - // different Service Packs. - ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, - fw_length, - fw_patch); - } - - printf("Update complete, resetting module\n"\ - "If this doesn't work, reset manually...\n"); - - wlan_stop(); - systick_sleep(500); - - // Re-Init module and request to load with patches. - initDriver(0); - - // If MAC does not exist, it is recommended - // that the user will write a valid mac address. - if (mac_status != 0) { - printf("MAC address is not valid, please write a new one\n"); - } - - // Patch update done - printf("All done, call wlan.patch_version()\n"); -} diff --git a/drivers/cc3000/src/security.c b/drivers/cc3000/src/security.c deleted file mode 100644 index 62b4f881343a..000000000000 --- a/drivers/cc3000/src/security.c +++ /dev/null @@ -1,530 +0,0 @@ -/***************************************************************************** -* -* security.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup security_api -//! @{ -// -//***************************************************************************** - -#include "security.h" - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -// foreward sbox -const UINT8 sbox[256] = { -//0 1 2 3 4 5 6 7 8 9 A B C D E F -0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 -0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 -0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2 -0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3 -0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4 -0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5 -0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6 -0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7 -0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8 -0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9 -0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A -0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B -0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C -0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D -0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F -// inverse sbox -const UINT8 rsbox[256] = -{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb -, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb -, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e -, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 -, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 -, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 -, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 -, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b -, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 -, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e -, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b -, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 -, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f -, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef -, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 -, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; -// round constant -const UINT8 Rcon[11] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; - - -UINT8 expandedKey[176]; - -//***************************************************************************** -// -//! expandKey -//! -//! @param key AES128 key - 16 bytes -//! @param expandedKey expanded AES128 key -//! -//! @return none -//! -//! @brief expend a 16 bytes key for AES128 implementation -//! -//***************************************************************************** - -void expandKey(UINT8 *expandedKey, UINT8 *key) -{ - UINT16 ii, buf1; - for (ii=0;ii<16;ii++) - expandedKey[ii] = key[ii]; - for (ii=1;ii<11;ii++){ - buf1 = expandedKey[ii*16 - 4]; - expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii]; - expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1]; - expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2]; - expandedKey[ii*16 + 3] = sbox[buf1 ]^expandedKey[(ii-1)*16 + 3]; - expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0]; - expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1]; - expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2]; - expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3]; - expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4]; - expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5]; - expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6]; - expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7]; - expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8]; - expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9]; - expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10]; - expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11]; - } - -} - -//***************************************************************************** -// -//! galois_mul2 -//! -//! @param value argument to multiply -//! -//! @return multiplied argument -//! -//! @brief multiply by 2 in the galois field -//! -//***************************************************************************** - -UINT8 galois_mul2(UINT8 value) -{ - if (value>>7) - { - value = value << 1; - return (value^0x1b); - } else - return value<<1; -} - -//***************************************************************************** -// -//! aes_encr -//! -//! @param[in] expandedKey expanded AES128 key -//! @param[in/out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief internal implementation of AES128 encryption. -//! straight forward aes encryption implementation -//! first the group of operations -//! - addRoundKey -//! - subbytes -//! - shiftrows -//! - mixcolums -//! is executed 9 times, after this addroundkey to finish the 9th -//! round, after that the 10th round without mixcolums -//! no further subfunctions to save cycles for function calls -//! no structuring with "for (....)" to save cycles. -//! -//! -//***************************************************************************** - -void aes_encr(UINT8 *state, UINT8 *expandedKey) -{ - UINT8 buf1, buf2, buf3, round; - - for (round = 0; round < 9; round ++){ - // addroundkey, sbox and shiftrows - // row 0 - state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; - state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])]; - state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])]; - state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])]; - // row 1 - buf1 = state[1] ^ expandedKey[(round*16) + 1]; - state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])]; - state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])]; - state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])]; - state[13] = sbox[buf1]; - // row 2 - buf1 = state[2] ^ expandedKey[(round*16) + 2]; - buf2 = state[6] ^ expandedKey[(round*16) + 6]; - state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])]; - state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])]; - state[10] = sbox[buf1]; - state[14] = sbox[buf2]; - // row 3 - buf1 = state[15] ^ expandedKey[(round*16) + 15]; - state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])]; - state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; - state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; - state[ 3] = sbox[buf1]; - - // mixcolums ////////// - // col1 - buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; - buf2 = state[0]; - buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; - buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; - buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; - buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; - // col2 - buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; - buf2 = state[4]; - buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; - buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; - buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; - buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; - // col3 - buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; - buf2 = state[8]; - buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; - buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; - buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; - buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; - // col4 - buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; - buf2 = state[12]; - buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; - buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; - buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - - } - // 10th round without mixcols - state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; - state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])]; - state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])]; - state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])]; - // row 1 - buf1 = state[1] ^ expandedKey[(round*16) + 1]; - state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])]; - state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])]; - state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])]; - state[13] = sbox[buf1]; - // row 2 - buf1 = state[2] ^ expandedKey[(round*16) + 2]; - buf2 = state[6] ^ expandedKey[(round*16) + 6]; - state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])]; - state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])]; - state[10] = sbox[buf1]; - state[14] = sbox[buf2]; - // row 3 - buf1 = state[15] ^ expandedKey[(round*16) + 15]; - state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])]; - state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; - state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; - state[ 3] = sbox[buf1]; - // last addroundkey - state[ 0]^=expandedKey[160]; - state[ 1]^=expandedKey[161]; - state[ 2]^=expandedKey[162]; - state[ 3]^=expandedKey[163]; - state[ 4]^=expandedKey[164]; - state[ 5]^=expandedKey[165]; - state[ 6]^=expandedKey[166]; - state[ 7]^=expandedKey[167]; - state[ 8]^=expandedKey[168]; - state[ 9]^=expandedKey[169]; - state[10]^=expandedKey[170]; - state[11]^=expandedKey[171]; - state[12]^=expandedKey[172]; - state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; - state[15]^=expandedKey[175]; -} - -//***************************************************************************** -// -//! aes_decr -//! -//! @param[in] expandedKey expanded AES128 key -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief internal implementation of AES128 decryption. -//! straight forward aes decryption implementation -//! the order of substeps is the exact reverse of decryption -//! inverse functions: -//! - addRoundKey is its own inverse -//! - rsbox is inverse of sbox -//! - rightshift instead of leftshift -//! - invMixColumns = barreto + mixColumns -//! no further subfunctions to save cycles for function calls -//! no structuring with "for (....)" to save cycles -//! -//***************************************************************************** - -void aes_decr(UINT8 *state, UINT8 *expandedKey) -{ - UINT8 buf1, buf2, buf3; - INT8 round; - round = 9; - - // initial addroundkey - state[ 0]^=expandedKey[160]; - state[ 1]^=expandedKey[161]; - state[ 2]^=expandedKey[162]; - state[ 3]^=expandedKey[163]; - state[ 4]^=expandedKey[164]; - state[ 5]^=expandedKey[165]; - state[ 6]^=expandedKey[166]; - state[ 7]^=expandedKey[167]; - state[ 8]^=expandedKey[168]; - state[ 9]^=expandedKey[169]; - state[10]^=expandedKey[170]; - state[11]^=expandedKey[171]; - state[12]^=expandedKey[172]; - state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; - state[15]^=expandedKey[175]; - - // 10th round without mixcols - state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; - state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; - state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8]; - state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12]; - // row 1 - buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1]; - state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13]; - state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9]; - state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5]; - state[ 1] = buf1; - // row 2 - buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10]; - buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14]; - state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2]; - state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6]; - state[10] = buf1; - state[14] = buf2; - // row 3 - buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15]; - state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3]; - state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; - state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; - state[15] = buf1; - - for (round = 8; round >= 0; round--){ - // barreto - //col1 - buf1 = galois_mul2(galois_mul2(state[0]^state[2])); - buf2 = galois_mul2(galois_mul2(state[1]^state[3])); - state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2; - //col2 - buf1 = galois_mul2(galois_mul2(state[4]^state[6])); - buf2 = galois_mul2(galois_mul2(state[5]^state[7])); - state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2; - //col3 - buf1 = galois_mul2(galois_mul2(state[8]^state[10])); - buf2 = galois_mul2(galois_mul2(state[9]^state[11])); - state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2; - //col4 - buf1 = galois_mul2(galois_mul2(state[12]^state[14])); - buf2 = galois_mul2(galois_mul2(state[13]^state[15])); - state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2; - // mixcolums ////////// - // col1 - buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; - buf2 = state[0]; - buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; - buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; - buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; - buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; - // col2 - buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; - buf2 = state[4]; - buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; - buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; - buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; - buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; - // col3 - buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; - buf2 = state[8]; - buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; - buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; - buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; - buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; - // col4 - buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; - buf2 = state[12]; - buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; - buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; - buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - - // addroundkey, rsbox and shiftrows - // row 0 - state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; - state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; - state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8]; - state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12]; - // row 1 - buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1]; - state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13]; - state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9]; - state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5]; - state[ 1] = buf1; - // row 2 - buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10]; - buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14]; - state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2]; - state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6]; - state[10] = buf1; - state[14] = buf2; - // row 3 - buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15]; - state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3]; - state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; - state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; - state[15] = buf1; - } - -} - -//***************************************************************************** -// -//! aes_encrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief AES128 encryption: -//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes -//! is computed. The AES implementation is in mode ECB (Electronic -//! Code Book). -//! -//! -//***************************************************************************** - -void aes_encrypt(UINT8 *state, UINT8 *key) -{ - // expand the key into 176 bytes - expandKey(expandedKey, key); - aes_encr(state, expandedKey); -} - -//***************************************************************************** -// -//! aes_decrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief AES128 decryption: -//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes -//! is computed The AES implementation is in mode ECB -//! (Electronic Code Book). -//! -//! -//***************************************************************************** - -void aes_decrypt(UINT8 *state, UINT8 *key) -{ - expandKey(expandedKey, key); // expand the key into 176 bytes - aes_decr(state, expandedKey); -} - -//***************************************************************************** -// -//! aes_read_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads AES128 key from EEPROM -//! Reads the AES128 key from fileID #12 in EEPROM -//! returns an error if the key does not exist. -//! -//! -//***************************************************************************** - -INT32 aes_read_key(UINT8 *key) -{ - INT32 returnValue; - - returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); - - return returnValue; -} - -//***************************************************************************** -// -//! aes_write_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief writes AES128 key from EEPROM -//! Writes the AES128 key to fileID #12 in EEPROM -//! -//! -//***************************************************************************** - -INT32 aes_write_key(UINT8 *key) -{ - INT32 returnValue; - - returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); - - return returnValue; -} - -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/socket.c b/drivers/cc3000/src/socket.c deleted file mode 100644 index ddd7e56e8075..000000000000 --- a/drivers/cc3000/src/socket.c +++ /dev/null @@ -1,1182 +0,0 @@ -/***************************************************************************** -* -* socket.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup socket_api -//! @{ -// -//***************************************************************************** - -#include -#include -#include "hci.h" -#include "socket.h" -#include "evnt_handler.h" -#include "netapp.h" - - - -//Enable this flag if and only if you must comply with BSD socket -//close() function -#ifdef _API_USE_BSD_CLOSE -#define close(sd) closesocket(sd) -#endif - -//Enable this flag if and only if you must comply with BSD socket read() and -//write() functions -#ifdef _API_USE_BSD_READ_WRITE -#define read(sd, buf, len, flags) recv(sd, buf, len, flags) -#define write(sd, buf, len, flags) send(sd, buf, len, flags) -#endif - -#define SOCKET_OPEN_PARAMS_LEN (12) -#define SOCKET_CLOSE_PARAMS_LEN (4) -#define SOCKET_ACCEPT_PARAMS_LEN (4) -#define SOCKET_BIND_PARAMS_LEN (20) -#define SOCKET_LISTEN_PARAMS_LEN (8) -#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) -#define SOCKET_CONNECT_PARAMS_LEN (20) -#define SOCKET_SELECT_PARAMS_LEN (44) -#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) -#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) -#define SOCKET_RECV_FROM_PARAMS_LEN (12) -#define SOCKET_SENDTO_PARAMS_LEN (24) -#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) -#define SOCKET_GET_MSS_VALUE_PARAMS_LEN (4) - -// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, -// while size of each parameter is 32 bit - so the total length is 16 bytes; - -#define HCI_CMND_SEND_ARG_LENGTH (16) - - -#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 - -#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) - -#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) - -#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) - - -//***************************************************************************** -// -//! HostFlowControlConsumeBuff -//! -//! @param sd socket descriptor -//! -//! @return 0 in case there are buffers available, -//! -1 in case of bad socket -//! -2 if there are no free buffers present (only when -//! SEND_NON_BLOCKING is enabled) -//! -//! @brief if SEND_NON_BLOCKING not define - block until have free buffer -//! becomes available, else return immediately with correct status -//! regarding the buffers available. -// -//***************************************************************************** -static INT16 HostFlowControlConsumeBuff(INT16 sd) -{ -#ifndef SEND_NON_BLOCKING - /* wait in busy loop */ - do - { - // In case last transmission failed then we will return the last failure - // reason here. - // Note that the buffer will not be allocated in this case - if (tSLInformation.slTransmitDataError != 0) - { - CC3000_EXPORT(errno) = tSLInformation.slTransmitDataError; - tSLInformation.slTransmitDataError = 0; - return CC3000_EXPORT(errno); - } - - if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) - return -1; - } while(0 == tSLInformation.usNumberOfFreeBuffers); - - tSLInformation.usNumberOfFreeBuffers--; - - return 0; -#else - - // In case last transmission failed then we will return the last failure - // reason here. - // Note that the buffer will not be allocated in this case - if (tSLInformation.slTransmitDataError != 0) - { - CC3000_EXPORT(errno) = tSLInformation.slTransmitDataError; - tSLInformation.slTransmitDataError = 0; - return CC3000_EXPORT(errno); - } - if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) - return -1; - - //If there are no available buffers, return -2. It is recommended to use - // select or receive to see if there is any buffer occupied with received data - // If so, call receive() to release the buffer. - if(0 == tSLInformation.usNumberOfFreeBuffers) - { - return -2; - } - else - { - tSLInformation.usNumberOfFreeBuffers--; - return 0; - } -#endif -} - -//***************************************************************************** -// -//! socket -//! -//! @param domain selects the protocol family which will be used for -//! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version -//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are -//! supported. -//! -//! @return On success, socket handle that is used for consequent socket -//! operations. On error, -1 is returned. -//! -//! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the -//! application layer to obtain a socket handle. -// -//***************************************************************************** - -INT16 CC3000_EXPORT(socket)(INT32 domain, INT32 type, INT32 protocol) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, domain); - args = UINT32_TO_STREAM(args, type); - args = UINT32_TO_STREAM(args, protocol); - - // Initiate a HCI command - hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); - - // Process the event - CC3000_EXPORT(errno) = ret; - - set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - - return(ret); -} - -//***************************************************************************** -// -//! closesocket -//! -//! @param sd socket handle. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief The socket function closes a created socket. -// -//***************************************************************************** - -INT32 CC3000_EXPORT(closesocket)(INT32 sd) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_CLOSE_SOCKET, - ptr, SOCKET_CLOSE_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); - CC3000_EXPORT(errno) = ret; - - // since 'close' call may result in either OK (and then it closed) or error - // mark this socket as invalid - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - - return(ret); -} - -//***************************************************************************** -// -//! accept -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. -//! On this version only AF_INET is supported. -//! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: -//! it should initially contain the size of the structure -//! pointed to by addr. -//! -//! @return For socket in blocking mode: -//! On success, socket handle. on failure negative -//! For socket in non-blocking mode: -//! - On connection establishment, socket handle -//! - On connection pending, SOC_IN_PROGRESS (-2) -//! - On failure, SOC_ERROR (-1) -//! -//! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the -//! queue of pending connections, creates a new connected socket, and -//! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. -//! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the -//! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the -//! socket's address family. The addrlen argument is a value-result -//! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual -//! length (in bytes) of the address returned. -//! -//! @sa socket ; bind ; listen -// -//***************************************************************************** - -INT32 CC3000_EXPORT(accept)(INT32 sd, sockaddr *addr, socklen_t *addrlen) -{ - INT32 ret; - UINT8 *ptr, *args; - tBsdReturnParams tAcceptReturnArguments; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_ACCEPT, - ptr, SOCKET_ACCEPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); - - - // need specify return parameters!!! - memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); - *addrlen = ASIC_ADDR_LEN; - CC3000_EXPORT(errno) = tAcceptReturnArguments.iStatus; - ret = CC3000_EXPORT(errno); - - // if succeeded, iStatus = new socket descriptor. otherwise - error number - if(M_IS_VALID_SD(ret)) - { - set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - } - else - { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } - - return(ret); -} - -//***************************************************************************** -// -//! bind -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief assign a name to a socket -//! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address -//! family) but has no name assigned. -//! It is necessary to assign a local address before a SOCK_STREAM -//! socket may receive connections. -//! -//! @sa socket ; accept ; listen -// -//***************************************************************************** - -INT32 CC3000_EXPORT(bind)(INT32 sd, const sockaddr *addr, INT32 addrlen) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - addrlen = ASIC_ADDR_LEN; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((UINT8 *)addr), addrlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_BIND, - ptr, SOCKET_BIND_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); - - CC3000_EXPORT(errno) = ret; - - return(ret); -} - -//***************************************************************************** -// -//! listen -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] backlog specifies the listen queue depth. On this version -//! backlog is not supported. -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief listen for connections on a socket -//! The willingness to accept incoming connections and a queue -//! limit for incoming connections are specified with listen(), -//! and then the connections are accepted with accept. -//! The listen() call applies only to sockets of type SOCK_STREAM -//! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. -//! -//! @sa socket ; accept ; bind -//! -//! @note On this version, backlog is not supported -// -//***************************************************************************** - -INT32 CC3000_EXPORT(listen)(INT32 sd, INT32 backlog) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, backlog); - - // Initiate a HCI command - hci_command_send(HCI_CMND_LISTEN, - ptr, SOCKET_LISTEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} - -//***************************************************************************** -// -//! gethostbyname -//! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. -//! @return On success, positive is returned. On error, negative is returned -//! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, -//! by its name. -//! -//! @note On this version, only blocking mode is supported. Also note that -//! the function requires DNS server to be configured prior to its usage. -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT16 CC3000_EXPORT(gethostbyname)(CHAR * hostname, UINT16 usNameLen, - UINT32* out_ip_addr) -{ - tBsdGethostbynameParams ret; - UINT8 *ptr, *args; - - CC3000_EXPORT(errno) = EFAIL; - - if (usNameLen > HOSTNAME_MAX_LENGTH) - { - return CC3000_EXPORT(errno); - } - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, 8); - args = UINT32_TO_STREAM(args, usNameLen); - ARRAY_TO_STREAM(args, hostname, usNameLen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN - + usNameLen - 1); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); - - CC3000_EXPORT(errno) = ret.retVal; - - (*((INT32*)out_ip_addr)) = ret.outputAddress; - - return CC3000_EXPORT(errno); - -} -#endif - -//***************************************************************************** -// -//! connect -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] addr specifies the destination addr. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is -//! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by -//! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection -//! establishment or for the connection establishment failure. -//! -//! @sa socket -// -//***************************************************************************** - -INT32 CC3000_EXPORT(connect)(INT32 sd, const sockaddr *addr, INT32 addrlen) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - addrlen = 8; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((UINT8 *)addr), addrlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_CONNECT, - ptr, SOCKET_CONNECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); - - CC3000_EXPORT(errno) = ret; - - return((INT32)ret); -} - - -//***************************************************************************** -// -//! select -//! -//! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. -//! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring -//! @param[out] exceptsds socket descriptors list for exception monitoring -//! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity -//! timeout. The minimum timeout is 5 milliseconds, -//! less than 5 milliseconds will be set -//! automatically to 5 milliseconds. -//! @return On success, select() returns the number of file descriptors -//! contained in the three returned descriptor sets (that is, the -//! total number of bits that are set in readfds, writefds, -//! exceptfds) which may be zero if the timeout expires before -//! anything interesting happens. -//! On error, -1 is returned. -//! *readsds - return the sockets on which Read request will -//! return without delay with valid data. -//! *writesds - return the sockets on which Write request -//! will return without delay. -//! *exceptsds - return the sockets which closed recently. -//! -//! @brief Monitor socket activity -//! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation -//! -//! @Note If the timeout value set to less than 5ms it will automatically set -//! to 5ms to prevent overload of the system -//! -//! @sa socket -// -//***************************************************************************** - -INT16 CC3000_EXPORT(select)(INT32 nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, -struct cc3000_timeval *timeout) -{ - UINT8 *ptr, *args; - tBsdSelectRecvParams tParams; - UINT32 is_blocking; - - if( timeout == NULL) - { - is_blocking = 1; /* blocking , infinity timeout */ - } - else - { - is_blocking = 0; /* no blocking, timeout */ - } - - // Fill in HCI packet structure - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, nfds); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, is_blocking); - args = UINT32_TO_STREAM(args, ((readsds) ? *(UINT32*)readsds : 0)); - args = UINT32_TO_STREAM(args, ((writesds) ? *(UINT32*)writesds : 0)); - args = UINT32_TO_STREAM(args, ((exceptsds) ? *(UINT32*)exceptsds : 0)); - - if (timeout) - { - if ( 0 == timeout->tv_sec && timeout->tv_usec < - SELECT_TIMEOUT_MIN_MICRO_SECONDS) - { - timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; - } - args = UINT32_TO_STREAM(args, timeout->tv_sec); - args = UINT32_TO_STREAM(args, timeout->tv_usec); - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); - - // Update actually read FD - if (tParams.iStatus >= 0) - { - if (readsds) - { - memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); - } - - if (writesds) - { - memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); - } - - if (exceptsds) - { - memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); - } - - return(tParams.iStatus); - - } - else - { - CC3000_EXPORT(errno) = tParams.iStatus; - return(-1); - } -} - -//***************************************************************************** -// -//! setsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[in] optval specifies a value for the option -//! @param[in] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa getsockopt -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT16 CC3000_EXPORT(setsockopt)(INT32 sd, INT32 level, INT32 optname, const void *optval, - socklen_t optlen) -{ - INT32 ret; - UINT8 *ptr, *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, optlen); - ARRAY_TO_STREAM(args, ((UINT8 *)optval), optlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_SETSOCKOPT, - ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); - - if (ret >= 0) - { - return (0); - } - else - { - CC3000_EXPORT(errno) = ret; - return ret; - } -} -#endif - -//***************************************************************************** -// -//! getsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[out] optval specifies a value for the option -//! @param[out] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa setsockopt -// -//***************************************************************************** - -INT16 CC3000_EXPORT(getsockopt) (INT32 sd, INT32 level, INT32 optname, void *optval, socklen_t *optlen) -{ - UINT8 *ptr, *args; - tBsdGetSockOptReturnParams tRetParams; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETSOCKOPT, - ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); - - if (((INT8)tRetParams.iStatus) >= 0) - { - *optlen = 4; - memcpy(optval, tRetParams.ucOptValue, 4); - return (0); - } - else - { - CC3000_EXPORT(errno) = tRetParams.iStatus; - return CC3000_EXPORT(errno); - } -} - -//***************************************************************************** -// -//! simple_link_recv -//! -//! @param sd socket handle -//! @param buf read buffer -//! @param len buffer length -//! @param flags indicates blocking or non-blocking operation -//! @param from pointer to an address structure indicating source address -//! @param fromlen source address structure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief Read data from socket -//! Return the length of the message on successful completion. -//! If a message is too long to fit in the supplied buffer, -//! excess bytes may be discarded depending on the type of -//! socket the message is received from -// -//***************************************************************************** -static INT16 simple_link_recv(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from, - socklen_t *fromlen, INT32 opcode) -{ - UINT8 *ptr, *args; - tBsdReadReturnParams tSocketReadEvent; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - // Generate the read command, and wait for the - hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(opcode, &tSocketReadEvent); - - // In case the number of bytes is more then zero - read data - if (tSocketReadEvent.iNumberOfBytes > 0) - { - // Wait for the data in a synchronous way. Here we assume that the bug is - // big enough to store also parameters of receive from too.... - SimpleLinkWaitData(buf, (UINT8 *)from, (UINT8 *)fromlen); - } - - CC3000_EXPORT(errno) = tSocketReadEvent.iNumberOfBytes; - - return(tSocketReadEvent.iNumberOfBytes); -} - -//***************************************************************************** -// -//! recv -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief function receives a message from a connection-mode socket -//! -//! @sa recvfrom -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** - -INT16 CC3000_EXPORT(recv)(INT32 sd, void *buf, INT32 len, INT32 flags) -{ - return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); -} - -//***************************************************************************** -// -//! recvfrom -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! @param[in] from pointer to an address structure indicating the source -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param[in] fromlen source address tructure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief read data from socket -//! function receives a message from a connection-mode or -//! connectionless-mode socket. Note that raw sockets are not -//! supported. -//! -//! @sa recv -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -INT16 CC3000_EXPORT(recvfrom)(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from, - socklen_t *fromlen) -{ - return(simple_link_recv(sd, buf, len, flags, from, fromlen, - HCI_CMND_RECVFROM)); -} - -//***************************************************************************** -// -//! simple_link_send -//! -//! @param sd socket handle -//! @param buf write buffer -//! @param len buffer length -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating destination -//! address -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an error -//! occurred, or -2 in case there are no free buffers available -//! (only when SEND_NON_BLOCKING is enabled) -//! -//! @brief This function is used to transmit a message to another -//! socket -// -//***************************************************************************** -static INT16 simple_link_send(INT32 sd, const void *buf, INT32 len, INT32 flags, - const sockaddr *to, INT32 tolen, INT32 opcode) -{ - UINT8 uArgSize=0, addrlen; - UINT8 *ptr, *pDataPtr=0, *args; - UINT32 addr_offset=0; - INT16 res; - tBsdReadReturnParams tSocketSendEvent; - - // Check the bsd_arguments - if (0 != (res = HostFlowControlConsumeBuff(sd))) - { - return res; - } - - //Update the number of sent packets - tSLInformation.NumberOfSentPackets++; - - // Allocate a buffer and construct a packet and send it over spi - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_DATA); - - // Update the offset of data and parameters according to the command - switch(opcode) - { - case HCI_CMND_SENDTO: - { - addr_offset = len + sizeof(len) + sizeof(len); - addrlen = 8; - uArgSize = SOCKET_SENDTO_PARAMS_LEN; - pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; - break; - } - - case HCI_CMND_SEND: - { - tolen = 0; - to = NULL; - uArgSize = HCI_CMND_SEND_ARG_LENGTH; - pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; - break; - } - - default: - { - break; - } - } - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - if (opcode == HCI_CMND_SENDTO) - { - args = UINT32_TO_STREAM(args, addr_offset); - args = UINT32_TO_STREAM(args, addrlen); - } - - // Copy the data received from user into the TX Buffer - ARRAY_TO_STREAM(pDataPtr, ((UINT8 *)buf), len); - - // In case we are using SendTo, copy the to parameters - if (opcode == HCI_CMND_SENDTO) - { - ARRAY_TO_STREAM(pDataPtr, ((UINT8 *)to), tolen); - } - - // Initiate a HCI command - hci_data_send(opcode, ptr, uArgSize, len,(UINT8*)to, tolen); - - if (opcode == HCI_CMND_SENDTO) - SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); - else - SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); - - return (len); -} - - -//***************************************************************************** -// -//! send -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa sendto -// -//***************************************************************************** - -INT16 CC3000_EXPORT(send)(INT32 sd, const void *buf, INT32 len, INT32 flags) -{ - return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); -} - -//***************************************************************************** -// -//! sendto -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating the destination -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa send -// -//***************************************************************************** - -INT16 CC3000_EXPORT(sendto)(INT32 sd, const void *buf, INT32 len, INT32 flags, const sockaddr *to, - socklen_t tolen) -{ - return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); -} - -//***************************************************************************** -// -//! mdnsAdvertiser -//! -//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature -//! @param[in] deviceServiceName Service name as part of the published -//! canonical domain name -//! @param[in] deviceServiceNameLength Length of the service name - up to 32 chars -//! -//! -//! @return On success, zero is returned, return SOC_ERROR if socket was not -//! opened successfully, or if an error occurred. -//! -//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. -// -//***************************************************************************** - -INT16 CC3000_EXPORT(mdnsAdvertiser)(UINT16 mdnsEnabled, CHAR * deviceServiceName, UINT16 deviceServiceNameLength) -{ - INT8 ret; - UINT8 *pTxBuffer, *pArgs; - - if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) - { - return EFAIL; - } - - pTxBuffer = tSLInformation.pucTxCommandBuffer; - pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); - pArgs = UINT32_TO_STREAM(pArgs, 8); - pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); - ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); - - // Initiate a HCI command - hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret); - - return ret; - -} - - -//***************************************************************************** -// -//! getmssvalue -//! -//! @param[in] sd socket descriptor -//! -//! @return On success, returns the MSS value of a TCP connection -//! -//! @brief Returns the MSS value of a TCP connection according to the socket descriptor -// -//***************************************************************************** -UINT16 CC3000_EXPORT(getmssvalue) (INT32 sd) -{ - UINT8 *ptr, *args; - UINT16 ret; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETMSSVALUE, ptr, SOCKET_GET_MSS_VALUE_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_GETMSSVALUE, &ret); - - return ret; -} diff --git a/drivers/cc3000/src/wlan.c b/drivers/cc3000/src/wlan.c deleted file mode 100644 index 6385937778cc..000000000000 --- a/drivers/cc3000/src/wlan.c +++ /dev/null @@ -1,1252 +0,0 @@ -/***************************************************************************** -* -* wlan.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup wlan_api -//! @{ -// -//***************************************************************************** - -#include -#include "wlan.h" -#include "hci.h" -#include "ccspi.h" -#include "socket.h" -#include "nvmem.h" -#include "security.h" -#include "evnt_handler.h" - - -volatile sSimplLinkInformation tSLInformation; - -#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length) - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -UINT8 key[AES128_KEY_SIZE]; -UINT8 profileArray[SMART_CONFIG_PROFILE_SIZE]; -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -/* patches type */ -#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01 -#define PATCHES_HOST_TYPE_WLAN_FW 0x02 -#define PATCHES_HOST_TYPE_BOOTLOADER 0x03 - -#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16) -#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3) -#define ETH_ALEN (6) -#define MAXIMAL_SSID_LENGTH (32) - -#define SL_PATCHES_REQUEST_DEFAULT (0) -#define SL_PATCHES_REQUEST_FORCE_HOST (1) -#define SL_PATCHES_REQUEST_FORCE_NONE (2) - - -#define WLAN_SEC_UNSEC (0) -#define WLAN_SEC_WEP (1) -#define WLAN_SEC_WPA (2) -#define WLAN_SEC_WPA2 (3) - - -#define WLAN_SL_INIT_START_PARAMS_LEN (1) -#define WLAN_PATCH_PARAMS_LENGTH (8) -#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12) -#define WLAN_DEL_PROFILE_PARAMS_LEN (4) -#define WLAN_SET_MASK_PARAMS_LEN (4) -#define WLAN_SET_SCAN_PARAMS_LEN (100) -#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4) -#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24) -#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36) -#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44) -#define WLAN_CONNECT_PARAM_LEN (29) -#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4) - - - - -//***************************************************************************** -// -//! SimpleLink_Init_Start -//! -//! @param usPatchesAvailableAtHost flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Send HCI_CMND_SIMPLE_LINK_START to CC3000 -// -//***************************************************************************** -static void SimpleLink_Init_Start(UINT16 usPatchesAvailableAtHost) -{ - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_NONE : SL_PATCHES_REQUEST_DEFAULT)); - - // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000 - hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN); - - SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); -} - - - -//***************************************************************************** -// -//! wlan_init -//! -//! @param sWlanCB Asynchronous events callback. -//! 0 no event call back. -//! -call back parameters: -//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR -//! HCI_EVNT_WLAN_KEEPALIVE keepalive. -//! 2) data: pointer to extra data that received by the event -//! (NULL no data). -//! 3) length: data length. -//! -Events with extra data: -//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, -//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes -//! for DNS server. -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, -//! 4 bytes Packets received, 4 bytes Min round time, -//! 4 bytes Max round time and 4 bytes for Avg round time. -//! -//! @param sFWPatches 0 no patch or pointer to FW patches -//! @param sDriverPatches 0 no patch or pointer to driver patches -//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches -//! @param sReadWlanInterruptPin init callback. the callback read wlan -//! interrupt status. -//! @param sWlanInterruptEnable init callback. the callback enable wlan -//! interrupt. -//! @param sWlanInterruptDisable init callback. the callback disable wlan -//! interrupt. -//! @param sWriteWlanPin init callback. the callback write value -//! to device pin. -//! -//! @return none -//! -//! @sa wlan_set_event_mask , wlan_start , wlan_stop -//! -//! @brief Initialize wlan driver -//! -//! @warning This function must be called before ANY other wlan driver function -// -//***************************************************************************** - -void wlan_init( tWlanCB sWlanCB, - tFWPatches sFWPatches, - tDriverPatches sDriverPatches, - tBootLoaderPatches sBootLoaderPatches, - tWlanReadInteruptPin sReadWlanInterruptPin, - tWlanInterruptEnable sWlanInterruptEnable, - tWlanInterruptDisable sWlanInterruptDisable, - tWriteWlanPin sWriteWlanPin) -{ - - tSLInformation.sFWPatches = sFWPatches; - tSLInformation.sDriverPatches = sDriverPatches; - tSLInformation.sBootLoaderPatches = sBootLoaderPatches; - - // init io callback - tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin; - tSLInformation.WlanInterruptEnable = sWlanInterruptEnable; - tSLInformation.WlanInterruptDisable = sWlanInterruptDisable; - tSLInformation.WriteWlanPin = sWriteWlanPin; - - //init asynchronous events callback - tSLInformation.sWlanCB= sWlanCB; - - // By default TX Complete events are routed to host too - tSLInformation.InformHostOnTxComplete = 1; -} - -//***************************************************************************** -// -//! SpiReceiveHandler -//! -//! @param pvBuffer - pointer to the received data buffer -//! The function triggers Received event/data processing -//! -//! @param Pointer to the received data -//! @return none -//! -//! @brief The function triggers Received event/data processing. It is -//! called from the SPI library to receive the data -// -//***************************************************************************** -void SpiReceiveHandler(void *pvBuffer) -{ - tSLInformation.usEventOrDataReceived = 1; - tSLInformation.pucReceivedData = (UINT8 *)pvBuffer; - - hci_unsolicited_event_handler(); -} - - -//***************************************************************************** -// -//! wlan_start -//! -//! @param usPatchesAvailableAtHost - flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Start WLAN device. This function asserts the enable pin of -//! the device (WLAN_EN), starting the HW initialization process. -//! The function blocked until device Initialization is completed. -//! Function also configure patches (FW, driver or bootloader) -//! and calls appropriate device callbacks. -//! -//! @Note Prior calling the function wlan_init shall be called. -//! @Warning This function must be called after wlan_init and before any -//! other wlan API -//! @sa wlan_init , wlan_stop -//! -// -//***************************************************************************** -#define TIMEOUT (500000) - -int wlan_start(UINT16 usPatchesAvailableAtHost) -{ - - UINT32 ulSpiIRQState; - UINT32 wlan_timeout; - - tSLInformation.NumberOfSentPackets = 0; - tSLInformation.NumberOfReleasedPackets = 0; - tSLInformation.usRxEventOpcode = 0; - tSLInformation.usNumberOfFreeBuffers = 0; - tSLInformation.usSlBufferLength = 0; - tSLInformation.usBufferSize = 0; - tSLInformation.usRxDataPending = 0; - tSLInformation.slTransmitDataError = 0; - tSLInformation.usEventOrDataReceived = 0; - tSLInformation.pucReceivedData = 0; - - // Allocate the memory for the RX/TX data transactions - tSLInformation.pucTxCommandBuffer = (UINT8 *)wlan_tx_buffer; - - // init spi - SpiOpen(SpiReceiveHandler); - - // Check the IRQ line - ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); - - // Chip enable: toggle WLAN EN line - tSLInformation.WriteWlanPin( WLAN_ENABLE ); - - wlan_timeout = TIMEOUT; - if (ulSpiIRQState) { - // wait till the IRQ line goes low - while(tSLInformation.ReadWlanInterruptPin() != 0 && --wlan_timeout) - { - } - } - else - { - // wait till the IRQ line goes high and than low - while(tSLInformation.ReadWlanInterruptPin() == 0 && --wlan_timeout) - { - } - - if (wlan_timeout == 0) { - return -1; - } - - wlan_timeout = TIMEOUT; - while(tSLInformation.ReadWlanInterruptPin() != 0 && --wlan_timeout) - { - } - } - - if (wlan_timeout ==0) { - return -1; - } - - SimpleLink_Init_Start(usPatchesAvailableAtHost); - - // Read Buffer's size and finish - hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); - SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); - - return 0; -} - - -//***************************************************************************** -// -//! wlan_stop -//! -//! @param none -//! -//! @return none -//! -//! @brief Stop WLAN device by putting it into reset state. -//! -//! @sa wlan_start -// -//***************************************************************************** - -void wlan_stop(void) -{ - // Chip disable - tSLInformation.WriteWlanPin( WLAN_DISABLE ); - - // Wait till IRQ line goes high... - while(tSLInformation.ReadWlanInterruptPin() == 0) - { - } - - // Free the used by WLAN Driver memory - if (tSLInformation.pucTxCommandBuffer) - { - tSLInformation.pucTxCommandBuffer = 0; - } - - SpiClose(); -} - - -//***************************************************************************** -// -//! wlan_connect -//! -//! @param sec_type security options: -//! WLAN_SEC_UNSEC, -//! WLAN_SEC_WEP (ASCII support only), -//! WLAN_SEC_WPA or WLAN_SEC_WPA2 -//! @param ssid up to 32 bytes and is ASCII SSID of the AP -//! @param ssid_len length of the SSID -//! @param bssid 6 bytes specified the AP bssid -//! @param key up to 32 bytes specified the AP security key -//! @param key_len key length -//! -//! @return On success, zero is returned. On error, negative is returned. -//! Note that even though a zero is returned on success to trigger -//! connection operation, it does not mean that CCC3000 is already -//! connected. An asynchronous "Connected" event is generated when -//! actual association process finishes and CC3000 is connected to -//! the AP. If DHCP is set, An asynchronous "DHCP" event is -//! generated when DHCP process is finish. -//! -//! -//! @brief Connect to AP -//! @warning Please Note that when connection to AP configured with security -//! type WEP, please confirm that the key is set as ASCII and not -//! as HEX. -//! @sa wlan_disconnect -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_connect(UINT32 ulSecType, CHAR *ssid, INT32 ssid_len, - UINT8 *bssid, UINT8 *key, INT32 key_len) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - UINT8 bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in command buffer - args = UINT32_TO_STREAM(args, 0x0000001c); - args = UINT32_TO_STREAM(args, ssid_len); - args = UINT32_TO_STREAM(args, ulSecType); - args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); - args = UINT32_TO_STREAM(args, key_len); - args = UINT16_TO_STREAM(args, 0); - - // padding shall be zeroed - if(bssid) - { - ARRAY_TO_STREAM(args, bssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - - ARRAY_TO_STREAM(args, ssid, ssid_len); - - if(key_len && key) - { - ARRAY_TO_STREAM(args, key, key_len); - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + - ssid_len + key_len - 1); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} -#else -INT32 wlan_connect(CHAR *ssid, INT32 ssid_len) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - UINT8 bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in command buffer - args = UINT32_TO_STREAM(args, 0x0000001c); - args = UINT32_TO_STREAM(args, ssid_len); - args = UINT32_TO_STREAM(args, 0); - args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); - args = UINT32_TO_STREAM(args, 0); - args = UINT16_TO_STREAM(args, 0); - - // padding shall be zeroed - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - ARRAY_TO_STREAM(args, ssid, ssid_len); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + - ssid_len - 1); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} -#endif - -//***************************************************************************** -// -//! wlan_disconnect -//! -//! @return 0 disconnected done, other CC3000 already disconnected -//! -//! @brief Disconnect connection from AP. -//! -//! @sa wlan_connect -// -//***************************************************************************** - -INT32 wlan_disconnect() -{ - INT32 ret; - UINT8 *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} - -//***************************************************************************** -// -//! wlan_ioctl_set_connection_policy -//! -//! @param should_connect_to_open_ap enable(1), disable(0) connect to any -//! available AP. This parameter corresponds to the configuration of -//! item # 3 in the brief description. -//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries -//! to connect to the last connected AP. This parameter corresponds -//! to the configuration of item # 1 in the brief description. -//! @param auto_start enable(1), disable(0) auto connect -//! after reset and periodically reconnect if needed. This -//! configuration configures option 2 in the above description. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief When auto is enabled, the device tries to connect according -//! the following policy: -//! 1) If fast connect is enabled and last connection is valid, -//! the device will try to connect to it without the scanning -//! procedure (fast). The last connection will be marked as -//! invalid, due to adding/removing profile. -//! 2) If profile exists, the device will try to connect it -//! (Up to seven profiles). -//! 3) If fast and profiles are not found, and open mode is -//! enabled, the device will try to connect to any AP. -//! * Note that the policy settings are stored in the CC3000 NVMEM. -//! -//! @sa wlan_add_profile , wlan_ioctl_del_profile -// -//***************************************************************************** - -INT32 wlan_ioctl_set_connection_policy(UINT32 should_connect_to_open_ap, - UINT32 ulShouldUseFastConnect, - UINT32 ulUseProfiles) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, should_connect_to_open_ap); - args = UINT32_TO_STREAM(args, ulShouldUseFastConnect); - args = UINT32_TO_STREAM(args, ulUseProfiles); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, - ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_add_profile -//! -//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 -//! @param ucSsid ssid SSID up to 32 bytes -//! @param ulSsidLen ssid length -//! @param ucBssid bssid 6 bytes -//! @param ulPriority ulPriority profile priority. Lowest priority:0. -//! Important Note: Smartconfig process (in unencrypted mode) -//! stores the profile internally with priority 1, so changing -//! priorities when adding new profiles should be done with extra care -//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security -//! @param ulGroupCipher_TxKeyIndex key index -//! @param ulKeyMgmt KEY management -//! @param ucPf_OrKey security key -//! @param ulPassPhraseLen security key length for WPA\WPA2 -//! -//! @return On success, index (1-7) of the stored profile is returned. -//! On error, -1 is returned. -//! -//! @brief When auto start is enabled, the device connects to -//! station from the profiles table. Up to 7 profiles are supported. -//! If several profiles configured the device choose the highest -//! priority profile, within each priority group, device will choose -//! profile based on security policy, signal strength, etc -//! parameters. All the profiles are stored in CC3000 NVMEM. -//! -//! @sa wlan_ioctl_del_profile -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_add_profile(UINT32 ulSecType, - UINT8* ucSsid, - UINT32 ulSsidLen, - UINT8 *ucBssid, - UINT32 ulPriority, - UINT32 ulPairwiseCipher_Or_TxKeyLen, - UINT32 ulGroupCipher_TxKeyIndex, - UINT32 ulKeyMgmt, - UINT8* ucPf_OrKey, - UINT32 ulPassPhraseLen) -{ - UINT16 arg_len=0; - INT32 ret; - UINT8 *ptr; - INT32 i = 0; - UINT8 *args; - UINT8 bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - args = UINT32_TO_STREAM(args, ulSecType); - - // Setup arguments in accordance with the security type - switch (ulSecType) - { - //OPEN - case WLAN_SEC_UNSEC: - { - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - - arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; - } - break; - - //WEP - case WLAN_SEC_WEP: - { - args = UINT32_TO_STREAM(args, 0x00000020); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); - args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); - args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - - for(i = 0; i < 4; i++) - { - UINT8 *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; - - ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); - } - - arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + - ulPairwiseCipher_Or_TxKeyLen * 4; - - } - break; - - //WPA - //WPA2 - case WLAN_SEC_WPA: - case WLAN_SEC_WPA2: - { - args = UINT32_TO_STREAM(args, 0x00000028); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); - args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); - args = UINT32_TO_STREAM(args, ulKeyMgmt); - args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); - args = UINT32_TO_STREAM(args, ulPassPhraseLen); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); - - arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; - } - - break; - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, - ptr, arg_len); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); - - return(ret); -} -#else -INT32 wlan_add_profile(UINT32 ulSecType, - UINT8* ucSsid, - UINT32 ulSsidLen, - UINT8 *ucBssid, - UINT32 ulPriority, - UINT32 ulPairwiseCipher_Or_TxKeyLen, - UINT32 ulGroupCipher_TxKeyIndex, - UINT32 ulKeyMgmt, - UINT8* ucPf_OrKey, - UINT32 ulPassPhraseLen) -{ - return -1; -} -#endif - -//***************************************************************************** -// -//! wlan_ioctl_del_profile -//! -//! @param index number of profile to delete -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Delete WLAN profile -//! -//! @Note In order to delete all stored profile, set index to 255. -//! -//! @sa wlan_add_profile -// -//***************************************************************************** - -INT32 wlan_ioctl_del_profile(UINT32 ulIndex) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulIndex); - ret = EFAIL; - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, - ptr, WLAN_DEL_PROFILE_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_ioctl_get_scan_results -//! -//! @param[in] scan_timeout parameter not supported -//! @param[out] ucResults scan results (_wlan_full_scan_results_args_t) -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Gets entry from scan result table. -//! The scan results are returned one by one, and each entry -//! represents a single AP found in the area. The following is a -//! format of the scan result: -//! - 4 Bytes: number of networks found -//! - 4 Bytes: The status of the scan: 0 - aged results, -//! 1 - results valid, 2 - no results -//! - 42 bytes: Result entry, where the bytes are arranged as follows: -//! -//! - 1 bit isValid - is result valid or not -//! - 7 bits rssi - RSSI value; -//! - 2 bits: securityMode - security mode of the AP: -//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 -//! - 6 bits: SSID name length -//! - 2 bytes: the time at which the entry has entered into -//! scans result table -//! - 32 bytes: SSID name -//! - 6 bytes: BSSID -//! -//! @Note scan_timeout, is not supported on this version. -//! -//! @sa wlan_ioctl_set_scan_params -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_ioctl_get_scan_results(UINT32 ulScanTimeout, - UINT8 *ucResults) -{ - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, ulScanTimeout); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, - ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults); - - return(0); -} -#endif - -//***************************************************************************** -// -//! wlan_ioctl_set_scan_params -//! -//! @param uiEnable - start/stop application scan: -//! 1 = start scan with default interval value of 10 min. -//! in order to set a different scan interval value apply the value -//! in milliseconds. minimum 1 second. 0=stop). Wlan reset -//! (wlan_stop() wlan_start()) is needed when changing scan interval -//! value. Saved: No -//! @param uiMinDwellTime minimum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 20) -//! @param uiMaxDwellTime maximum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 30) -//! @param uiNumOfProbeRequests max probe request between dwell time. -//! Saved: yes. Recommended Value: 5 (Default:2) -//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). -//! Saved: yes. Default: 0x7ff -//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) -//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) -//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) -//! @param aiIntervalList pointer to array with 16 entries (16 channels) -//! each entry (UINT32) holds timeout between periodic scan -//! (connection scan) - in millisecond. Saved: yes. Default 2000ms. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief start and stop scan procedure. Set scan parameters. -//! -//! @Note uiDefaultTxPower, is not supported on this version. -//! -//! @sa wlan_ioctl_get_scan_results -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_ioctl_set_scan_params(UINT32 uiEnable, UINT32 uiMinDwellTime, - UINT32 uiMaxDwellTime, - UINT32 uiNumOfProbeRequests, - UINT32 uiChannelMask,INT32 iRSSIThreshold, - UINT32 uiSNRThreshold, - UINT32 uiDefaultTxPower, - UINT32 *aiIntervalList) -{ - UINT32 uiRes; - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, 36); - args = UINT32_TO_STREAM(args, uiEnable); - args = UINT32_TO_STREAM(args, uiMinDwellTime); - args = UINT32_TO_STREAM(args, uiMaxDwellTime); - args = UINT32_TO_STREAM(args, uiNumOfProbeRequests); - args = UINT32_TO_STREAM(args, uiChannelMask); - args = UINT32_TO_STREAM(args, iRSSIThreshold); - args = UINT32_TO_STREAM(args, uiSNRThreshold); - args = UINT32_TO_STREAM(args, uiDefaultTxPower); - ARRAY_TO_STREAM(args, aiIntervalList, sizeof(UINT32) * - SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, - ptr, WLAN_SET_SCAN_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes); - - return(uiRes); -} -#endif - -//***************************************************************************** -// -//! wlan_set_event_mask -//! -//! @param mask mask option: -//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done -//! HCI_EVNT_WLAN_UNSOL_INIT init done -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report -//! HCI_EVNT_WLAN_KEEPALIVE keepalive -//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission -//! Saved: no. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Mask event according to bit mask. In case that event is -//! masked (1), the device will not send the masked event to host. -// -//***************************************************************************** - -INT32 wlan_set_event_mask(UINT32 ulMask) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - - if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) - { - tSLInformation.InformHostOnTxComplete = 0; - - // Since an event is a virtual event - i.e. it is not coming from CC3000 - // there is no need to send anything to the device if it was an only event - if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE) - { - return 0; - } - - ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE; - ulMask |= HCI_EVNT_WLAN_UNSOL_BASE; - } - else - { - tSLInformation.InformHostOnTxComplete = 1; - } - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulMask); - - // Initiate a HCI command - hci_command_send(HCI_CMND_EVENT_MASK, - ptr, WLAN_SET_MASK_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_ioctl_statusget -//! -//! @param none -//! -//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, -//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED -//! -//! @brief get wlan status: disconnected, scanning, connecting or connected -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_ioctl_statusget(void) -{ - INT32 ret; - UINT8 *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET, - ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret); - - return(ret); -} -#endif - -//***************************************************************************** -// -//! wlan_smart_config_start -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Start to acquire device profile. The device acquire its own -//! profile, if profile message is found. The acquired AP information -//! is stored in CC3000 EEPROM only in case AES128 encryption is used. -//! In case AES128 encryption is not used, a profile is created by -//! CC3000 internally. -//! -//! @Note An asynchronous event - Smart Config Done will be generated as soon -//! as the process finishes successfully. -//! -//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop -// -//***************************************************************************** - -INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, algoEncryptedFlag); - ret = EFAIL; - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, - WLAN_SMART_CONFIG_START_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_smart_config_stop -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Stop the acquire profile procedure -//! -//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix -// -//***************************************************************************** - -INT32 wlan_smart_config_stop(void) -{ - INT32 ret; - UINT8 *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_smart_config_set_prefix -//! -//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Configure station ssid prefix. The prefix is used internally -//! in CC3000. It should always be TTT. -//! -//! @Note The prefix is stored in CC3000 NVMEM -//! -//! @sa wlan_smart_config_start , wlan_smart_config_stop -// -//***************************************************************************** - -INT32 wlan_smart_config_set_prefix(CHAR* cNewPrefix) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - if (cNewPrefix == NULL) - return ret; - else // with the new Smart Config, prefix must be TTT - { - *cNewPrefix = 'T'; - *(cNewPrefix + 1) = 'T'; - *(cNewPrefix + 2) = 'T'; - } - - ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH); - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, - SL_SIMPLE_CONFIG_PREFIX_LENGTH); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_smart_config_process -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief process the acquired data and store it as a profile. The acquired -//! AP information is stored in CC3000 EEPROM encrypted. -//! The encrypted data is decrypted and stored as a profile. -//! behavior is as defined by connection policy. -// -//***************************************************************************** - - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -INT32 wlan_smart_config_process() -{ - INT32 returnValue; - UINT32 ssidLen, keyLen; - UINT8 *decKeyPtr; - UINT8 *ssidPtr; - - // read the key from EEPROM - fileID 12 - returnValue = aes_read_key(key); - - if (returnValue != 0) - return returnValue; - - // read the received data from fileID #13 and parse it according to the followings: - // 1) SSID LEN - not encrypted - // 2) SSID - not encrypted - // 3) KEY LEN - not encrypted. always 32 bytes long - // 4) Security type - not encrypted - // 5) KEY - encrypted together with true key length as the first byte in KEY - // to elaborate, there are two corner cases: - // 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length - // 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31 - returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray); - - if (returnValue != 0) - return returnValue; - - ssidPtr = &profileArray[1]; - - ssidLen = profileArray[0]; - - decKeyPtr = &profileArray[profileArray[0] + 3]; - - aes_decrypt(decKeyPtr, key); - if (profileArray[profileArray[0] + 1] > 16) - aes_decrypt((UINT8 *)(decKeyPtr + 16), key); - - if (*(UINT8 *)(decKeyPtr +31) != 0) - { - if (*decKeyPtr == 31) - { - keyLen = 31; - decKeyPtr++; - } - else - { - keyLen = 32; - } - } - else - { - keyLen = *decKeyPtr; - decKeyPtr++; - } - - // add a profile - switch (profileArray[profileArray[0] + 2]) - { - case WLAN_SEC_UNSEC://None - { - returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type - ssidPtr, // SSID - ssidLen, // SSID length - NULL, // BSSID - 1, // Priority - 0, 0, 0, 0, 0); - - break; - } - - case WLAN_SEC_WEP://WEP - { - returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type - ssidPtr, // SSID - ssidLen, // SSID length - NULL, // BSSID - 1, // Priority - keyLen, // KEY length - 0, // KEY index - 0, - decKeyPtr, // KEY - 0); - - break; - } - - case WLAN_SEC_WPA://WPA - case WLAN_SEC_WPA2://WPA2 - { - returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type - ssidPtr, - ssidLen, - NULL, // BSSID - 1, // Priority - 0x18, // PairwiseCipher - 0x1e, // GroupCipher - 2, // KEY management - decKeyPtr, // KEY - keyLen); // KEY length - - break; - } - } - - return returnValue; -} -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** From 858707181d907b96fe55e786defa8947e404ab91 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 23 Aug 2022 17:05:30 +1000 Subject: [PATCH 1649/4290] tools/mpremote: Print a nicer error when a filesystem command fails. Signed-off-by: Damien George --- tools/mpremote/mpremote/main.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index e614156dbf78..fa4785b3bf8f 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -354,9 +354,13 @@ def _list_recursive(files, path): verbose=verbose, ) else: - pyboard.filesystem_command( - pyb, fs_args, progress_callback=show_progress_bar, verbose=verbose - ) + try: + pyboard.filesystem_command( + pyb, fs_args, progress_callback=show_progress_bar, verbose=verbose + ) + except OSError as er: + print(f"{_PROG}: {er}") + sys.exit(1) def do_edit(pyb, args): From 24f1161fe21df146b64a657acadf67e723040636 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 23 Aug 2022 17:25:54 +1000 Subject: [PATCH 1650/4290] tools/pyboard.py: Remove implicit fs_put if source starts with ./. Signed-off-by: Damien George --- tools/pyboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 752504987587..8c4696c4392c 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -583,7 +583,7 @@ def fname_cp_dest(src, dest): if cmd == "cp": srcs = args[:-1] dest = args[-1] - if srcs[0].startswith("./") or dest.startswith(":"): + if dest.startswith(":"): op = pyb.fs_put fmt = "cp %s :%s" dest = fname_remote(dest) From f5fedf4676274dd26d70142b08753873dc1b99bc Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 24 Aug 2022 10:26:35 +1000 Subject: [PATCH 1651/4290] tools/pyboard.py: Add fs_cp function for direct device-to-device copy. Signed-off-by: Damien George --- tools/pyboard.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 8c4696c4392c..436bc5ab1be5 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -491,6 +491,20 @@ def fs_cat(self, src, chunk_size=256): ) self.exec_(cmd, data_consumer=stdout_write_bytes) + def fs_cp(self, src, dest, chunk_size=256, progress_callback=None): + if progress_callback: + src_size = int(self.exec_("import os\nprint(os.stat('%s')[6])" % src)) + written = 0 + self.exec_("fr=open('%s','rb')\nr=fr.read\nfw=open('%s','wb')\nw=fw.write" % (src, dest)) + while True: + data_len = int(self.exec_("d=r(%u)\nw(d)\nprint(len(d))" % chunk_size)) + if not data_len: + break + if progress_callback: + written += data_len + progress_callback(written, src_size) + self.exec_("fr.close()\nfw.close()") + def fs_get(self, src, dest, chunk_size=256, progress_callback=None): if progress_callback: src_size = int(self.exec_("import os\nprint(os.stat('%s')[6])" % src)) @@ -584,18 +598,21 @@ def fname_cp_dest(src, dest): srcs = args[:-1] dest = args[-1] if dest.startswith(":"): - op = pyb.fs_put - fmt = "cp %s :%s" - dest = fname_remote(dest) + op_remote_src = pyb.fs_cp + op_local_src = pyb.fs_put else: - op = pyb.fs_get - fmt = "cp :%s %s" + op_remote_src = pyb.fs_get + op_local_src = lambda src, dest, **_: __import__("shutil").copy(src, dest) for src in srcs: - src = fname_remote(src) - dest2 = fname_cp_dest(src, dest) if verbose: - print(fmt % (src, dest2)) - op(src, dest2, progress_callback=progress_callback) + print("cp %s %s" % (src, dest)) + if src.startswith(":"): + op = op_remote_src + else: + op = op_local_src + src2 = fname_remote(src) + dest2 = fname_cp_dest(src2, fname_remote(dest)) + op(src2, dest2, progress_callback=progress_callback) else: op = { "cat": pyb.fs_cat, From 2e386bcf76c38a81a9de93452f9a253c571d2b72 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 24 Aug 2022 10:33:11 +1000 Subject: [PATCH 1652/4290] tools/mpremote: Print nicer errors for unsupported 'cp -r' arguments. Also document support for 'cp :a :b'. Signed-off-by: Damien George --- docs/reference/mpremote.rst | 2 ++ tools/mpremote/mpremote/main.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index eb0233bddae4..a48df9953f50 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -262,6 +262,8 @@ Examples mpremote cp main.py : + mpremote cp :a.py :b.py + mpremote cp -r dir/ : mpremote cp a.py b.py : + repl diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index fa4785b3bf8f..bd98da88248c 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -333,10 +333,15 @@ def _list_recursive(files, path): if fs_args[0] == "cp" and fs_args[1] == "-r": fs_args.pop(0) fs_args.pop(0) - assert fs_args[-1] == ":" + if fs_args[-1] != ":": + print(f"{_PROG}: 'cp -r' destination must be ':'") + sys.exit(1) fs_args.pop() src_files = [] for path in fs_args: + if path.startswith(":"): + print(f"{_PROG}: 'cp -r' source files must be local") + sys.exit(1) _list_recursive(src_files, path) known_dirs = {""} pyb.exec_("import uos") From 6b16ce8d38461e9a8f11642a4a9c6e4621c00872 Mon Sep 17 00:00:00 2001 From: Matt Trentini Date: Fri, 19 Aug 2022 01:15:50 +1000 Subject: [PATCH 1653/4290] docs: Update CPython differences and improve the look of table layouts. Updated some of the CPython feature differences: - Updated status of some features. - Added CSS to fix table widths to 100% and word wrap. - Specified explicit table column ratios to improve layout appearance. - Added missing references to anchors. - Better consistency with use of formatting and case. --- docs/conf.py | 4 + docs/differences/python_35.rst | 330 +++++++++++++++++---------------- docs/differences/python_36.rst | 103 +++++----- docs/differences/python_37.rst | 127 +++++++------ docs/differences/python_38.rst | 33 ++-- docs/differences/python_39.rst | 43 +++-- docs/static/custom.css | 5 + 7 files changed, 353 insertions(+), 292 deletions(-) create mode 100644 docs/static/custom.css diff --git a/docs/conf.py b/docs/conf.py index a7a4ab08c5b0..5533bf01918a 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -166,6 +166,10 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['static'] +# Add a custom CSS file for HTML generation +html_css_files = [ + 'custom.css', +] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. diff --git a/docs/differences/python_35.rst b/docs/differences/python_35.rst index 94b10b583737..0fdc6121a1dd 100644 --- a/docs/differences/python_35.rst +++ b/docs/differences/python_35.rst @@ -5,55 +5,60 @@ Python 3.5 Below is a list of finalised/accepted PEPs for Python 3.5 grouped into their impact to MicroPython. - +----------------------------------------------------------------------------------------------------------+---------------+ - | **Extensions to the syntax:** | **Status** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 448 `_ | additional unpacking generalizations | Partial | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 465 `_ | a new matrix multiplication operator | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 492 `_ | coroutines with async and await syntax | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | **Extensions and changes to runtime:** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 461 `_ | % formatting for binary strings | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 475 `_ | retrying system calls that fail with EINTR | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 479 `_ | change StopIteration handling inside generators | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | **Standard library changes:** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 471 `_ | os.scandir() | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 485 `_ | math.isclose(), a function for testing | Completed | - | | approximate equality | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | **Miscellaneous changes:** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 441 `_ | improved Python zip application support | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 486 `_ | make the Python Launcher aware of virtual | Not relevant | - | | environments | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 484 `_ | type hints (advisory only) | In Progress | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 488 `_ | elimination of PYO files | Not relevant | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 489 `_ | redesigning extension module loading | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ +.. table:: + :widths: 30 50 20 + +--------------------------------------------------------------------------------------------------------------+--------------------+ + | **Extensions to the syntax** | **Status** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 448 `_ | Additional unpacking generalizations | Partial | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 465 `_ | A new matrix multiplication operator | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 492 `_ | Coroutines with ``async`` and ``await`` syntax | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | **Extensions and changes to runtime** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 461 `_ | % formatting for binary strings | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 475 `_ | Retrying system calls that fail with ``EINTR`` | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 479 `_ | Change ``StopIteration`` handling inside generators | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | **Standard library changes** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 471 `_ | ``os.scandir()`` | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 485 `_ | ``math.isclose()``, a function for testing | Complete | + | | approximate equality | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | **Miscellaneous changes** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 441 `_ | Improved Python zip application support | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 486 `_ | Make the Python Launcher aware of virtual | Not relevant | + | | environments | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 484 `_ | Type hints (advisory only) | Complete [#fth]_ | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 488 `_ | Elimination of PYO files | Not relevant | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 489 `_ | Redesigning extension module loading | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ Other Language Changes: - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Added the *namereplace* error handlers. The *backslashreplace* error handlers now work with decoding and | | - | translating. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Property docstrings are now writable. This is especially useful for collections.namedtuple() docstrings | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Circular imports involving relative imports are now supported. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ +.. table:: + :widths: 90 10 + + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Added the *namereplace* error handlers. The *backslashreplace* error handlers now work with decoding and | | + | translating. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Property docstrings are now writable. This is especially useful for collections.namedtuple() docstrings | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Circular imports involving relative imports are now supported. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ New Modules: @@ -65,117 +70,124 @@ New Modules: Changes to built-in modules: - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `collections `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *OrderedDict* class is now implemented in C, which makes it 4 to 100 times faster. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | *OrderedDict.items()* , *OrderedDict.keys()* , *OrderedDict.values()* views now support reversed() | | - | iteration. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The deque class now defines *index()*, *insert()*, and *copy()*, and supports the + and * operators. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Docstrings produced by namedtuple() can now be updated. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The UserString class now implements the *__getnewargs__()*, *__rmod__()*, *casefold()*, *format_map()*, | | - | *isprintable()*, and *maketrans()* methods to match the corresponding methods of str. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `heapq `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Element comparison in *merge()* can now be customized by passing a key function in a new optional key | | - | keyword argument, and a new optional *reverse* keyword argument can be used to reverse element comparison | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `io `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *BufferedIOBase.readinto1()* method, that uses at most one call to the underlying raw stream's | | - | *RawIOBase.read()* or *RawIOBase.readinto()* methods | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `json `_ | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | JSON decoder now raises JSONDecodeError instead of ValueError to provide better context information about | | - | the error. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `math `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Two new constants have been added to the math module: *inf* and *nan*. | Completed | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new function *isclose()* provides a way to test for approximate equality. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *gcd()* function has been added. The *fractions.gcd()* function is now deprecated. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `os `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The new *scandir()* function returning an iterator of DirEntry objects has been added. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *urandom()* function now uses the *getrandom()* syscall on Linux 3.17 or newer, and *getentropy()* on | | - | OpenBSD 5.6 and newer, removing the need to use /dev/urandom and avoiding failures due to potential file | | - | descriptor exhaustion. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | New *get_blocking()* and *set_blocking()* functions allow getting and setting a file descriptor's blocking| | - | mode (O_NONBLOCK.) | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | There is a new *os.path.commonpath()* function returning the longest common sub-path of each passed | | - | pathname | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `re `_ | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | References and conditional references to groups with fixed length are now allowed in lookbehind assertions| | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The number of capturing groups in regular expressions is no longer limited to 100. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *sub()* and *subn()* functions now replace unmatched groups with empty strings instead of raising an | | - | exception. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *re.error* exceptions have new attributes, msg, pattern, pos, lineno, and colno, that provide better | | - | context information about the error | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `socket `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Functions with timeouts now use a monotonic clock, instead of a system clock. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *socket.sendfile()* method allows sending a file over a socket by using the high-performance | | - | *os.sendfile()* function on UNIX, resulting in uploads being from 2 to 3 times faster than when using | | - | plain *socket.send()* | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *socket.sendall()* method no longer resets the socket timeout every time bytes are received or sent. | | - | The socket timeout is now the maximum total duration to send all data. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The backlog argument of the *socket.listen()* method is now optional. By default it is set to SOMAXCONN or| Completed | - | to 128, whichever is less. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `ssl `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Memory BIO Support | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Application-Layer Protocol Negotiation Support | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | There is a new *SSLSocket.version()* method to query the actual protocol version in use. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The SSLSocket class now implements a *SSLSocket.sendfile()* method. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *SSLSocket.send()* method now raises either the *ssl.SSLWantReadError* or *ssl.SSLWantWriteError* | | - | exception on a non-blocking socket if the operation would block. Previously, it would return 0. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *cert_time_to_seconds()* function now interprets the input time as UTC and not as local time, per RFC | | - | 5280. Additionally, the return value is always an int. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | New *SSLObject.shared_ciphers()* and *SSLSocket.shared_ciphers()* methods return the list of ciphers sent | | - | by the client during the handshake. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *SSLSocket.do_handshake()*, *SSLSocket.read()*, *SSLSocket.shutdown()*, and *SSLSocket.write()* | | - | methods of the SSLSocket class no longer reset the socket timeout every time bytes are received or sent. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *match_hostname()* function now supports matching of IP addresses. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `sys `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *set_coroutine_wrapper()* function allows setting a global hook that will be called whenever a | | - | coroutine object is created by an async def function. A corresponding *get_coroutine_wrapper()* can be | | - | used to obtain a currently set wrapper. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *is_finalizing()* function can be used to check if the Python interpreter is shutting down. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `time `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *monotonic()* function is now always available | | - +-----------------------------------------------------------------------------------------------------------+---------------+ +.. table:: + :widths: 90 10 + + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `collections `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *OrderedDict* class is now implemented in C, which makes it 4 to 100 times faster. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | *OrderedDict.items()* , *OrderedDict.keys()* , *OrderedDict.values()* views now support reversed() | | + | iteration. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The deque class now defines *index()*, *insert()*, and *copy()*, and supports the + and * operators. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Docstrings produced by namedtuple() can now be updated. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The UserString class now implements the *__getnewargs__()*, *__rmod__()*, *casefold()*, *format_map()*, | | + | *isprintable()*, and *maketrans()* methods to match the corresponding methods of str. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `heapq `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Element comparison in *merge()* can now be customized by passing a key function in a new optional key | | + | keyword argument, and a new optional *reverse* keyword argument can be used to reverse element comparison | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `io `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *BufferedIOBase.readinto1()* method, that uses at most one call to the underlying raw stream's | | + | *RawIOBase.read()* or *RawIOBase.readinto()* methods | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `json `_ | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | JSON decoder now raises JSONDecodeError instead of ValueError to provide better context information about | | + | the error. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `math `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Two new constants have been added to the math module: *inf* and *nan*. | Complete | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new function *isclose()* provides a way to test for approximate equality. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *gcd()* function has been added. The *fractions.gcd()* function is now deprecated. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `os `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The new *scandir()* function returning an iterator of DirEntry objects has been added. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *urandom()* function now uses the *getrandom()* syscall on Linux 3.17 or newer, and *getentropy()* on | | + | OpenBSD 5.6 and newer, removing the need to use /dev/urandom and avoiding failures due to potential file | | + | descriptor exhaustion. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | New *get_blocking()* and *set_blocking()* functions allow getting and setting a file descriptor's blocking| | + | mode (O_NONBLOCK.) | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | There is a new *os.path.commonpath()* function returning the longest common sub-path of each passed | | + | pathname | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `re `_ | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | References and conditional references to groups with fixed length are now allowed in lookbehind assertions| | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The number of capturing groups in regular expressions is no longer limited to 100. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *sub()* and *subn()* functions now replace unmatched groups with empty strings instead of raising an | | + | exception. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *re.error* exceptions have new attributes, msg, pattern, pos, lineno, and colno, that provide better | | + | context information about the error | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `socket `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Functions with timeouts now use a monotonic clock, instead of a system clock. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *socket.sendfile()* method allows sending a file over a socket by using the high-performance | | + | *os.sendfile()* function on UNIX, resulting in uploads being from 2 to 3 times faster than when using | | + | plain *socket.send()* | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *socket.sendall()* method no longer resets the socket timeout every time bytes are received or sent. | | + | The socket timeout is now the maximum total duration to send all data. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The backlog argument of the *socket.listen()* method is now optional. By default it is set to SOMAXCONN or| Complete | + | to 128, whichever is less. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `ssl `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Memory BIO Support | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Application-Layer Protocol Negotiation Support | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | There is a new *SSLSocket.version()* method to query the actual protocol version in use. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The SSLSocket class now implements a *SSLSocket.sendfile()* method. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *SSLSocket.send()* method now raises either the *ssl.SSLWantReadError* or *ssl.SSLWantWriteError* | | + | exception on a non-blocking socket if the operation would block. Previously, it would return 0. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *cert_time_to_seconds()* function now interprets the input time as UTC and not as local time, per RFC | | + | 5280. Additionally, the return value is always an int. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | New *SSLObject.shared_ciphers()* and *SSLSocket.shared_ciphers()* methods return the list of ciphers sent | | + | by the client during the handshake. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *SSLSocket.do_handshake()*, *SSLSocket.read()*, *SSLSocket.shutdown()*, and *SSLSocket.write()* | | + | methods of the SSLSocket class no longer reset the socket timeout every time bytes are received or sent. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *match_hostname()* function now supports matching of IP addresses. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `sys `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *set_coroutine_wrapper()* function allows setting a global hook that will be called whenever a | | + | coroutine object is created by an async def function. A corresponding *get_coroutine_wrapper()* can be | | + | used to obtain a currently set wrapper. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *is_finalizing()* function can be used to check if the Python interpreter is shutting down. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `time `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *monotonic()* function is now always available | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + +.. rubric:: Notes + +.. [#fth] The MicroPython parser correct ignores all type hints. However, the ``typing`` module is not built-in. diff --git a/docs/differences/python_36.rst b/docs/differences/python_36.rst index edf6bef02300..3315b0594daf 100644 --- a/docs/differences/python_36.rst +++ b/docs/differences/python_36.rst @@ -5,53 +5,59 @@ Python 3.6 Python 3.6 beta 1 was released on 12 Sep 2016, and a summary of the new features can be found here: - +-----------------------------------------------------------------------------------------------------------+--------------+ - | **New Syntax Features:** | **Status** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 498 `_ | Literal String Formatting | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 515 `_ | Underscores in Numeric Literals | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 525 `_ | Asynchronous Generators | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 526 `_ | Syntax for Variable Annotations (provisional) | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 530 `_ | Asynchronous Comprehensions | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **New Built-in Features:** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 468 `_ | Preserving the order of *kwargs* in a function | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 487 `_ | Simpler customization of class creation | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 520 `_ | Preserving Class Attribute Definition Order | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **Standard Library Changes:** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 495 `_ | Local Time Disambiguation | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 506 `_ | Adding A Secrets Module To The Standard Library | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 519 `_ | Adding a file system path protocol | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **CPython internals:** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 509 `_ | Add a private version to dict | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 523 `_ | Adding a frame evaluation API to CPython | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **Linux/Window Changes** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 524 `_ | Make os.urandom() blocking on Linux | | - | | (during system startup) | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 528 `_ | Change Windows console encoding to UTF-8 | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 529 `_ | Change Windows filesystem encoding to UTF-8 | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ +.. table:: + :widths: 30 50 20 + + +-----------------------------------------------------------------------------------------------------------+-----------------+ + | **New Syntax Features** | **Status** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 498 `_ | Literal String Formatting | Complete | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 515 `_ | Underscores in Numeric Literals | Complete | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 525 `_ | Asynchronous Generators | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 526 `_ | Syntax for Variable Annotations (provisional) | Complete | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 530 `_ | Asynchronous Comprehensions | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **New Built-in Features** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 468 `_ | Preserving the order of *kwargs* in a function | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 487 `_ | Simpler customization of class creation | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 520 `_ | Preserving Class Attribute Definition Order | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **Standard Library Changes** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 495 `_ | Local Time Disambiguation | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 506 `_ | Adding A Secrets Module To The Standard Library | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 519 `_ | Adding a file system path protocol | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **CPython Internals** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 509 `_ | Add a private version to dict | Won't do | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 523 `_ | Adding a frame evaluation API to CPython | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **Linux/Window Changes** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 524 `_ | Make ``os.urandom()`` blocking on Linux | | + | | (during system startup) | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 528 `_ | Change Windows console encoding to UTF-8 | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 529 `_ | Change Windows filesystem encoding to UTF-8 | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ Other Language Changes: +.. table:: + :widths: 90 10 + +-------------------------------------------------------------------------------------------------------------+---------------+ | A *global* or *nonlocal* statement must now textually appear before the first use of the affected name in | | | the same scope. Previously this was a SyntaxWarning. | | @@ -71,6 +77,9 @@ Other Language Changes: Changes to built-in modules: +.. table:: + :widths: 90 10 + +--------------------------------------------------------------------------------------------------------------+----------------+ | `array `_ | | +--------------------------------------------------------------------------------------------------------------+----------------+ @@ -78,7 +87,7 @@ Changes to built-in modules: +--------------------------------------------------------------------------------------------------------------+----------------+ | `binascii `_ | | +--------------------------------------------------------------------------------------------------------------+----------------+ - | The b2a_base64() function now accepts an optional newline keyword argument to control whether the newline | Completed | + | The b2a_base64() function now accepts an optional newline keyword argument to control whether the newline | Complete | | character is appended to the return value | | +--------------------------------------------------------------------------------------------------------------+----------------+ | `cmath `_ | | @@ -121,7 +130,7 @@ Changes to built-in modules: +--------------------------------------------------------------------------------------------------------------+----------------+ | `math `_ | +--------------------------------------------------------------------------------------------------------------+----------------+ - | The new math.tau (Ï„) constant has been added | Completed | + | The new math.tau (Ï„) constant has been added | Complete | +--------------------------------------------------------------------------------------------------------------+----------------+ | `os `_ | +--------------------------------------------------------------------------------------------------------------+----------------+ @@ -136,7 +145,7 @@ Changes to built-in modules: | `re `_ | +--------------------------------------------------------------------------------------------------------------+----------------+ | Added support of modifier spans in regular expressions. Examples: *'(?i:p)ython'* matches 'python' and | | - | 'Python', but not 'PYTHON'; *'(?i)g(?-i:v)r'* matches *'GvR'* and *'gvr'*, but not *'GVR'* . | | + | 'Python', but not 'PYTHON'; *'(?i)g(?-i:v)r'* matches *'GvR'* and *'gvr'*, but not *'GVR'*. | | +--------------------------------------------------------------------------------------------------------------+----------------+ | Match object groups can be accessed by *__getitem__*, which is equivalent to *group()*. So *mo['name']* is | | | now equivalent to *mo.group('name')*. | | diff --git a/docs/differences/python_37.rst b/docs/differences/python_37.rst index c46678e931dd..86d1b6e81f96 100644 --- a/docs/differences/python_37.rst +++ b/docs/differences/python_37.rst @@ -5,72 +5,81 @@ Python 3.7 New Features: - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | **Features:** | **Status** | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 538 `_ | Coercing the legacy C locale to a UTF-8 based | | - | | locale | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 539 `_ | A New C-API for Thread-Local Storage in CPython | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 540 `_ | UTF-8 mode | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 552 `_ | Deterministic pyc | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 553 `_ | Built-in breakpoint() | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 557 `_ | Data Classes | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 560 `_ | Core support for typing module and generic types | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 562 `_ | Module __getattr__ and __dir__ | Partially done | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 563 `_ | Postponed Evaluation of Annotations | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 564 `_ | Time functions with nanosecond resolution | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 565 `_ | Show DeprecationWarning in __main__ | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 567 `_ | Context Variables | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ +.. table:: + :widths: 20 60 20 + + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | **Feature** | **Status** | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 538 `_ | Coercing the legacy C locale to a UTF-8 based | | + | | locale | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 539 `_ | A New C-API for Thread-Local Storage in CPython | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 540 `_ | UTF-8 mode | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 552 `_ | Deterministic pyc | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 553 `_ | Built-in ``breakpoint()`` | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 557 `_ | Data Classes | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 560 `_ | Core support for typing module and generic types | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 562 `_ | Module ``__getattr__`` and ``__dir__`` | Partial | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 563 `_ | Postponed Evaluation of Annotations | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 564 `_ | Time functions with nanosecond resolution | Partial [#ftimenanosec]_ | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 565 `_ | Show DeprecationWarning in ``__main__`` | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 567 `_ | Context Variables | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ Other Language Changes: - +----------------------------------------------------------------------------------------------------------+----------------+ - | async and await are now reserved keywords | Completed | - +----------------------------------------------------------------------------------------------------------+----------------+ - | dict objects must preserve insertion-order | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | More than 255 arguments can now be passed to a function; a function can now have more than 255 parameters| | - +----------------------------------------------------------------------------------------------------------+----------------+ - | bytes.fromhex() and bytearray.fromhex() now ignore all ASCII whitespace, not only spaces | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | str, bytes, and bytearray gained support for the new isascii() method, which can be used to test if a | | - | string or bytes contain only the ASCII characters | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | ImportError now displays module name and module __file__ path whenfrom ... import ... fails | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | Circular imports involving absolute imports with binding a submodule to a name are now supported | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | object.__format__(x, '') is now equivalent to str(x) rather than format(str(self), '') | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | In order to better support dynamic creation of stack traces, types.TracebackType can now be instantiated | | - | from Python code, and the tb_next attribute on tracebacks is now writable | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | When using the -m switch, sys.path[0] is now eagerly expanded to the full starting directory path, rather| | - | than being left as the empty directory (which allows imports from the current working directory at the | | - | time when an import occurs) | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | The new -X importtime option or the PYTHONPROFILEIMPORTTIME environment variable can be used to show the | | - | timing of each module import | | - +----------------------------------------------------------------------------------------------------------+----------------+ +.. table:: + :widths: 90 10 + + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``async`` and ``await`` are now reserved keywords | Complete | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``dict`` objects must preserve insertion-order | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | More than 255 arguments can now be passed to a function; a function can now have more than 255 parameters | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``bytes.fromhex()`` and ``bytearray.fromhex()`` now ignore all ASCII whitespace, not only spaces | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``str``, ``bytes``, and ``bytearray`` gained support for the new ``isascii()`` method, which can be used to | | + | test if a string or bytes contain only the ASCII characters | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``ImportError`` now displays module name and module ``__file__`` path when ``from ... import ...`` fails | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | Circular imports involving absolute imports with binding a submodule to a name are now supported | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``object.__format__(x, '')`` is now equivalent to ``str(x)`` rather than ``format(str(self), '')`` | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | In order to better support dynamic creation of stack traces, ``types.TracebackType`` can now be | | + | instantiated from Python code, and the ``tb_next`` attribute on tracebacks is now writable | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | When using the ``-m`` switch, ``sys.path[0]`` is now eagerly expanded to the full starting directory path, | | + | rather than being left as the empty directory (which allows imports from the current working directory | | + | at the time when an import occurs) | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | The new ``-X importtime`` option or the ``PYTHONPROFILEIMPORTTIME`` environment variable can be used to | | + | show the timing of each module import | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ Changes to built-in modules: +.. table:: + :widths: 90 10 + +------------------------------------------------------------------------------------------------------------+----------------+ | `asyncio `_ | | +------------------------------------------------------------------------------------------------------------+----------------+ - | asyncio (many, may need a separate ticket) | | + | Too many to list | | +------------------------------------------------------------------------------------------------------------+----------------+ | `gc `_ | | +------------------------------------------------------------------------------------------------------------+----------------+ @@ -93,3 +102,7 @@ Changes to built-in modules: +------------------------------------------------------------------------------------------------------------+----------------+ | Mostly updates to support nanosecond resolution in PEP564, see above | | +------------------------------------------------------------------------------------------------------------+----------------+ + +.. rubric:: Notes + +.. [#ftimenanosec] Only :func:`time.time_ns` is implemented. diff --git a/docs/differences/python_38.rst b/docs/differences/python_38.rst index 47840a8b40ec..32fd68d2caea 100644 --- a/docs/differences/python_38.rst +++ b/docs/differences/python_38.rst @@ -5,15 +5,18 @@ Python 3.8 Python 3.8.0 (final) was released on the 14 October 2019. The Features for 3.8 are defined in `PEP 569 `_ and -a detailed description of the changes can be found in What's New in `Python +a detailed description of the changes can be found in `What's New in Python 3.8. `_ +.. table:: + :widths: 20 60 20 + +--------------------------------------------------------+---------------------------------------------------+---------------+ - | **Features:** | Status | + | **Features** | **Status** | +--------------------------------------------------------+---------------------------------------------------+---------------+ | `PEP 570 `_ | Positional-only arguments | | +--------------------------------------------------------+---------------------------------------------------+---------------+ - | `PEP 572 `_ | Assignment Expressions | | + | `PEP 572 `_ | Assignment Expressions | Complete | +--------------------------------------------------------+---------------------------------------------------+---------------+ | `PEP 574 `_ | Pickle protocol 5 with out-of-band data | | +--------------------------------------------------------+---------------------------------------------------+---------------+ @@ -25,13 +28,16 @@ a detailed description of the changes can be found in What's New in `Python +--------------------------------------------------------+---------------------------------------------------+---------------+ | **Miscellaneous** | +------------------------------------------------------------------------------------------------------------+---------------+ - | f-strings support = for self-documenting expressions and debugging | Completed | + | f-strings support = for self-documenting expressions and debugging | Complete | +------------------------------------------------------------------------------------------------------------+---------------+ Other Language Changes: +.. table:: + :widths: 90 10 + +------------------------------------------------------------------------------------------------------------+-------------+ - | A *continue* statement was illegal in the *finally* clause due to a problem with the implementation. In | Completed | + | A *continue* statement was illegal in the *finally* clause due to a problem with the implementation. In | Complete | | Python 3.8 this restriction was lifted | | +------------------------------------------------------------------------------------------------------------+-------------+ | The *bool*, *int* , and *fractions.Fraction* types now have an *as_integer_ratio()* method like that found | | @@ -72,14 +78,17 @@ Other Language Changes: Changes to built-in modules: +.. table:: + :widths: 90 10 + +------------------------------------------------------------------------------------------------------------+-------------+ - | `asyncio` | + | `asyncio `_ | +------------------------------------------------------------------------------------------------------------+-------------+ - | *asyncio.run()* has graduated from the provisional to stable API | Completed | + | *asyncio.run()* has graduated from the provisional to stable API | Complete | +------------------------------------------------------------------------------------------------------------+-------------+ | Running *python -m asyncio* launches a natively async REPL | | +------------------------------------------------------------------------------------------------------------+-------------+ - | The exception *asyncio.CancelledError* now inherits from *BaseException* rather than *Exception* and no | Completed | + | The exception *asyncio.CancelledError* now inherits from *BaseException* rather than *Exception* and no | Complete | | longer inherits from *concurrent.futures.CancelledError* | | +------------------------------------------------------------------------------------------------------------+-------------+ | Added *asyncio.Task.get_coro()* for getting the wrapped coroutine within an *asyncio.Task* | | @@ -90,12 +99,12 @@ Changes to built-in modules: | Added support for Happy Eyeballs to *asyncio.loop.create_connection()*. To specify the behavior, two new | | | parameters have been added: *happy_eyeballs_delay* and interleave. | | +------------------------------------------------------------------------------------------------------------+-------------+ - | `gc` | + | `gc `_ | +------------------------------------------------------------------------------------------------------------+-------------+ | *get_objects()* can now receive an optional generation parameter indicating a generation to get objects | | | from. (Note, though, that while *gc* is a built-in, *get_objects()* is not implemented for MicroPython) | | +------------------------------------------------------------------------------------------------------------+-------------+ - | `math` | + | `math `_ | +------------------------------------------------------------------------------------------------------------+-------------+ | Added new function *math.dist()* for computing Euclidean distance between two points | | +------------------------------------------------------------------------------------------------------------+-------------+ @@ -109,9 +118,9 @@ Changes to built-in modules: | Added a new function *math.isqrt()* for computing accurate integer square roots without conversion to | | | floating point | | +------------------------------------------------------------------------------------------------------------+-------------+ - | The function *math.factorial()* no longer accepts arguments that are not int-like | Completed | + | The function *math.factorial()* no longer accepts arguments that are not int-like | Complete | +------------------------------------------------------------------------------------------------------------+-------------+ - | `sys` | + | `sys `_ | +------------------------------------------------------------------------------------------------------------+-------------+ | Add new *sys.unraisablehook()* function which can be overridden to control how "unraisable exceptions" | | | are handled | | diff --git a/docs/differences/python_39.rst b/docs/differences/python_39.rst index 6852dd635ea8..023c6d7c1e39 100644 --- a/docs/differences/python_39.rst +++ b/docs/differences/python_39.rst @@ -8,35 +8,41 @@ defined in `PEP 596 and a detailed description of the changes can be found in `What's New in Python 3.9 `_ +.. table:: + :widths: 20 60 20 + +--------------------------------------------------------+----------------------------------------------------+--------------+ - | **Features:** | | **Status** | + | **Features** | | **Status** | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 573 `_ | fast access to module state from methods of C | | + | `PEP 573 `_ | Fast access to module state from methods of C | | | | extension types | | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 584 `_ | union operators added to dict | | + | `PEP 584 `_ | Union operators added to dict | | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 585 `_ | type hinting generics in standard collections | | + | `PEP 585 `_ | Type hinting generics in standard collections | | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 593 `_ | flexible function and variable annotations | | + | `PEP 593 `_ | Flexible function and variable annotations | | +--------------------------------------------------------+----------------------------------------------------+--------------+ | `PEP 602 `_ | CPython adopts an annual release cycle. Instead of | | | | annual, aiming for two month release cycle | | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 614 `_ | relaxed grammar restrictions on decorators | | + | `PEP 614 `_ | Relaxed grammar restrictions on decorators | | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 615 `_ | the IANA Time Zone Database is now present in the | | + | `PEP 615 `_ | The IANA Time Zone Database is now present in the | | | | standard library in the zoneinfo module | | +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 616 `_ | string methods to remove prefixes and suffixes | | + | `PEP 616 `_ | String methods to remove prefixes and suffixes | | +--------------------------------------------------------+----------------------------------------------------+--------------+ | `PEP 617 `_ | CPython now uses a new parser based on PEG | | +--------------------------------------------------------+----------------------------------------------------+--------------+ Other Language Changes: +.. table:: + :widths: 90 10 + +-------------------------------------------------------------------------------------------------------------+---------------+ - | *__import__()* now raises *ImportError* instead of *ValueError* | Completed | + | *__import__()* now raises *ImportError* instead of *ValueError* | Complete | +-------------------------------------------------------------------------------------------------------------+---------------+ | Python now gets the absolute path of the script filename specified on the command line (ex: *python3* | | | *script.py*): the *__file__* attribute of the *__main__* module became an absolute path, rather than a | | @@ -62,8 +68,11 @@ Other Language Changes: Changes to built-in modules: +.. table:: + :widths: 90 10 + +---------------------------------------------------------------------------------------------------------------+---------------+ - | `asyncio` | + | `asyncio `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Due to significant security concerns, the reuse_address parameter of *asyncio.loop.create_datagram_endpoint()*| | | is no longer supported | | @@ -82,13 +91,13 @@ Changes to built-in modules: +---------------------------------------------------------------------------------------------------------------+---------------+ | *asyncio* now raises *TyperError* when calling incompatible methods with an *ssl.SSLSocket* socket | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `gc` | + | `gc `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Garbage collection does not block on resurrected objects | | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added a new function *gc.is_finalized()* to check if an object has been finalized by the garbage collector | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `math` | + | `math `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Expanded the *math.gcd()* function to handle multiple arguments. Formerly, it only supported two arguments | | +---------------------------------------------------------------------------------------------------------------+---------------+ @@ -98,21 +107,21 @@ Changes to built-in modules: +---------------------------------------------------------------------------------------------------------------+---------------+ | Added *math.ulp()*: return the value of the least significant bit of a float | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `os` | + | `os `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Exposed the Linux-specific *os.pidfd_open()* and *os.P_PIDFD* | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | The *os.unsetenv()* function is now also available on Windows | Completed | + | The *os.unsetenv()* function is now also available on Windows | Complete | +---------------------------------------------------------------------------------------------------------------+---------------+ - | The *os.putenv()* and *os.unsetenv()* functions are now always available | Completed | + | The *os.putenv()* and *os.unsetenv()* functions are now always available | Complete | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added *os.waitstatus_to_exitcode()* function: convert a wait status to an exit code | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `random` | + | `random `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added a new *random.Random.randbytes* method: generate random bytes | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `sys` | + | `sys `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added a new *sys.platlibdir* attribute: name of the platform-specific library directory | | +---------------------------------------------------------------------------------------------------------------+---------------+ diff --git a/docs/static/custom.css b/docs/static/custom.css new file mode 100644 index 000000000000..b0a7f746fcab --- /dev/null +++ b/docs/static/custom.css @@ -0,0 +1,5 @@ +/* Workaround to force Sphinx to render tables to 100% and wordwrap */ +/* See https://stackoverflow.com/questions/69359978/grid-table-does-not-word-wrap for more details */ +.wy-table-responsive table td, .wy-table-responsive table th { + white-space: inherit; +} From 769262ef03b4e7198759bcc72c87c7ca5fc7de29 Mon Sep 17 00:00:00 2001 From: Tomasz 'CeDeROM' CEDRO Date: Thu, 18 Aug 2022 05:20:02 +0200 Subject: [PATCH 1654/4290] docs/esp32: Update UART quickref on input-only pins. Signed-off-by: Tomasz 'CeDeROM' CEDRO --- docs/esp32/quickref.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 1529c0ef4929..03ca97c7a7df 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -216,9 +216,10 @@ They each have default GPIO assigned to them, however depending on your ESP32 variant and board, these pins may conflict with embedded flash, onboard PSRAM or peripherals. -Any GPIO can be used for hardware UARTs using the GPIO matrix, so to avoid -conflicts simply provide ``tx`` and ``rx`` pins when constructing. The default -pins listed below. +Any GPIO can be used for hardware UARTs using the GPIO matrix, except for +input-only pins 34-39 that can be used as ``rx``. To avoid conflicts simply +provide ``tx`` and ``rx`` pins when constructing. The default pins listed +below. ===== ===== ===== ===== \ UART0 UART1 UART2 From 602f9db2f35924a687f8ded2170b2a0b0e13979a Mon Sep 17 00:00:00 2001 From: Tomasz 'CeDeROM' CEDRO Date: Thu, 18 Aug 2022 06:02:53 +0200 Subject: [PATCH 1655/4290] docs/library/machine.UART: Add notes about UART init and deinit. * `init()` can be called multiple times to reconfigure UART. * After `deinit()` it is impossible to call `init()` again. Signed-off-by: Tomasz 'CeDeROM' CEDRO --- docs/library/machine.UART.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst index e23952573698..1d54174c9961 100644 --- a/docs/library/machine.UART.rst +++ b/docs/library/machine.UART.rst @@ -87,10 +87,22 @@ Methods When no pins are given, then the default set of TX and RX pins is taken, and hardware flow control will be disabled. If *pins* is ``None``, no pin assignment will be made. + .. note:: + It is possible to call ``init()`` multiple times on the same object in + order to reconfigure UART on the fly. That allows using single UART + peripheral to serve different devices attached to different GPIO pins. + Only one device can be served at a time in that case. + Also do not call ``deinit()`` as it will prevent calling ``init()`` + again. + .. method:: UART.deinit() Turn off the UART bus. + .. note:: + You will not be able to call ``init()`` on the object after ``deinit()``. + A new instance needs to be created in that case. + .. method:: UART.any() Returns an integer counting the number of characters that can be read without From da217e83d9a710a03fd8e324fe18d3684628cd69 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Tue, 23 Aug 2022 21:35:49 +0200 Subject: [PATCH 1656/4290] docs/library: Fix nested rst styles not rendering. These can't be nested, so apply styling separately. Signed-off-by: Laurens Valk --- docs/library/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/index.rst b/docs/library/index.rst index ffd373a4df25..59ed1127a783 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -195,4 +195,4 @@ but also the MicroPython libraries too (e.g. ``machine``, ``bluetooth``, etc). The main exception is the port-specific libraries (``pyb``, ``esp``, etc). *Other than when you specifically want to force the use of the built-in module, -we recommend always using ``import module`` rather than ``import umodule``.* +we recommend always using* ``import module`` *rather than* ``import umodule``. From 6dcfb25ae7cadc298a5aaa09c68205a828939cd9 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Tue, 23 Aug 2022 21:37:24 +0200 Subject: [PATCH 1657/4290] docs/library/micropython: Fix spelling of compiler. Signed-off-by: Laurens Valk --- docs/library/micropython.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst index 7106a1a2ff16..b17dfa9a75a4 100644 --- a/docs/library/micropython.rst +++ b/docs/library/micropython.rst @@ -9,7 +9,7 @@ Functions .. function:: const(expr) - Used to declare that the expression is a constant so that the compile can + Used to declare that the expression is a constant so that the compiler can optimise it. The use of this function should be as follows:: from micropython import const From 09879f99ca3a6c0e48353eb2aaa1c71ed237f126 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 22 Aug 2022 11:16:16 +1000 Subject: [PATCH 1658/4290] esp8266/README: Update build instructions to match ci.sh. The existing non-Docker instructions are basically impossible to follow because the esp-open-sdk does not compile. Update these instructions to use the exact toolchain that our CI uses. Also split the Docker from non-Docker instructions, to avoid confusion about which commands need to be prefixed. Signed-off-by: Jim Mussared --- ports/esp8266/README.md | 116 +++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 30 deletions(-) diff --git a/ports/esp8266/README.md b/ports/esp8266/README.md index 15ca7f891c26..dd50fc1af943 100644 --- a/ports/esp8266/README.md +++ b/ports/esp8266/README.md @@ -27,52 +27,106 @@ Documentation is available at http://docs.micropython.org/en/latest/esp8266/quic Build instructions ------------------ -You need the esp-open-sdk toolchain (which provides both the compiler and libraries), which -you can obtain using one of the following two options: - - - Use a Docker image with a pre-built toolchain (**recommended**). - To use this, install Docker, then prepend - `docker run --rm -v $HOME:$HOME -u $UID -w $PWD larsks/esp-open-sdk ` to the start - of the mpy-cross and firmware `make` commands below. This will run the commands using the - toolchain inside the container but using the files on your local filesystem. - - - or, install the esp-open-sdk directly on your PC, which can be found at - . Clone this repository and - run `make` in its directory to build and install the SDK locally. Make sure - to add toolchain bin directory to your PATH. Read esp-open-sdk's README for - additional important information on toolchain setup. - If you use this approach, then the command below will work exactly. - -Add the external dependencies to the MicroPython repository checkout: +You need the esp-open-sdk toolchain, which provides both the compiler and libraries. + +There are two ways to do this: + - By running the toolchain in [Docker](https://www.docker.com/) (**recommended**). + - By installing a pre-built toolchain and adding it to your `$PATH`. + +Regardless of which toolchain you use, the first step is to make sure required +submodules are available: + ```bash $ make -C ports/esp8266 submodules ``` + See the README in the repository root for more information about external dependencies. -The MicroPython cross-compiler must be built to pre-compile some of the -built-in scripts to bytecode. This can be done using: +__Building with Docker__ + +Once you have installed Docker, you can run all of the following build +commands inside the Docker container by prefixing them with `docker +run --rm -v $HOME:$HOME -u $UID -w $PWD larsks/esp-open-sdk ...command...`. +This will automatically download the Docker image provided by @larsks which +contains the full toolchain and SDK. + +Then you need to compile the MicroPython cross-compiler (`mpy-cross`). From +the root of this repository, run: + ```bash -$ make -C mpy-cross +$ docker run --rm -v $HOME:$HOME -u $UID -w $PWD larsks/esp-open-sdk make -C mpy-cross +``` + +**Note:** The `mpy-cross` binary will likely only work inside the Docker +container. This will not be a problem if you're only building ESP8266 +firmware, but if you're also working on other ports then you will need to +recompile for your host when switching between ports. To avoid this, use +the local toolchain instead. + +Then to compile the ESP8266 firmware: + +``` +$ cd ports/esp8266 +$ docker run --rm -v $HOME:$HOME -u $UID -w $PWD larsks/esp-open-sdk make -j BOARD=GENERIC +``` + +This will produce binary images in the `build-GENERIC/` subdirectory. +Substitute the board for whichever board you're using. + +__Building with a local toolchain__ + +First download the pre-built toolchain (thanks to @jepler from Adafruit). You +will need to find somewhere to put it in your filesystem, e.g. `~/espressif`. +Create that directory first if necessary. + +``` +$ cd ~/espressif # Change as necessary +$ wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz +$ tar zxvf xtensa-lx106-elf-standalone.tar.gz +$ rm xtensa-lx106-elf/bin/esptool.py # Use system version of esptool.py instead. +``` + +Then append this to your `$PATH` variable so the compiler binaries can be +found: + +``` +$ export "PATH=$HOME/espressif/xtensa-lx106-elf/bin/:$PATH" ``` -(Prepend the Docker command if using Docker, see above) -Then, to build MicroPython for the ESP8266, just run: +(You will need to do this each time you start a new terminal) + +Then you need to compile the MicroPython cross-compiler (`mpy-cross`). From +the root of this repository, run: + ```bash +$ make -C mpy-cross +``` + +Then to compile the ESP8266 firmware: + +``` $ cd ports/esp8266 -$ make +$ make -j BOARD=GENERIC ``` -(Prepend the Docker command if using Docker, see above) -This will produce binary images in the `build-GENERIC/` subdirectory. If you -install MicroPython to your module for the first time, or after installing any -other firmware, you should erase flash completely: +This will produce binary images in the `build-GENERIC/` subdirectory. +Substitute the board for whichever board you're using. + + +Installing MicroPython +---------------------- + +To communicate with the board you will need to install `esptool.py`. This can +be obtained from your system package manager or from PyPi via `pip`. + +If you install MicroPython to your module for the first time, or after +installing any other firmware, you should erase flash completely: + ```bash $ esptool.py --port /dev/ttyXXX erase_flash ``` -You can install esptool.py either from your system package manager or from PyPi. - Erasing the flash is also useful as a troubleshooting measure, if a module doesn't behave as expected. @@ -80,7 +134,9 @@ To flash MicroPython image to your ESP8266, use: ```bash $ make deploy ``` -(This should not be run inside Docker as it will need access to the serial port.) + +(If using the Docker instructions above, do not run this command via Docker as +it will need access to the serial port. Run it directly instead.) This will use the `esptool.py` script to download the images. You must have your ESP module in the bootloader mode, and connected to a serial port on your PC. From 8a0ee5a5c04e83f04d1c62029ac5ba7c74856507 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 22 Aug 2022 17:08:05 +1000 Subject: [PATCH 1659/4290] py/objstr: Split mp_obj_str_from_vstr into bytes/str versions. Previously the desired output type was specified. Now make the type part of the function name. Because this function is used in a few places this saves code size due to smaller call-site. This makes `mp_obj_new_str_type_from_vstr` a private function of objstr.c (which is almost the only place where the output type isn't a compile-time constant). This saves ~140 bytes on PYBV11. Signed-off-by: Jim Mussared --- extmod/machine_i2c.c | 4 ++-- extmod/machine_spi.c | 2 +- extmod/modlwip.c | 4 ++-- extmod/modubinascii.c | 4 ++-- extmod/moducryptolib.c | 2 +- extmod/moduhashlib.c | 12 +++++----- extmod/modujson.c | 4 ++-- extmod/modure.c | 6 ++++- extmod/modusocket.c | 4 ++-- extmod/vfs.c | 2 +- ports/cc3200/mods/moduos.c | 2 +- ports/cc3200/mods/modusocket.c | 4 ++-- ports/cc3200/mods/pybi2c.c | 4 ++-- ports/cc3200/mods/pybspi.c | 2 +- ports/esp32/modsocket.c | 2 +- ports/esp32/moduos.c | 2 +- ports/esp8266/moduos.c | 2 +- ports/mimxrt/moduos.c | 2 +- ports/nrf/modules/machine/spi.c | 2 +- ports/nrf/modules/uos/moduos.c | 2 +- ports/rp2/moduos.c | 2 +- ports/stm32/moduos.c | 2 +- ports/stm32/pyb_i2c.c | 4 ++-- ports/stm32/pyb_spi.c | 4 ++-- ports/stm32/usb.c | 4 ++-- ports/unix/main.c | 4 ++-- ports/unix/moduos.c | 2 +- ports/unix/modusocket.c | 2 +- ports/zephyr/modusocket.c | 2 +- py/modbuiltins.c | 4 ++-- py/modstruct.c | 2 +- py/obj.h | 3 ++- py/objint.c | 2 +- py/objstr.c | 40 ++++++++++++++++++++------------- py/parsenum.c | 2 +- py/persistentcode.c | 6 ++++- py/stream.c | 22 +++++++++++++----- 37 files changed, 102 insertions(+), 73 deletions(-) diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index 452f07a2ebdb..2aa217914bfb 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -417,7 +417,7 @@ STATIC mp_obj_t machine_i2c_readfrom(size_t n_args, const mp_obj_t *args) { if (ret < 0) { mp_raise_OSError(-ret); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_obj, 3, 4, machine_i2c_readfrom); @@ -581,7 +581,7 @@ STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args mp_raise_OSError(-ret); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_obj, 1, machine_i2c_readfrom_mem); diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index f160f97d04b4..ba533b2a651a 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -70,7 +70,7 @@ STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) { vstr_init_len(&vstr, mp_obj_get_int(args[1])); memset(vstr.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, vstr.len); mp_machine_spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read); diff --git a/extmod/modlwip.c b/extmod/modlwip.c index c6ee02132ff2..f9451a0ce439 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -1198,7 +1198,7 @@ STATIC mp_obj_t lwip_socket_recv(mp_obj_t self_in, mp_obj_t len_in) { return mp_const_empty_bytes; } vstr.len = ret; - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(lwip_socket_recv_obj, lwip_socket_recv); @@ -1271,7 +1271,7 @@ STATIC mp_obj_t lwip_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { tuple[0] = mp_const_empty_bytes; } else { vstr.len = ret; - tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + tuple[0] = mp_obj_new_bytes_from_vstr(&vstr); } tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); return mp_obj_new_tuple(2, tuple); diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 49c8d1fb971e..45a39c58d443 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -104,7 +104,7 @@ STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) { mp_raise_ValueError(MP_ERROR_TEXT("incorrect padding")); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64); @@ -166,7 +166,7 @@ STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args, if (newline) { *out = '\n'; } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64); diff --git a/extmod/moducryptolib.c b/extmod/moducryptolib.c index c58abaada67e..dc0ecb9b20f1 100644 --- a/extmod/moducryptolib.c +++ b/extmod/moducryptolib.c @@ -329,7 +329,7 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) { if (out_buf != MP_OBJ_NULL) { return out_buf; } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC mp_obj_t ucryptolib_aes_encrypt(size_t n_args, const mp_obj_t *args) { diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 39488788f271..7eae06b77d34 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -109,7 +109,7 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { vstr_t vstr; vstr_init_len(&vstr, 32); mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } #else @@ -143,7 +143,7 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { vstr_t vstr; vstr_init_len(&vstr, SHA256_BLOCK_SIZE); sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } #endif @@ -196,7 +196,7 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { vstr_t vstr; vstr_init_len(&vstr, SHA1_SIZE); SHA1_Final((byte *)vstr.buf, (SHA1_CTX *)self->state); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } #endif @@ -237,7 +237,7 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { vstr_init_len(&vstr, 20); mbedtls_sha1_finish_ret((mbedtls_sha1_context *)self->state, (byte *)vstr.buf); mbedtls_sha1_free((mbedtls_sha1_context *)self->state); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } #endif @@ -289,7 +289,7 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { vstr_t vstr; vstr_init_len(&vstr, MD5_SIZE); MD5_Final((byte *)vstr.buf, (MD5_CTX *)self->state); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } #endif // MICROPY_SSL_AXTLS @@ -330,7 +330,7 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { vstr_init_len(&vstr, 16); mbedtls_md5_finish_ret((mbedtls_md5_context *)self->state, (byte *)vstr.buf); mbedtls_md5_free((mbedtls_md5_context *)self->state); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } #endif // MICROPY_SSL_MBEDTLS diff --git a/extmod/modujson.c b/extmod/modujson.c index 9a73e4501e7c..57c50deec028 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -67,7 +67,7 @@ STATIC mp_obj_t mod_ujson_dump_helper(size_t n_args, const mp_obj_t *pos_args, m vstr_t vstr; vstr_init_print(&vstr, 8, &print_ext.base); mp_obj_print_helper(&print_ext.base, pos_args[0], PRINT_JSON); - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr(&vstr); } else { // dump(obj, stream) print_ext.base.data = MP_OBJ_TO_PTR(pos_args[1]); @@ -103,7 +103,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) { mp_print_t print; vstr_init_print(&vstr, 8, &print); mp_obj_print_helper(&print, obj, PRINT_JSON); - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); diff --git a/extmod/modure.c b/extmod/modure.c index 6bd89898431f..59fbfddbf24a 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -372,7 +372,11 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { // Add post-match string vstr_add_strn(&vstr_return, subj.begin, subj.end - subj.begin); - return mp_obj_new_str_from_vstr(mp_obj_get_type(where), &vstr_return); + if (mp_obj_get_type(where) == &mp_type_str) { + return mp_obj_new_str_from_vstr(&vstr_return); + } else { + return mp_obj_new_bytes_from_vstr(&vstr_return); + } } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub_helper); diff --git a/extmod/modusocket.c b/extmod/modusocket.c index 638ab0cf28c0..4d72531160e6 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -296,7 +296,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { return mp_const_empty_bytes; } vstr.len = ret; - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); @@ -347,7 +347,7 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { tuple[0] = mp_const_empty_bytes; } else { vstr.len = ret; - tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + tuple[0] = mp_obj_new_bytes_from_vstr(&vstr); } tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); return mp_obj_new_tuple(2, tuple); diff --git a/extmod/vfs.c b/extmod/vfs.c index be1a82d40447..0ef20e928108 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -360,7 +360,7 @@ mp_obj_t mp_vfs_getcwd(void) { if (!(cwd[0] == '/' && cwd[1] == 0)) { vstr_add_str(&vstr, cwd); } - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd); diff --git a/ports/cc3200/mods/moduos.c b/ports/cc3200/mods/moduos.c index cd01b59b35d5..e284e9eb1ffb 100644 --- a/ports/cc3200/mods/moduos.c +++ b/ports/cc3200/mods/moduos.c @@ -116,7 +116,7 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) { for (int i = 0; i < n; i++) { vstr.buf[i] = rng_get(); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); diff --git a/ports/cc3200/mods/modusocket.c b/ports/cc3200/mods/modusocket.c index 32849c51d47c..23982eb96602 100644 --- a/ports/cc3200/mods/modusocket.c +++ b/ports/cc3200/mods/modusocket.c @@ -581,7 +581,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { } vstr.len = ret; vstr.buf[vstr.len] = '\0'; - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); @@ -625,7 +625,7 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { } else { vstr.len = ret; vstr.buf[vstr.len] = '\0'; - tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + tuple[0] = mp_obj_new_bytes_from_vstr(&vstr); } tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_LITTLE); return mp_obj_new_tuple(2, tuple); diff --git a/ports/cc3200/mods/pybi2c.c b/ports/cc3200/mods/pybi2c.c index 5310176091a9..40b3e2a20714 100644 --- a/ports/cc3200/mods/pybi2c.c +++ b/ports/cc3200/mods/pybi2c.c @@ -392,7 +392,7 @@ STATIC mp_obj_t pyb_i2c_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map pyb_i2c_read_into(args, &vstr); // return the received data - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_obj, 3, pyb_i2c_readfrom); @@ -456,7 +456,7 @@ STATIC mp_obj_t pyb_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp vstr_t vstr; pyb_i2c_readmem_into (args, &vstr); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_mem_obj, 1, pyb_i2c_readfrom_mem); diff --git a/ports/cc3200/mods/pybspi.c b/ports/cc3200/mods/pybspi.c index 61b1a6bd11ee..ed03b0906081 100644 --- a/ports/cc3200/mods/pybspi.c +++ b/ports/cc3200/mods/pybspi.c @@ -305,7 +305,7 @@ STATIC mp_obj_t pyb_spi_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t * pybspi_transfer(self, NULL, vstr.buf, vstr.len, &write); // return the received data - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_read_obj, 1, pyb_spi_read); diff --git a/ports/esp32/modsocket.c b/ports/esp32/modsocket.c index 819ea26e9800..a281558241dc 100644 --- a/ports/esp32/modsocket.c +++ b/ports/esp32/modsocket.c @@ -552,7 +552,7 @@ mp_obj_t _socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in, } vstr.len = ret; - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { diff --git a/ports/esp32/moduos.c b/ports/esp32/moduos.c index f307a9ffe05b..bdfd19c5d20a 100644 --- a/ports/esp32/moduos.c +++ b/ports/esp32/moduos.c @@ -45,7 +45,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { vstr.buf[i] = r; r >>= 8; } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); diff --git a/ports/esp8266/moduos.c b/ports/esp8266/moduos.c index 9a235e61b9b9..a023796fd3b6 100644 --- a/ports/esp8266/moduos.c +++ b/ports/esp8266/moduos.c @@ -48,7 +48,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { for (int i = 0; i < n; i++) { vstr.buf[i] = *WDEV_HWRNG; } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); diff --git a/ports/mimxrt/moduos.c b/ports/mimxrt/moduos.c index 34bd2b424876..ddb4826db9cf 100644 --- a/ports/mimxrt/moduos.c +++ b/ports/mimxrt/moduos.c @@ -63,7 +63,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { trng_start(); TRNG_GetRandomData(TRNG, vstr.buf, n); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); #endif diff --git a/ports/nrf/modules/machine/spi.c b/ports/nrf/modules/machine/spi.c index 880d946a29f9..81bc151bebd6 100644 --- a/ports/nrf/modules/machine/spi.c +++ b/ports/nrf/modules/machine/spi.c @@ -388,7 +388,7 @@ STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) { vstr_init_len(&vstr, mp_obj_get_int(args[1])); memset(vstr.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, vstr.len); spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read); diff --git a/ports/nrf/modules/uos/moduos.c b/ports/nrf/modules/uos/moduos.c index 184f833ef5df..3fdd8eb19ec1 100644 --- a/ports/nrf/modules/uos/moduos.c +++ b/ports/nrf/modules/uos/moduos.c @@ -108,7 +108,7 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) { for (int i = 0; i < n; i++) { vstr.buf[i] = (uint8_t)(rng_generate_random_word() & 0xFF); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); #endif diff --git a/ports/rp2/moduos.c b/ports/rp2/moduos.c index 6288ff5696e4..398ec28d9210 100644 --- a/ports/rp2/moduos.c +++ b/ports/rp2/moduos.c @@ -35,6 +35,6 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { for (int i = 0; i < n; i++) { vstr.buf[i] = rosc_random_u8(8); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); diff --git a/ports/stm32/moduos.c b/ports/stm32/moduos.c index 1862564b611c..85d0edeca8a1 100644 --- a/ports/stm32/moduos.c +++ b/ports/stm32/moduos.c @@ -58,7 +58,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { for (int i = 0; i < n; i++) { vstr.buf[i] = rng_get(); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); #endif diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 2ca0793c189e..436b1c9bc243 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -926,7 +926,7 @@ STATIC mp_obj_t pyb_i2c_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t * if (o_ret != MP_OBJ_NULL) { return o_ret; } else { - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_recv_obj, 1, pyb_i2c_recv); @@ -1002,7 +1002,7 @@ STATIC mp_obj_t pyb_i2c_mem_read(size_t n_args, const mp_obj_t *pos_args, mp_map if (o_ret != MP_OBJ_NULL) { return o_ret; } else { - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_read_obj, 1, pyb_i2c_mem_read); diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c index abb7ba41db0d..f2cdcebf2a72 100644 --- a/ports/stm32/pyb_spi.c +++ b/ports/stm32/pyb_spi.c @@ -229,7 +229,7 @@ STATIC mp_obj_t pyb_spi_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t * if (o_ret != MP_OBJ_NULL) { return o_ret; } else { - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_recv_obj, 1, pyb_spi_recv); @@ -298,7 +298,7 @@ STATIC mp_obj_t pyb_spi_send_recv(size_t n_args, const mp_obj_t *pos_args, mp_ma if (o_ret != MP_OBJ_NULL) { return o_ret; } else { - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr_recv); + return mp_obj_new_bytes_from_vstr(&vstr_recv); } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_recv_obj, 1, pyb_spi_send_recv); diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 2a669b2a28a8..c5fdd88acfb8 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -813,7 +813,7 @@ STATIC mp_obj_t pyb_usb_vcp_recv(size_t n_args, const mp_obj_t *args, mp_map_t * return mp_obj_new_int(ret); // number of bytes read into given buffer } else { vstr.len = ret; // set actual number of bytes read - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); // create a new buffer + return mp_obj_new_bytes_from_vstr(&vstr); // create a new buffer } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_vcp_recv_obj, 1, pyb_usb_vcp_recv); @@ -1007,7 +1007,7 @@ STATIC mp_obj_t pyb_usb_hid_recv(size_t n_args, const mp_obj_t *args, mp_map_t * return mp_obj_new_int(ret); // number of bytes read into given buffer } else { vstr.len = ret; // set actual number of bytes read - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); // create a new buffer + return mp_obj_new_bytes_from_vstr(&vstr); // create a new buffer } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_hid_recv_obj, 1, pyb_usb_hid_recv); diff --git a/ports/unix/main.c b/ports/unix/main.c index 0b27a1f5f5c8..c388106a645e 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -554,7 +554,7 @@ MP_NOINLINE int main_(int argc, char **argv) { vstr_init(&vstr, home_l + (p1 - p - 1) + 1); vstr_add_strn(&vstr, home, home_l); vstr_add_strn(&vstr, p + 1, p1 - p - 1); - path_items[i] = mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + path_items[i] = mp_obj_new_str_from_vstr(&vstr); } else { path_items[i] = mp_obj_new_str_via_qstr(p, p1 - p); } @@ -650,7 +650,7 @@ MP_NOINLINE int main_(int argc, char **argv) { vstr_init(&vstr, len + sizeof(".__main__")); vstr_add_strn(&vstr, argv[a + 1], len); vstr_add_strn(&vstr, ".__main__", sizeof(".__main__") - 1); - import_args[0] = mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + import_args[0] = mp_obj_new_str_from_vstr(&vstr); goto reimport; } diff --git a/ports/unix/moduos.c b/ports/unix/moduos.c index b577dbd297f7..854ff335faa4 100644 --- a/ports/unix/moduos.c +++ b/ports/unix/moduos.c @@ -94,7 +94,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { vstr_t vstr; vstr_init_len(&vstr, n); mp_hal_get_random(n, vstr.buf); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 69ae2a78ebbb..88e7675a9278 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -559,7 +559,7 @@ STATIC mp_obj_t mod_socket_inet_ntop(mp_obj_t family_in, mp_obj_t binaddr_in) { mp_raise_OSError(errno); } vstr.len = strlen(vstr.buf); - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_socket_inet_ntop_obj, mod_socket_inet_ntop); diff --git a/ports/zephyr/modusocket.c b/ports/zephyr/modusocket.c index 2b6adf477334..17cf9babd333 100644 --- a/ports/zephyr/modusocket.c +++ b/ports/zephyr/modusocket.c @@ -289,7 +289,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { } vstr.len = len; - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index f3caccbc83e1..2459edda13cd 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -250,7 +250,7 @@ STATIC mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) { if (line.len == 0 && ret == CHAR_CTRL_D) { mp_raise_type(&mp_type_EOFError); } - return mp_obj_new_str_from_vstr(&mp_type_str, &line); + return mp_obj_new_str_from_vstr(&line); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 1, mp_builtin_input); @@ -467,7 +467,7 @@ STATIC mp_obj_t mp_builtin_repr(mp_obj_t o_in) { mp_print_t print; vstr_init_print(&vstr, 16, &print); mp_obj_print_helper(&print, o_in, PRINT_REPR); - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr); diff --git a/py/modstruct.c b/py/modstruct.c index 69c7279e370e..ec86d4b9c297 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -220,7 +220,7 @@ STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { byte *p = (byte *)vstr.buf; memset(p, 0, size); struct_pack_into_internal(args[0], p, n_args - 1, &args[1]); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack); diff --git a/py/obj.h b/py/obj.h index 645fae79f566..d171e0fe620e 100644 --- a/py/obj.h +++ b/py/obj.h @@ -791,7 +791,8 @@ mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-prec mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_str(const char *data, size_t len); mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); -mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); +mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr); +mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte *data, size_t len); mp_obj_t mp_obj_new_bytearray(size_t n, const void *items); mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); diff --git a/py/objint.c b/py/objint.c index 740e7ea948df..645b26996689 100644 --- a/py/objint.c +++ b/py/objint.c @@ -446,7 +446,7 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *args) { mp_binary_set_int(l, big_endian, data + (big_endian ? (len - l) : 0), val); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_to_bytes_obj, 3, 4, int_to_bytes); diff --git a/py/objstr.c b/py/objstr.c index 45dbb9b3ebde..69745a2f586a 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -41,6 +41,8 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); +STATIC mp_obj_t mp_obj_new_str_type_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); + STATIC void str_check_arg_type(const mp_obj_type_t *self_type, const mp_obj_t arg) { // String operations generally need the args type to match the object they're called on, // e.g. str.find(str), byte.startswith(byte) @@ -170,7 +172,7 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ mp_print_t print; vstr_init_print(&vstr, 16, &print); mp_obj_print_helper(&print, args[0], PRINT_STR); - return mp_obj_new_str_from_vstr(type, &vstr); + return mp_obj_new_str_type_from_vstr(type, &vstr); } default: // 2 or 3 args @@ -256,7 +258,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size vstr_t vstr; vstr_init_len(&vstr, len); memset(vstr.buf, 0, len); - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); } // check if argument has the buffer protocol @@ -288,7 +290,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size vstr_add_byte(&vstr, val); } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + return mp_obj_new_bytes_from_vstr(&vstr); wrong_args: mp_raise_TypeError(MP_ERROR_TEXT("wrong number of arguments")); @@ -363,7 +365,7 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i vstr_t vstr; vstr_init_len(&vstr, lhs_len * n); mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, vstr.buf); - return mp_obj_new_str_from_vstr(lhs_type, &vstr); + return mp_obj_new_str_type_from_vstr(lhs_type, &vstr); } // From now on all operations allow: @@ -414,7 +416,7 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i vstr_init_len(&vstr, lhs_len + rhs_len); memcpy(vstr.buf, lhs_data, lhs_len); memcpy(vstr.buf + lhs_len, rhs_data, rhs_len); - return mp_obj_new_str_from_vstr(lhs_type, &vstr); + return mp_obj_new_str_type_from_vstr(lhs_type, &vstr); } case MP_BINARY_OP_CONTAINS: @@ -528,7 +530,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { } // return joined string - return mp_obj_new_str_from_vstr(ret_type, &vstr); + return mp_obj_new_str_type_from_vstr(ret_type, &vstr); } MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join); @@ -918,7 +920,7 @@ STATIC mp_obj_t str_center(mp_obj_t str_in, mp_obj_t width_in) { memset(vstr.buf, ' ', width); int left = (width - str_len) / 2; memcpy(vstr.buf + left, str, str_len); - return mp_obj_new_str_from_vstr(mp_obj_get_type(str_in), &vstr); + return mp_obj_new_str_type_from_vstr(mp_obj_get_type(str_in), &vstr); } MP_DEFINE_CONST_FUN_OBJ_2(str_center_obj, str_center); #endif @@ -1144,7 +1146,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar mp_print_t arg_print; vstr_init_print(&arg_vstr, 16, &arg_print); mp_obj_print_helper(&arg_print, arg, print_kind); - arg = mp_obj_new_str_from_vstr(&mp_type_str, &arg_vstr); + arg = mp_obj_new_str_type_from_vstr(&mp_type_str, &arg_vstr); } char fill = '\0'; @@ -1429,7 +1431,7 @@ mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs GET_STR_DATA_LEN(args[0], str, len); int arg_i = 0; vstr_t vstr = mp_obj_str_format_helper((const char *)str, (const char *)str + len, &arg_i, n_args, args, kwargs); - return mp_obj_new_str_from_vstr(mp_obj_get_type(args[0]), &vstr); + return mp_obj_new_str_type_from_vstr(mp_obj_get_type(args[0]), &vstr); } MP_DEFINE_CONST_FUN_OBJ_KW(str_format_obj, 1, mp_obj_str_format); @@ -1634,7 +1636,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ mp_raise_TypeError(MP_ERROR_TEXT("format string didn't convert all arguments")); } - return mp_obj_new_str_from_vstr(is_bytes ? &mp_type_bytes : &mp_type_str, &vstr); + return mp_obj_new_str_type_from_vstr(is_bytes ? &mp_type_bytes : &mp_type_str, &vstr); } #endif @@ -1737,7 +1739,7 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { } } - return mp_obj_new_str_from_vstr(self_type, &vstr); + return mp_obj_new_str_type_from_vstr(self_type, &vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); @@ -1849,7 +1851,7 @@ STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) { for (size_t i = 0; i < self_len; i++) { *data++ = op(*self_data++); } - return mp_obj_new_str_from_vstr(mp_obj_get_type(self_in), &vstr); + return mp_obj_new_str_type_from_vstr(mp_obj_get_type(self_in), &vstr); } STATIC mp_obj_t str_lower(mp_obj_t self_in) { @@ -1988,7 +1990,7 @@ mp_obj_t mp_obj_bytes_hex(size_t n_args, const mp_obj_t *args, const mp_obj_type *out++ = *sep; } } - return mp_obj_new_str_from_vstr(type, &vstr); + return mp_obj_new_str_type_from_vstr(type, &vstr); } mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data) { @@ -2016,7 +2018,7 @@ mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data) { hex_byte = 0; } } - return mp_obj_new_str_from_vstr(MP_OBJ_TO_PTR(type_in), &vstr); + return mp_obj_new_str_type_from_vstr(MP_OBJ_TO_PTR(type_in), &vstr); } STATIC mp_obj_t bytes_hex_as_str(size_t n_args, const mp_obj_t *args) { @@ -2213,7 +2215,7 @@ mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len) { // Create a str/bytes object from the given vstr. The vstr buffer is resized to // the exact length required and then reused for the str/bytes object. The vstr // is cleared and can safely be passed to vstr_free if it was heap allocated. -mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) { +STATIC mp_obj_t mp_obj_new_str_type_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) { // if not a bytes object, look if a qstr with this data already exists if (type == &mp_type_str) { qstr q = qstr_find_strn(vstr->buf, vstr->len); @@ -2245,6 +2247,14 @@ mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) { return MP_OBJ_FROM_PTR(o); } +mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr) { + return mp_obj_new_str_type_from_vstr(&mp_type_str, vstr); +} + +mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr) { + return mp_obj_new_str_type_from_vstr(&mp_type_bytes, vstr); +} + mp_obj_t mp_obj_new_str(const char *data, size_t len) { qstr q = qstr_find_strn(data, len); if (q != MP_QSTRnull) { diff --git a/py/parsenum.c b/py/parsenum.c index 19cc71920140..79765f84f64f 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -160,7 +160,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m mp_printf(&print, "invalid syntax for integer with base %d: ", base); mp_str_print_quoted(&print, str_val_start, top - str_val_start, true); mp_obj_t exc = mp_obj_new_exception_arg1(&mp_type_ValueError, - mp_obj_new_str_from_vstr(&mp_type_str, &vstr)); + mp_obj_new_str_from_vstr(&vstr)); raise_exc(exc, lex); #endif } diff --git a/py/persistentcode.c b/py/persistentcode.c index a8e74295504e..995dedb4569d 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -202,7 +202,11 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { read_bytes(reader, (byte *)vstr.buf, len); if (obj_type == MP_PERSISTENT_OBJ_STR || obj_type == MP_PERSISTENT_OBJ_BYTES) { read_byte(reader); // skip null terminator - return mp_obj_new_str_from_vstr(obj_type == MP_PERSISTENT_OBJ_STR ? &mp_type_str : &mp_type_bytes, &vstr); + if (obj_type == MP_PERSISTENT_OBJ_STR) { + return mp_obj_new_str_from_vstr(&vstr); + } else { + return mp_obj_new_bytes_from_vstr(&vstr); + } } else if (obj_type == MP_PERSISTENT_OBJ_INT) { return mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL); } else { diff --git a/py/stream.c b/py/stream.c index dce64a44dbed..87bed38f6778 100644 --- a/py/stream.c +++ b/py/stream.c @@ -40,8 +40,6 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in); -#define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes) - // Returns error condition in *errcode, if non-zero, return value is number of bytes written // before error condition occurred. If *errcode == 0, returns total bytes written (which will // be equal to input size). @@ -190,7 +188,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl } } - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr(&vstr); } #endif @@ -211,7 +209,11 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl mp_raise_OSError(error); } else { vstr.len = out_sz; - return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); + if (stream_p->is_text) { + return mp_obj_new_str_from_vstr(&vstr); + } else { + return mp_obj_new_bytes_from_vstr(&vstr); + } } } @@ -337,7 +339,11 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) { } vstr.len = total_size; - return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); + if (stream_p->is_text) { + return mp_obj_new_str_from_vstr(&vstr); + } else { + return mp_obj_new_bytes_from_vstr(&vstr); + } } // Unbuffered, inefficient implementation of readline() for raw I/O files. @@ -390,7 +396,11 @@ STATIC mp_obj_t stream_unbuffered_readline(size_t n_args, const mp_obj_t *args) } } - return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); + if (stream_p->is_text) { + return mp_obj_new_str_from_vstr(&vstr); + } else { + return mp_obj_new_bytes_from_vstr(&vstr); + } } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj, 1, 2, stream_unbuffered_readline); From 88864587f5af292d7f86aceb6bf40e8331e9a8d6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 26 Aug 2022 12:54:53 +1000 Subject: [PATCH 1660/4290] py/objstr: Always ensure mp_obj_str_from_vstr is unicode-safe. Now that we have `mp_obj_new_str_type_from_vstr` (private helper used by objstr.c) split from the public API (`mp_obj_new_str_from_vstr`), we can enforce a unicode check at the public API without incurring a performance cost on the various objstr.c methods (which are already working on known unicode-safe strings). Signed-off-by: Jim Mussared --- py/objstr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/py/objstr.c b/py/objstr.c index 69745a2f586a..ab1229ad66a6 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2248,6 +2248,11 @@ STATIC mp_obj_t mp_obj_new_str_type_from_vstr(const mp_obj_type_t *type, vstr_t } mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr) { + #if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK + if (!utf8_check((byte *)vstr->buf, vstr->len)) { + mp_raise_msg(&mp_type_UnicodeError, NULL); + } + #endif // MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK return mp_obj_new_str_type_from_vstr(&mp_type_str, vstr); } From 3a910b15650636efc58bce48cc1bfa0debfd375c Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 23 Aug 2022 18:35:37 +1000 Subject: [PATCH 1661/4290] py/objstr: Optimise mp_obj_new_str_from_vstr for known-safe strings. The new `mp_obj_new_str_from_utf8_vstr` can be used when you know you already have a unicode-safe string. Signed-off-by: Jim Mussared --- extmod/modujson.c | 4 ++-- extmod/modure.c | 2 +- ports/unix/modusocket.c | 2 +- py/modbuiltins.c | 2 +- py/obj.h | 5 +++++ py/objstr.c | 7 +++++++ py/parsenum.c | 2 +- py/persistentcode.c | 2 +- 8 files changed, 19 insertions(+), 7 deletions(-) diff --git a/extmod/modujson.c b/extmod/modujson.c index 57c50deec028..4e992e2245d1 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -67,7 +67,7 @@ STATIC mp_obj_t mod_ujson_dump_helper(size_t n_args, const mp_obj_t *pos_args, m vstr_t vstr; vstr_init_print(&vstr, 8, &print_ext.base); mp_obj_print_helper(&print_ext.base, pos_args[0], PRINT_JSON); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } else { // dump(obj, stream) print_ext.base.data = MP_OBJ_TO_PTR(pos_args[1]); @@ -103,7 +103,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) { mp_print_t print; vstr_init_print(&vstr, 8, &print); mp_obj_print_helper(&print, obj, PRINT_JSON); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); diff --git a/extmod/modure.c b/extmod/modure.c index 59fbfddbf24a..799fef13b1bd 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -373,7 +373,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { vstr_add_strn(&vstr_return, subj.begin, subj.end - subj.begin); if (mp_obj_get_type(where) == &mp_type_str) { - return mp_obj_new_str_from_vstr(&vstr_return); + return mp_obj_new_str_from_utf8_vstr(&vstr_return); } else { return mp_obj_new_bytes_from_vstr(&vstr_return); } diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 88e7675a9278..72c70d1750b5 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -559,7 +559,7 @@ STATIC mp_obj_t mod_socket_inet_ntop(mp_obj_t family_in, mp_obj_t binaddr_in) { mp_raise_OSError(errno); } vstr.len = strlen(vstr.buf); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_socket_inet_ntop_obj, mod_socket_inet_ntop); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 2459edda13cd..f74db95cf5a5 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -467,7 +467,7 @@ STATIC mp_obj_t mp_builtin_repr(mp_obj_t o_in) { mp_print_t print; vstr_init_print(&vstr, 16, &print); mp_obj_print_helper(&print, o_in, PRINT_REPR); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr); diff --git a/py/obj.h b/py/obj.h index d171e0fe620e..0b0a9692ed53 100644 --- a/py/obj.h +++ b/py/obj.h @@ -792,6 +792,11 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a mp_obj_t mp_obj_new_str(const char *data, size_t len); mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr); +#if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK +mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr); // only use when vstr is already known to be utf-8 encoded +#else +#define mp_obj_new_str_from_utf8_vstr mp_obj_new_str_from_vstr +#endif mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte *data, size_t len); mp_obj_t mp_obj_new_bytearray(size_t n, const void *items); diff --git a/py/objstr.c b/py/objstr.c index ab1229ad66a6..5a62237516c3 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2256,6 +2256,13 @@ mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr) { return mp_obj_new_str_type_from_vstr(&mp_type_str, vstr); } +#if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK +mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr) { + // bypasses utf8_check. + return mp_obj_new_str_type_from_vstr(&mp_type_str, vstr); +} +#endif // MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK + mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr) { return mp_obj_new_str_type_from_vstr(&mp_type_bytes, vstr); } diff --git a/py/parsenum.c b/py/parsenum.c index 79765f84f64f..d59715fdc937 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -160,7 +160,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m mp_printf(&print, "invalid syntax for integer with base %d: ", base); mp_str_print_quoted(&print, str_val_start, top - str_val_start, true); mp_obj_t exc = mp_obj_new_exception_arg1(&mp_type_ValueError, - mp_obj_new_str_from_vstr(&vstr)); + mp_obj_new_str_from_utf8_vstr(&vstr)); raise_exc(exc, lex); #endif } diff --git a/py/persistentcode.c b/py/persistentcode.c index 995dedb4569d..82ef0c49953f 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -203,7 +203,7 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { if (obj_type == MP_PERSISTENT_OBJ_STR || obj_type == MP_PERSISTENT_OBJ_BYTES) { read_byte(reader); // skip null terminator if (obj_type == MP_PERSISTENT_OBJ_STR) { - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } else { return mp_obj_new_bytes_from_vstr(&vstr); } From 6c3d8d38bfbe24c3d810f89f546ac947cf0cb66d Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 24 Aug 2022 12:22:57 +1000 Subject: [PATCH 1662/4290] py/objstr: Always validate utf-8 for mp_obj_new_str. All uses of this are either tiny strings or not-known-to-be-safe. Update comments for mp_obj_new_str_copy and mp_obj_new_str_of_type. Signed-off-by: Jim Mussared --- py/obj.h | 8 ++++---- py/objstr.c | 11 ++++++----- py/objstr.h | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/py/obj.h b/py/obj.h index 0b0a9692ed53..e048cf0c286a 100644 --- a/py/obj.h +++ b/py/obj.h @@ -789,11 +789,11 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value); mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base); mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception) -mp_obj_t mp_obj_new_str(const char *data, size_t len); -mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); -mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr); +mp_obj_t mp_obj_new_str(const char *data, size_t len); // will check utf-8 (raises UnicodeError) +mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); // input data must be valid utf-8 +mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr); // will check utf-8 (raises UnicodeError) #if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK -mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr); // only use when vstr is already known to be utf-8 encoded +mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr); // input data must be valid utf-8 #else #define mp_obj_new_str_from_utf8_vstr mp_obj_new_str_from_vstr #endif diff --git a/py/objstr.c b/py/objstr.c index 5a62237516c3..683d035e4409 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -202,11 +202,7 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ } else { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); - #if MICROPY_PY_BUILTINS_STR_UNICODE_CHECK - if (!utf8_check(bufinfo.buf, bufinfo.len)) { - mp_raise_msg(&mp_type_UnicodeError, NULL); - } - #endif + // This will utf-8 check the input. return mp_obj_new_str(bufinfo.buf, bufinfo.len); } } @@ -2268,6 +2264,11 @@ mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr) { } mp_obj_t mp_obj_new_str(const char *data, size_t len) { + #if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK + if (!utf8_check((byte *)data, len)) { + mp_raise_msg(&mp_type_UnicodeError, NULL); + } + #endif qstr q = qstr_find_strn(data, len); if (q != MP_QSTRnull) { // qstr with this data already exists diff --git a/py/objstr.h b/py/objstr.h index 78441fedaf2c..6c6735bf5efa 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -88,8 +88,8 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t void mp_str_print_json(const mp_print_t *print, const byte *str_data, size_t str_len); mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args); -mp_obj_t mp_obj_new_str_copy(const mp_obj_type_t *type, const byte *data, size_t len); -mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte *data, size_t len); +mp_obj_t mp_obj_new_str_copy(const mp_obj_type_t *type, const byte *data, size_t len); // for type=str, input data must be valid utf-8 +mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte *data, size_t len); // for type=str, will check utf-8 (raises UnicodeError) mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in); mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); From bd4e45fd68e20af3f965b403e643fa5f71aa1b08 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 24 Aug 2022 12:42:45 +1000 Subject: [PATCH 1663/4290] tests/unicode: Add test for invalid utf-8 file contents. Signed-off-by: Jim Mussared --- tests/unicode/data/utf-8_invalid.txt | 1 + tests/unicode/file_invalid.py | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 tests/unicode/data/utf-8_invalid.txt create mode 100644 tests/unicode/file_invalid.py diff --git a/tests/unicode/data/utf-8_invalid.txt b/tests/unicode/data/utf-8_invalid.txt new file mode 100644 index 000000000000..50020482bf6e --- /dev/null +++ b/tests/unicode/data/utf-8_invalid.txt @@ -0,0 +1 @@ +aaÿbb diff --git a/tests/unicode/file_invalid.py b/tests/unicode/file_invalid.py new file mode 100644 index 000000000000..3f7f1840629f --- /dev/null +++ b/tests/unicode/file_invalid.py @@ -0,0 +1,5 @@ +try: + f = open("unicode/data/utf-8_invalid.txt", encoding="utf-8") + f.read() +except UnicodeError: + print("UnicodeError") From d521899e18c305a4cf3870449e3dd12308f7a806 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 17 Aug 2022 08:43:17 +1000 Subject: [PATCH 1664/4290] py/persistentcode: Clarify ValueError when native emitter disabled. --- py/persistentcode.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/py/persistentcode.c b/py/persistentcode.c index 82ef0c49953f..1b1741f2614e 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -402,7 +402,13 @@ mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t * if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE) { byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); if (!MPY_FEATURE_ARCH_TEST(arch)) { - mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy arch")); + if (MPY_FEATURE_ARCH_TEST(MP_NATIVE_ARCH_NONE)) { + // On supported ports this can be resolved by enabling feature, eg + // mpconfigboard.h: MICROPY_EMIT_THUMB (1) + mp_raise_ValueError(MP_ERROR_TEXT("native code in .mpy unsupported")); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy arch")); + } } } From 9a826e0f24add1b7e719e915e0d4dde1c14b416e Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 26 Jul 2022 18:48:06 +1000 Subject: [PATCH 1665/4290] lib/lwip: Update lwIP to v2.1.3, tag STABLE-2_1_3_RELEASE. There don't seem to be many changes going from v2.1.2 to v2.1.3 of lwIP. Mostly they are: - IPv6 fixes and improvements - changes to apps and other code that MicroPython doesn't use - comments and tests - minor bug fixes In particular there doesn't look to be any change to the API of any function used by MicroPython. Network multi tests pass on PYBD_SF2 and PYBD_SF6. PYBD_SF2, PYBD_SF6 and PICO_W have unchanged iperf3 performance. Similar results for networking on the mimxrt port. Signed-off-by: Damien George --- lib/lwip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lwip b/lib/lwip index 159e31b68957..6ca936f6b588 160000 --- a/lib/lwip +++ b/lib/lwip @@ -1 +1 @@ -Subproject commit 159e31b689577dbf69cf0683bbaffbd71fa5ee10 +Subproject commit 6ca936f6b588cee702c638eee75c2436e6cf75de From 730e97509117ea9c8b527857c25f8a2bf04ecd86 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 30 Aug 2022 11:14:32 +1000 Subject: [PATCH 1666/4290] esp32/boards: Merge manifest_release modules into standard manifest. Having two separate manifests is confusing. It's simpler to have the daily builds use the same configuration as the stable, release builds. Signed-off-by: Damien George --- ports/esp32/boards/manifest.py | 6 ++++++ ports/esp32/boards/manifest_release.py | 7 ------- tools/autobuild/build-boards.sh | 7 +------ 3 files changed, 7 insertions(+), 13 deletions(-) delete mode 100644 ports/esp32/boards/manifest_release.py diff --git a/ports/esp32/boards/manifest.py b/ports/esp32/boards/manifest.py index f0ed38b515c7..23252442ea46 100644 --- a/ports/esp32/boards/manifest.py +++ b/ports/esp32/boards/manifest.py @@ -6,3 +6,9 @@ include("$(MPY_DIR)/extmod/uasyncio/manifest.py") include("$(MPY_DIR)/extmod/webrepl/manifest.py") include("$(MPY_DIR)/drivers/neopixel/manifest.py") + +# Freeze some micropython-lib modules. +freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") +freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") diff --git a/ports/esp32/boards/manifest_release.py b/ports/esp32/boards/manifest_release.py deleted file mode 100644 index 8b9bcde6ffa7..000000000000 --- a/ports/esp32/boards/manifest_release.py +++ /dev/null @@ -1,7 +0,0 @@ -include("manifest.py") - -freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") - -freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") -freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") -freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") diff --git a/tools/autobuild/build-boards.sh b/tools/autobuild/build-boards.sh index b3d2f8c4c55a..48c7b81841aa 100755 --- a/tools/autobuild/build-boards.sh +++ b/tools/autobuild/build-boards.sh @@ -83,12 +83,7 @@ function build_esp32_boards { if idf.py --version | grep -q v4.2; then if [ $mcu = esp32 ]; then # build standard esp32-based boards with IDF v4.2 - if echo $board_json | grep -q GENERIC; then - # traditionally, GENERIC and GENERIC_SPIRAM boards used manifest_release.py - MICROPY_AUTOBUILD_MAKE="$MICROPY_AUTOBUILD_MAKE FROZEN_MANIFEST=$(pwd)/boards/manifest_release.py" build_board $board_json $fw_tag $dest_dir bin elf map - else - build_board $board_json $fw_tag $dest_dir bin elf map - fi + build_board $board_json $fw_tag $dest_dir bin elf map fi else if [ $mcu != esp32 ]; then From d108fc9c4793e1846b2ddfad925fb17bbc44cd51 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 30 Aug 2022 11:18:08 +1000 Subject: [PATCH 1667/4290] esp32/machine_sdcard: Free SPI bus when deiniting SD card. So that everything is reset and the SD card can be created again after calling SDCard.deinit() (and after a soft reset). Fixes issue #8949. Signed-off-by: Damien George --- ports/esp32/machine_sdcard.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/esp32/machine_sdcard.c b/ports/esp32/machine_sdcard.c index 82c2e6cd4e32..3f94356adbb4 100644 --- a/ports/esp32/machine_sdcard.c +++ b/ports/esp32/machine_sdcard.c @@ -283,6 +283,10 @@ STATIC mp_obj_t sd_deinit(mp_obj_t self_in) { { self->host.deinit(); } + if (self->host.flags & SDMMC_HOST_FLAG_SPI) { + // SD card used a (dedicated) SPI bus, so free that SPI bus. + spi_bus_free(self->host.slot); + } self->flags &= ~SDCARD_CARD_FLAGS_HOST_INIT_DONE; } From 64c62f8cf162e56cf4c6049f4a65c3d5e18556ae Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 24 Aug 2022 23:47:58 +1000 Subject: [PATCH 1668/4290] README: Simplify and update, and move unix section to separate file. Changes are: - Remove unix- and stm32-specific sections (move unix to its own README.md), stm32 was duplicated. - Add links to GitHub Discussions and Discord. - Update information about the project. - Add a getting started section. - Explain `make submodules`. Signed-off-by: Jim Mussared Signed-off-by: Damien George --- README.md | 262 ++++++++++++++++++------------------------- ports/unix/README.md | 70 ++++++++++++ 2 files changed, 181 insertions(+), 151 deletions(-) create mode 100644 ports/unix/README.md diff --git a/README.md b/README.md index 6941102f0ac4..6482899b251d 100644 --- a/README.md +++ b/README.md @@ -15,174 +15,134 @@ code-base, including project-wide name changes and API changes. MicroPython implements the entire Python 3.4 syntax (including exceptions, `with`, `yield from`, etc., and additionally `async`/`await` keywords from -Python 3.5). The following core datatypes are provided: `str` (including -basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`, -`frozenset`, `array.array`, `collections.namedtuple`, classes and instances. -Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have -support for `_thread` module (multithreading). Note that only a subset of -Python 3 functionality is implemented for the data types and modules. - -MicroPython can execute scripts in textual source form or from precompiled -bytecode, in both cases either from an on-device filesystem or "frozen" into -the MicroPython executable. - -See the repository http://github.com/micropython/pyboard for the MicroPython -board (PyBoard), the officially supported reference electronic circuit board. - -Major components in this repository: -- py/ -- the core Python implementation, including compiler, runtime, and +Python 3.5 and some select features from later versions). The following core +datatypes are provided: `str`(including basic Unicode support), `bytes`, +`bytearray`, `tuple`, `list`, `dict`, `set`, `frozenset`, `array.array`, +`collections.namedtuple`, classes and instances. Builtin modules include +`os`, `sys`, `time`, `re`, and `struct`, etc. Select ports have support for +`_thread` module (multithreading), `socket` and `ssl` for networking, and +`asyncio`. Note that only a subset of Python 3 functionality is implemented +for the data types and modules. + +MicroPython can execute scripts in textual source form (.py files) or from +precompiled bytecode (.mpy files), in both cases either from an on-device +filesystem or "frozen" into the MicroPython executable. + +MicroPython also provides a set of MicroPython-specific modules to access +hardware-specific functionality and peripherals such as GPIO, Timers, ADC, +DAC, PWM, SPI, I2C, CAN, Bluetooth, and USB. + +Getting started +--------------- + +See the [online documentation](https://docs.micropython.org/) for API +references and information about using MicroPython and information about how +it is implemented. + +We use [GitHub Discussions](https://github.com/micropython/micropython/discussions) +as our forum, and [Discord](https://discord.gg/RB8HZSAExQ) for chat. These +are great places to ask questions and advice from the community or to discuss your +MicroPython-based projects. + +For bugs and feature requests, please [raise an issue](https://github.com/micropython/micropython/issues/new/choose) +and follow the templates there. + +For information about the [MicroPython pyboard](https://store.micropython.org/pyb-features), +the officially supported board from the +[original Kickstarter campaign](https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers), +see the [schematics and pinouts](http://github.com/micropython/pyboard) and +[documentation](https://docs.micropython.org/en/latest/pyboard/quickref.html). + +Contributing +------------ + +MicroPython is an open-source project and welcomes contributions. To be +productive, please be sure to follow the +[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines) +and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md). +Note that MicroPython is licenced under the MIT license, and all contributions +should follow this license. + +About this repository +--------------------- + +This repository contains the following components: +- [py/](py/) -- the core Python implementation, including compiler, runtime, and core library. -- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts +- [mpy-cross/](mpy-cross/) -- the MicroPython cross-compiler which is used to turn scripts into precompiled bytecode. -- ports/unix/ -- a version of MicroPython that runs on Unix. -- ports/stm32/ -- a version of MicroPython that runs on the PyBoard and similar - STM32 boards (using ST's Cube HAL drivers). -- ports/minimal/ -- a minimal MicroPython port. Start with this if you want - to port MicroPython to another microcontroller. -- tests/ -- test framework and test scripts. -- docs/ -- user documentation in Sphinx reStructuredText format. Rendered - HTML documentation is available at http://docs.micropython.org. - -Additional components: -- ports/bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used - mostly to control code size. -- ports/teensy/ -- a version of MicroPython that runs on the Teensy 3.1 - (preliminary but functional). -- ports/pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers. -- ports/cc3200/ -- a version of MicroPython that runs on the CC3200 from TI. -- ports/esp8266/ -- a version of MicroPython that runs on Espressif's ESP8266 SoC. -- ports/esp32/ -- a version of MicroPython that runs on Espressif's ESP32 SoC. -- ports/nrf/ -- a version of MicroPython that runs on Nordic's nRF51 and nRF52 MCUs. -- extmod/ -- additional (non-core) modules implemented in C. -- tools/ -- various tools, including the pyboard.py module. -- examples/ -- a few example Python scripts. - -The subdirectories above may include READMEs with additional info. +- [ports/](ports/) -- platform-specific code for the various ports and architectures that MicroPython runs on. +- [lib/](lib/) -- submodules for external dependencies. +- [tests/](tests/) -- test framework and test scripts. +- [docs/](docs/) -- user documentation in Sphinx reStructuredText format. This is used to generate the [online documentation](http://docs.micropython.org). +- [extmod/](extmod/) -- additional (non-core) modules implemented in C. +- [tools/](tools/) -- various tools, including the pyboard.py module. +- [examples/](examples/) -- a few example Python scripts. "make" is used to build the components, or "gmake" on BSD-based systems. You will also need bash, gcc, and Python 3.3+ available as the command `python3` (if your system only has Python 2.7 then invoke make with the additional option -`PYTHON=python2`). +`PYTHON=python2`). Some ports (rp2 and esp32) additionally use CMake. + +Supported platforms & architectures +----------------------------------- + +MicroPython runs on a wide range of microcontrollers, as well as on Unix-like +(including Linux, BSD, macOS, WSL) and Windows systems. + +Microcontroller targets can be as small as 256kiB flash + 16kiB RAM, although +devices with at least 512kiB flash + 128kiB RAM allow a much more +full-featured experience. + +The [Unix](ports/unix) and [Windows](ports/windows) ports allow both +development and testing of MicroPython itself, as well as providing +lightweight alternative to CPython on these platforms (in particular on +embedded Linux systems). + +The ["minimal"](ports/minimal) port provides an example of a very basic +MicroPython port and can be compiled as both a standalone Linux binary as +well as for ARM Cortex M4. Start with this if you want to port MicroPython to +another microcontroller. Additionally the ["bare-arm"](ports/bare-arm) port +is an example of the absolute minimum configuration, and is used to keep +track of the code size of the core runtime and VM. + +In addition, the following ports are provided in this repository: + - [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy). + - [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3). + - [esp8266](ports/esp8266) -- Espressif ESP8266 SoC. + - [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x). + - [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52. + - [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit. + - [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt) + - [qemu-arm](ports/qemu-arm) -- QEMU-based emulated target, for testing) + - [renesas-ra](ports/renesas-ra) -- Renesas RA family. + - [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W). + - [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51. + - [stm32](ports/stm32) -- STMicroelectronics STM32 family (including F0, F4, F7, G0, G4, H7, L0, L4, WB) + - [teensy](ports/teensy) -- Teensy 3.x. + - [webassembly](ports/webassembly) -- Emscripten port targeting browsers and NodeJS. + - [zephyr](ports/zephyr) -- Zephyr RTOS. The MicroPython cross-compiler, mpy-cross ----------------------------------------- -Most ports require the MicroPython cross-compiler to be built first. This -program, called mpy-cross, is used to pre-compile Python scripts to .mpy -files which can then be included (frozen) into the firmware/executable for -a port. To build mpy-cross use: +Most ports require the [MicroPython cross-compiler](mpy-cross) to be built +first. This program, called mpy-cross, is used to pre-compile Python scripts +to .mpy files which can then be included (frozen) into the +firmware/executable for a port. To build mpy-cross use: $ cd mpy-cross $ make -The Unix version ----------------- - -The "unix" port requires a standard Unix environment with gcc and GNU make. -x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well -as ARM and MIPS. Making full-featured port to another architecture requires -writing some assembly code for the exception handling and garbage collection. -Alternatively, fallback implementation based on setjmp/longjmp can be used. - -To build (see section below for required dependencies): - - $ cd ports/unix - $ make submodules - $ make - -Then to give it a try: - - $ ./micropython - >>> list(5 * x + y for x in range(10) for y in [4, 2, 1]) - -Use `CTRL-D` (i.e. EOF) to exit the shell. -Learn about command-line options (in particular, how to increase heap size -which may be needed for larger applications): - - $ ./micropython -h - -Run complete testsuite: - - $ make test - -Unix version comes with a builtin package manager called upip, e.g.: - - $ ./micropython -m upip install micropython-pystone - $ ./micropython -m pystone - -Browse available modules on -[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython). -Standard library modules come from -[micropython-lib](https://github.com/micropython/micropython-lib) project. - External dependencies --------------------- -Building MicroPython ports may require some dependencies installed. - -For Unix port, `libffi` library and `pkg-config` tool are required. On -Debian/Ubuntu/Mint derivative Linux distros, install `build-essential` -(includes toolchain and make), `libffi-dev`, and `pkg-config` packages. - -Other dependencies can be built together with MicroPython. This may -be required to enable extra features or capabilities, and in recent -versions of MicroPython, these may be enabled by default. To build -these additional dependencies, in the port directory you're -interested in (e.g. `ports/unix/`) first execute: +The core MicroPython VM and runtime has no external dependencies, but a given +port might depend on third-party drivers or vendor HALs. This repository +includes [several submodules](lib/) linking to these external dependencies. +Before compiling a given port, use + $ cd ports/name $ make submodules -This will fetch all the relevant git submodules (sub repositories) that -the port needs. Use the same command to get the latest versions of -submodules as they are updated from time to time. After that execute: - - $ make deplibs - -This will build all available dependencies (regardless whether they -are used or not). If you intend to build MicroPython with additional -options (like cross-compiling), the same set of options should be passed -to `make deplibs`. To actually enable/disable use of dependencies, edit -`ports/unix/mpconfigport.mk` file, which has inline descriptions of the options. -For example, to build SSL module (required for `upip` tool described above, -and so enabled by default), `MICROPY_PY_USSL` should be set to 1. - -For some ports, building required dependences is transparent, and happens -automatically. But they still need to be fetched with the `make submodules` -command. - -The STM32 version ------------------ - -The "stm32" port requires an ARM compiler, arm-none-eabi-gcc, and associated -bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils, -arm-none-eabi-gcc and arm-none-eabi-newlib packages. Otherwise, try here: -https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads - -To build: - - $ cd ports/stm32 - $ make submodules - $ make - -You then need to get your board into DFU mode. On the pyboard, connect the -3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other -on the bottom left of the board, second row from the bottom). - -Then to flash the code via USB DFU to your device: - - $ make deploy - -This will use the included `tools/pydfu.py` script. If flashing the firmware -does not work it may be because you don't have the correct permissions, and -need to use `sudo make deploy`. -See the README.md file in the ports/stm32/ directory for further details. - -Contributing ------------- - -MicroPython is an open-source project and welcomes contributions. To be -productive, please be sure to follow the -[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines) -and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md). -Note that MicroPython is licenced under the MIT license, and all contributions -should follow this license. +to ensure that all required submodules are initialised. diff --git a/ports/unix/README.md b/ports/unix/README.md new file mode 100644 index 000000000000..efc68b2455f9 --- /dev/null +++ b/ports/unix/README.md @@ -0,0 +1,70 @@ +The Unix version +---------------- + +The "unix" port requires a standard Unix-like environment with gcc and GNU +make. This includes Linux, BSD, macOS, and Windows Subsystem for Linux. The +x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well as +ARM and MIPS. Making a full-featured port to another architecture requires +writing some assembly code for the exception handling and garbage collection. +Alternatively, a fallback implementation based on setjmp/longjmp can be used. + +To build (see section below for required dependencies): + + $ cd ports/unix + $ make submodules + $ make + +Then to give it a try: + + $ ./build-standard/micropython + >>> list(5 * x + y for x in range(10) for y in [4, 2, 1]) + +Use `CTRL-D` (i.e. EOF) to exit the shell. + +Learn about command-line options (in particular, how to increase heap size +which may be needed for larger applications): + + $ ./micropython -h + +To run the complete testsuite, use: + + $ make test + +The Unix port comes with a builtin package manager called upip, e.g.: + + $ ./micropython -m upip install micropython-pystone + $ ./micropython -m pystone + +Browse available modules on +[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython). +Standard library modules come from the +[micropython-lib](https://github.com/micropython/micropython-lib) project. + +External dependencies +--------------------- + +The `libffi` library and `pkg-config` tool are required. On Debian/Ubuntu/Mint +derivative Linux distros, install `build-essential`(includes toolchain and +make), `libffi-dev`, and `pkg-config` packages. + +Other dependencies can be built together with MicroPython. This may +be required to enable extra features or capabilities, and in recent +versions of MicroPython, these may be enabled by default. To build +these additional dependencies, in the unix port directory first execute: + + $ make submodules + +This will fetch all the relevant git submodules (sub repositories) that +the port needs. Use the same command to get the latest versions of +submodules as they are updated from time to time. After that execute: + + $ make deplibs + +This will build all available dependencies (regardless whether they are used +or not). If you intend to build MicroPython with additional options +(like cross-compiling), the same set of options should be passed to `make +deplibs`. To actually enable/disable use of dependencies, edit the +`ports/unix/mpconfigport.mk` file, which has inline descriptions of the +options. For example, to build SSL module (required for the `upip` tool +described above, and so enabled by default), `MICROPY_PY_USSL` should be set +to 1. From 316008046a689b59e7a521c811d6e381bd03fb5a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 25 Aug 2022 15:03:38 +1000 Subject: [PATCH 1669/4290] github/ISSUE_TEMPLATE: Replace forum with Discussions. Signed-off-by: Jim Mussared Signed-off-by: Damien George --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/config.yml | 4 ++-- .github/ISSUE_TEMPLATE/documentation.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ac9d97041a50..7bad9562964a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,7 +7,7 @@ assignees: '' --- -* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please see the MicroPython Forum (https://forum.micropython.org/) or raise a documentation request instead. +* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please use the Discussions tab or raise a documentation request instead. * In your issue, please include a clear and concise description of what the bug is, the expected output, and how to replicate it. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 318d9416ee74..f3662464da33 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,7 @@ blank_issues_enabled: false contact_links: - - name: MicroPython Forum - url: https://forum.micropython.org/ + - name: MicroPython GitHub Discussions + url: https://github.com/orgs/micropython/discussions about: Community discussion about all things MicroPython. This is the best place to start if you have questions about using MicroPython or getting started with MicroPython development. - name: MicroPython Documentation url: https://docs.micropython.org/ diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md index c86c1ec2b8ed..e36fa62ac29a 100644 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -7,7 +7,7 @@ assignees: '' --- -* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please see the MicroPython Forum -- https://forum.micropython.org/ +* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please use the Discussions tab instead. * Describe what was missing from the documentation and/or what was incorrect/incomplete. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 3976699b28ed..81b55d98e0da 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,7 +7,7 @@ assignees: '' --- -* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please see the MicroPython Forum (https://forum.micropython.org/) or raise a documentation request instead. +* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please use the Discussions tab or raise a documentation request instead. * Describe the feature you'd like to see added to MicroPython. In particular, what does this feature enable and why is it useful. MicroPython aims to strike a balance between functionality and code size, so please consider whether this feature can be optionally enabled and whether it can be provided in other ways (e.g. pure-Python library). From 31d7ab327b0da4fe7747aba5590a542b88caa123 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 25 Aug 2022 15:03:56 +1000 Subject: [PATCH 1670/4290] docs/templates/topindex.html: Update forum link. Signed-off-by: Jim Mussared --- docs/templates/topindex.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templates/topindex.html b/docs/templates/topindex.html index 41bcc740dd91..cfe3ad1516ac 100644 --- a/docs/templates/topindex.html +++ b/docs/templates/topindex.html @@ -119,7 +119,7 @@

MicroPython documentation

the official MicroPython site

From 53ebbf10e56dd4cc33aec6cc6d0590c66fd1948e Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 27 Aug 2022 10:42:15 +0200 Subject: [PATCH 1671/4290] docs/library/machine.I2C: Add a note about I2C pull-up resistors. Quite regularly users complain about unexpected behavior of I2C, calling it a bug, when in fact the trouble is caused by missing pull-up resistors. So this commit adds a note to the documentation, in the slim hope that people will find and read it. --- docs/library/machine.I2C.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst index 82a88390c3fb..2a33b1da47a3 100644 --- a/docs/library/machine.I2C.rst +++ b/docs/library/machine.I2C.rst @@ -20,6 +20,17 @@ Software I2C is implemented by bit-banging and can be used on any pin but is not as efficient. These classes have the same methods available and differ primarily in the way they are constructed. +.. Note:: + + The I2C bus requires pull-up circuitry on both SDA and SCL for it's operation. + Usually these are resistors in the range of 1 - 10 kOhm, connected from each SDA/SCL + to Vcc. Without these, the behaviour is undefined and may range from blocking, + unexpected watchdog reset to just wrong values. Often, this pull-up circuitry + is built-in already to the MCU board or sensor breakout boards, but there is + no rule for that. So please check in case of trouble. See also this excellent + `learning guide `_ + by Adafruit about I2C wiring. + Example usage:: from machine import I2C From 2488311dc2f5ef259a03b871620fd6d3f45a1086 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 12:47:34 +0200 Subject: [PATCH 1672/4290] rp2/machine_uart: Implement uart.flush() and uart.txdone(). uart.flush() flush() will wait until all characters have been sent. It may return while the last character is sent. if needed, the calling code has to add one character wait time. To avoid a permanent lock, a timeout applies depending on the size of txbuf and the baud rate. ret = uart.txdone() ret is True if no transfer is in progress. It may return True if the last byte of a transfer is sent. ret is False otherwise. --- ports/rp2/machine_uart.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index 77ccdb5f50f2..f7e44b6b256c 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -435,17 +435,31 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak); +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (ringbuf_avail(&self->write_buffer) == 0 && + uart_get_hw(self->uart)->fr & UART_UARTFR_TXFE_BITS) { + return mp_const_true; + } else { + return mp_const_false; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) }, { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) }, @@ -538,6 +552,19 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint if ((flags & MP_STREAM_POLL_WR) && ringbuf_free(&self->write_buffer) > 0) { ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // The timeout is estimated using the buffer size and the baudrate. + // Take the worst case assumptions at 13 bit symbol size times 2. + uint64_t timeout = time_us_64() + + (uint64_t)(33 + self->write_buffer.size) * 13000000ll * 2 / self->baudrate; + do { + if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) { + return 0; + } + MICROPY_EVENT_POLL_HOOK + } while (time_us_64() < timeout); + *errcode = MP_ETIMEDOUT; + ret = MP_STREAM_ERROR; } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; From 5466f1b0ea562548cd11cdbe31b5f71c97cf36f9 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 15:21:48 +0200 Subject: [PATCH 1673/4290] esp32/machine_uart: Implement uart.flush() and uart.txdone(). uart.flush() flush() will wait until all characters have been sent.To avoid a permanent lock, a timeout applies depending on the size of txbuf and the baud rate. ret = uart.txdone() ret is True if no transfer is in progress. ret is False otherwise. --- ports/esp32/machine_uart.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 28110e39f378..72445912897f 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -417,15 +417,28 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak); +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (uart_wait_tx_done(self->uart_num, 0) == ESP_OK) { + return mp_const_true; + } else { + return mp_const_false; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INV_TX) }, { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INV_RX) }, @@ -491,6 +504,18 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr if ((flags & MP_STREAM_POLL_WR) && 1) { // FIXME: uart_tx_any_room(self->uart_num) ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // The timeout is estimated using the buffer size and the baudrate. + // Take the worst case assumptions at 13 bit symbol size times 2. + uint32_t baudrate; + uart_get_baudrate(self->uart_num, &baudrate); + uint32_t timeout = (3 + self->txbuf) * 13000 * 2 / baudrate; + if (uart_wait_tx_done(self->uart_num, timeout) == ESP_OK) { + ret = 0; + } else { + *errcode = MP_ETIMEDOUT; + ret = MP_STREAM_ERROR; + } } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; From 49e17c8bb0c55d8efb3f768ba1dfd5b27c466b26 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 15:49:59 +0200 Subject: [PATCH 1674/4290] mimxrt/machine_uart: Implement uart.flush() and uart.txdone(). uart.flush() flush() will wait until all characters have been sent.To avoid a permanent lock, a timeout applies depending on the size of txbuf and the baud rate. ret = uart.txdone() ret is True if no transfer is in progress. ret is False otherwise. --- ports/mimxrt/machine_uart.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index 115d9226bf8b..302244f7221f 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -308,17 +308,30 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak); +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->tx_status == kStatus_LPUART_TxIdle) { + return mp_const_true; + } else { + return mp_const_false; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) }, { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) }, { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) }, @@ -433,6 +446,21 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint if ((flags & MP_STREAM_POLL_WR)) { ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // The timeout is estimated using the buffer size and the baudrate. + // Take the worst case assumptions at 13 bit symbol size times 2. + uint64_t timeout = (uint64_t)(3 + self->txbuf_len) * 13000000ll * 2 / + self->config.baudRate_Bps + ticks_us64(); + + do { + if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) { + return 0; + } + MICROPY_EVENT_POLL_HOOK + } while (ticks_us64() < timeout); + + *errcode = MP_ETIMEDOUT; + ret = MP_STREAM_ERROR; } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; From 8804993d0f5326fd71f137433a1b52199d65f119 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 16:42:10 +0200 Subject: [PATCH 1675/4290] esp8266/machine_uart: Implement uart.flush() and uart.txdone(). uart.flush() flush() will wait until all characters but the last one have been sent. It returns while the last character is sent. If needed, the calling code has to add one character wait time. To avoid a permanent lock, a timeout applies depending on the size of the FIFO and the baud rate. ret = uart.txdone() ret is True if no transfer is in progress. It returns already True when the last byte of a transfer is sent. ret is False otherwise. --- ports/esp8266/machine_uart.c | 24 ++++++++++++++++++++++++ ports/esp8266/uart.c | 9 +++++++++ ports/esp8266/uart.h | 1 + 3 files changed, 34 insertions(+) diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index 4e88eee162d8..2fe6516dc7ce 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -231,10 +231,20 @@ STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any); +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return uart_txdone(self->uart_id) == true ? mp_const_true : mp_const_false; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) }, { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, + + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, @@ -305,6 +315,20 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a if ((flags & MP_STREAM_POLL_WR) && uart_tx_any_room(self->uart_id)) { ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // The timeout is estimated using the buffer size and the baudrate. + // Take the worst case assumptions at 13 bit symbol size times 2. + uint64_t timeout = (uint64_t)(3 + 127) * 13000000ll * 2 / self->baudrate + + system_get_time(); + do { + if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) { + return 0; + } + MICROPY_EVENT_POLL_HOOK + } while (system_get_time() < timeout); + + *errcode = MP_ETIMEDOUT; + ret = MP_STREAM_ERROR; } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; diff --git a/ports/esp8266/uart.c b/ports/esp8266/uart.c index 978a7efc38ed..117cd1bf6c93 100644 --- a/ports/esp8266/uart.c +++ b/ports/esp8266/uart.c @@ -111,6 +111,15 @@ void uart_tx_one_char(uint8 uart, uint8 TxChar) { WRITE_PERI_REG(UART_FIFO(uart), TxChar); } +int uart_txdone(uint8 uart) { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) { + return true; + } else { + return false; + } +} + void uart_flush(uint8 uart) { while (true) { uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); diff --git a/ports/esp8266/uart.h b/ports/esp8266/uart.h index de0919bde056..3c5592ff0aa8 100644 --- a/ports/esp8266/uart.h +++ b/ports/esp8266/uart.h @@ -101,6 +101,7 @@ bool uart_rx_wait(uint32_t timeout_us); int uart_rx_char(void); void uart_tx_one_char(uint8 uart, uint8 TxChar); void uart_flush(uint8 uart); +int uart_txdone(uint8 uart); void uart_os_config(int uart); void uart_setup(uint8 uart); int uart0_get_rxbuf_len(void); From 8ea6fefc6d52ae46199a337064c05431f6dd30cb Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 17:04:23 +0200 Subject: [PATCH 1676/4290] stm32/machine_uart: Implement uart.flush() and uart.txdone(). Since uart.write() of the STM32 port waits until all bytes have been sent, uart.flush() and uart.txdone() are implemented as empty functions to provide API consistency. uart.flush() flush() will always return immediately. ret = uart.txdone() uart.txdone() will always return True. --- ports/stm32/machine_uart.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index bf7bcfb9cd35..1bb1d2a1a784 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -523,6 +523,12 @@ STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t * } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq); +// Since uart.write() waits up to the last byte, uart.txdone() always returns True. +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + return mp_const_true; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { // instance methods @@ -538,11 +544,13 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, /// \method write(buf) { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&pyb_uart_irq_obj) }, { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&pyb_uart_writechar_obj) }, { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&pyb_uart_readchar_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&pyb_uart_sendbreak_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, // class constants { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, @@ -635,6 +643,9 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t a if ((flags & MP_STREAM_POLL_WR) && uart_tx_avail(self)) { ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // Since uart.write() waits up to the last byte, uart.flush() always succeds. + ret = 0; } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; From cc0249c936091889c9f2bda0ecafc522e06364a3 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 17:24:30 +0200 Subject: [PATCH 1677/4290] nrf/modules/machine/uart: Implement uart.flush() and uart.txdone(). Since uart.write() of the nrf port waits until all bytes but the last one have been sent, uart.flush() and uart.txdone() are implemented as empty functions to provide API consistency. uart.flush() flush() will always return immediately, even if the last byte may still be sent. ret = uart.txdone() uart.txdone() will always return True, even if the last byte may still be sent. --- ports/nrf/modules/machine/uart.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index e8c82e57dd16..1fd2ccc06caf 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -292,6 +292,12 @@ STATIC mp_obj_t machine_hard_uart_sendbreak(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hard_uart_sendbreak_obj, machine_hard_uart_sendbreak); +// Since uart.write() waits up to the last byte, uart.txdone() always returns True. +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + return mp_const_true; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t machine_hard_uart_locals_dict_table[] = { // instance methods { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, @@ -302,6 +308,8 @@ STATIC const mp_rom_map_elem_t machine_hard_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&machine_hard_uart_writechar_obj) }, { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&machine_hard_uart_readchar_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_hard_uart_sendbreak_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, // class constants /* @@ -347,6 +355,11 @@ STATIC mp_uint_t machine_hard_uart_write(mp_obj_t self_in, const void *buf_in, m STATIC mp_uint_t machine_hard_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { machine_hard_uart_obj_t *self = self_in; (void)self; + + if (request == MP_STREAM_FLUSH) { + // Since uart.write() waits up to the last byte, uart.flush() always succeds. + return 0; + } return MP_STREAM_ERROR; } From a39b88f0fbffe802dc8a80980e6fd675c9ef5a65 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 18:08:29 +0200 Subject: [PATCH 1678/4290] cc3200/mods/pybuart: Implement uart.flush() and uart.txdone(). uart.flush() flush() will wait until all characters have been sent. To avoid a permanent lock, a timeout applies depending on the size of FIFO and the baud rate. ret = uart.txdone() ret is True if no transfer is in progress. ret is False otherwise. --- ports/cc3200/mods/pybuart.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c index 6e774b70d9a9..a81954abb8b5 100644 --- a/ports/cc3200/mods/pybuart.c +++ b/ports/cc3200/mods/pybuart.c @@ -66,6 +66,7 @@ #define PYBUART_TX_MAX_TIMEOUT_MS (5) #define PYBUART_RX_BUFFER_LEN (256) +#define PYBUART_TX_BUFFER_LEN (17) // interrupt triggers #define UART_TRIGGER_RX_ANY (0x01) @@ -558,6 +559,17 @@ STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t * } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq); +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (MAP_UARTBusy(self->reg) == false) { + return mp_const_true; + } else { + return mp_const_false; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { // instance methods { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) }, @@ -565,6 +577,7 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&pyb_uart_sendbreak_obj) }, { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&pyb_uart_irq_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, /// \method read([nbytes]) { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, @@ -574,6 +587,7 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, /// \method write(buf) { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, // class constants { MP_ROM_QSTR(MP_QSTR_RX_ANY), MP_ROM_INT(UART_TRIGGER_RX_ANY) }, @@ -635,6 +649,21 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a if ((flags & MP_STREAM_POLL_WR) && MAP_UARTSpaceAvail(self->reg)) { ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // The timeout is estimated using the buffer size and the baudrate. + // Take the worst case assumptions at 13 bit symbol size times 2. + uint64_t timeout = mp_hal_ticks_ms() + + (PYBUART_TX_BUFFER_LEN) * 13000 * 2 / self->baudrate; + + do { + if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) { + return 0; + } + MICROPY_EVENT_POLL_HOOK + } while (mp_hal_ticks_ms() < timeout); + + *errcode = MP_ETIMEDOUT; + ret = MP_STREAM_ERROR;; } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; From b74eeee5e0e2a6c1437072c7343ccf9a5e7b5aad Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 26 Aug 2022 20:37:43 +0200 Subject: [PATCH 1679/4290] docs/library/machine.UART: Add docs for uart.flush() and uart.txdone(). --- docs/library/machine.UART.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst index 1d54174c9961..c3eca8f55a69 100644 --- a/docs/library/machine.UART.rst +++ b/docs/library/machine.UART.rst @@ -177,6 +177,32 @@ Methods Availability: WiPy. +.. method:: UART.flush() + + Waits until all data has been sent. In case of a timeout, an exception is raised. The timeout + duration depends on the tx buffer size and the baud rate. Unless flow control is enabled, a timeout + should not occur. + + .. note:: + + For the rp2, esp8266 and nrf ports the call returns while the last byte is sent. + If required, a one character wait time has to be added in the calling script. + + Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports + +.. method:: UART.txdone() + + Tells whether all data has been sent or no data transfer is happening. In this case, + it returns ``True``. If a data transmission is ongoing it returns ``False``. + + .. note:: + + For the rp2, esp8266 and nrf ports the call may return ``True`` even if the last byte + of a transfer is still being sent. If required, a one character wait time has to be + added in the calling script. + + Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports + Constants --------- From 85a25895ffc17b6034f4348e26c6248c34be8324 Mon Sep 17 00:00:00 2001 From: hoihu Date: Mon, 29 Aug 2022 08:00:37 +0200 Subject: [PATCH 1680/4290] rp2/mbedtls: Fix missing time.h include. --- ports/rp2/mbedtls/mbedtls_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/rp2/mbedtls/mbedtls_config.h b/ports/rp2/mbedtls/mbedtls_config.h index 743d0a6a8425..c80aa5bc18c2 100644 --- a/ports/rp2/mbedtls/mbedtls_config.h +++ b/ports/rp2/mbedtls/mbedtls_config.h @@ -106,6 +106,7 @@ void m_tracked_free(void *ptr); #define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf // Time hook +#include time_t rp2_rtctime_seconds(time_t *timer); #define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds From 621bff8557c7a7e35cdc9f6c6de0e6c912d94202 Mon Sep 17 00:00:00 2001 From: Takeo Takahashi Date: Thu, 23 Jun 2022 22:27:47 +0900 Subject: [PATCH 1681/4290] renesas-ra/machine_pin: Support drive keyword and fix GPIO setting. Changes are: - Support drive= keyword argument. - Fix trigger keyword check. - Fix GPIO pin setting. Signed-off-by: Takeo Takahashi --- .../boards/RA4M1_CLICKER/mpconfigboard.h | 4 +- .../boards/RA4M1_EK/mpconfigboard.h | 4 +- .../boards/RA4W1_EK/mpconfigboard.h | 4 +- .../boards/RA6M1_EK/mpconfigboard.h | 4 +- .../boards/RA6M2_EK/mpconfigboard.h | 4 +- ports/renesas-ra/extint.c | 30 ++-- ports/renesas-ra/machine_pin.c | 132 +++++++++++------- ports/renesas-ra/mphalport.h | 12 +- ports/renesas-ra/ra/ra_gpio.c | 59 ++++---- ports/renesas-ra/ra/ra_gpio.h | 57 ++++---- ports/renesas-ra/ra/ra_i2c.c | 4 +- ports/renesas-ra/ra/ra_sci.c | 8 +- ports/renesas-ra/ra/ra_spi.c | 4 +- ports/renesas-ra/usrsw.c | 2 +- 14 files changed, 177 insertions(+), 151 deletions(-) diff --git a/ports/renesas-ra/boards/RA4M1_CLICKER/mpconfigboard.h b/ports/renesas-ra/boards/RA4M1_CLICKER/mpconfigboard.h index ec67d68b6584..f39cf8f80e39 100644 --- a/ports/renesas-ra/boards/RA4M1_CLICKER/mpconfigboard.h +++ b/ports/renesas-ra/boards/RA4M1_CLICKER/mpconfigboard.h @@ -47,8 +47,8 @@ // Switch #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_USRSW_PIN (pin_P304) -#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) -#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PULL (MP_HAL_PIN_PULL_NONE) +#define MICROPY_HW_USRSW_EXTI_MODE (MP_HAL_PIN_TRIGGER_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) // LEDs diff --git a/ports/renesas-ra/boards/RA4M1_EK/mpconfigboard.h b/ports/renesas-ra/boards/RA4M1_EK/mpconfigboard.h index 500fe78b9e12..2874142890c1 100644 --- a/ports/renesas-ra/boards/RA4M1_EK/mpconfigboard.h +++ b/ports/renesas-ra/boards/RA4M1_EK/mpconfigboard.h @@ -59,8 +59,8 @@ // Switch #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_USRSW_PIN (pin_P105) -#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) -#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PULL (MP_HAL_PIN_PULL_NONE) +#define MICROPY_HW_USRSW_EXTI_MODE (MP_HAL_PIN_TRIGGER_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) // LEDs diff --git a/ports/renesas-ra/boards/RA4W1_EK/mpconfigboard.h b/ports/renesas-ra/boards/RA4W1_EK/mpconfigboard.h index 0e0dff14755c..0bf907a48c7c 100644 --- a/ports/renesas-ra/boards/RA4W1_EK/mpconfigboard.h +++ b/ports/renesas-ra/boards/RA4W1_EK/mpconfigboard.h @@ -58,8 +58,8 @@ // Switch #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_USRSW_PIN (pin_P402) -#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) -#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PULL (MP_HAL_PIN_PULL_NONE) +#define MICROPY_HW_USRSW_EXTI_MODE (MP_HAL_PIN_TRIGGER_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) // LEDs diff --git a/ports/renesas-ra/boards/RA6M1_EK/mpconfigboard.h b/ports/renesas-ra/boards/RA6M1_EK/mpconfigboard.h index 0693e404fd8f..59db4bc218a8 100644 --- a/ports/renesas-ra/boards/RA6M1_EK/mpconfigboard.h +++ b/ports/renesas-ra/boards/RA6M1_EK/mpconfigboard.h @@ -64,8 +64,8 @@ // Switch #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_USRSW_PIN (pin_P415) -#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) -#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PULL (MP_HAL_PIN_PULL_NONE) +#define MICROPY_HW_USRSW_EXTI_MODE (MP_HAL_PIN_TRIGGER_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) // LEDs diff --git a/ports/renesas-ra/boards/RA6M2_EK/mpconfigboard.h b/ports/renesas-ra/boards/RA6M2_EK/mpconfigboard.h index 2d2dc326d338..9988e0ed25d0 100644 --- a/ports/renesas-ra/boards/RA6M2_EK/mpconfigboard.h +++ b/ports/renesas-ra/boards/RA6M2_EK/mpconfigboard.h @@ -77,8 +77,8 @@ // Switch #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_USRSW_PIN (pin_P105) -#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) -#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PULL (MP_HAL_PIN_PULL_NONE) +#define MICROPY_HW_USRSW_EXTI_MODE (MP_HAL_PIN_TRIGGER_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) // LEDs diff --git a/ports/renesas-ra/extint.c b/ports/renesas-ra/extint.c index 19caa7a3b3fe..59f9ecfa37ea 100644 --- a/ports/renesas-ra/extint.c +++ b/ports/renesas-ra/extint.c @@ -138,8 +138,8 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("The Pin object(%d) doesn't have EXTINT feature"), pin_idx); } } - if (pull != GPIO_NOPULL && - pull != GPIO_PULLUP) { + if ((pull != MP_HAL_PIN_PULL_NONE) && + (pull != MP_HAL_PIN_PULL_UP)) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid ExtInt Pull: %d"), pull); } mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[v_line]; @@ -153,7 +153,6 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca extint_disable(v_line); *cb = callback_obj; - // ToDo: mode should be handled pyb_extint_mode[v_line] = mode; pyb_extint_callback_arg[v_line] = MP_OBJ_NEW_SMALL_INT(v_line); if (*cb != mp_const_none) { @@ -200,7 +199,6 @@ void extint_register_pin(const machine_pin_obj_t *pin, uint32_t mode, bool hard_ extint_disable(line); *cb = callback_obj; - // ToDo: mode should be handled pyb_extint_mode[line] = mode; if (*cb != mp_const_none) { @@ -255,16 +253,16 @@ void extint_trigger_mode(uint line, uint32_t mode) { // cond: 0: falling, 1: rising, 2: both edge, 3 low level // Enable or disable the rising detector uint32_t cond = 0; - if ((mode == GPIO_MODE_IT_RISING) || (mode == GPIO_MODE_EVT_RISING)) { - cond = 1; - } else if ((mode == GPIO_MODE_IT_FALLING) || (mode == GPIO_MODE_EVT_FALLING)) { - cond = 0; - } else if ((mode == GPIO_MODE_IT_RISING_FALLING) || (mode == GPIO_MODE_EVT_RISING_FALLING)) { - cond = 2; - } else if (mode == GPIO_IRQ_LOWLEVEL) { + if (mode & MP_HAL_PIN_TRIGGER_LOWLEVEL) { cond = 3; + } else if (mode & MP_HAL_PIN_TRIGGER_FALLING) { + if (mode & MP_HAL_PIN_TRIGGER_RISING) { + cond = 2; + } else { + cond = 0; + } } else { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("The device doesn't have (%d) feature"), (uint32_t)mode); + cond = 1; } ra_icu_trigger_irq_no((uint8_t)line, cond); enable_irq(irq_state); @@ -372,14 +370,6 @@ STATIC const mp_rom_map_elem_t extint_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_disable), MP_ROM_PTR(&extint_obj_disable_obj) }, { MP_ROM_QSTR(MP_QSTR_swint), MP_ROM_PTR(&extint_obj_swint_obj) }, { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&extint_regs_obj) }, - - // class constants - /// \constant IRQ_RISING - interrupt on a rising edge - /// \constant IRQ_FALLING - interrupt on a falling edge - /// \constant IRQ_RISING_FALLING - interrupt on a rising or falling edge - { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_MODE_IT_RISING) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_MODE_IT_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_ROM_INT(GPIO_MODE_IT_RISING_FALLING) }, }; STATIC MP_DEFINE_CONST_DICT(extint_locals_dict, extint_locals_dict_table); diff --git a/ports/renesas-ra/machine_pin.c b/ports/renesas-ra/machine_pin.c index 6e852e9cbf1d..f940b55547eb 100644 --- a/ports/renesas-ra/machine_pin.c +++ b/ports/renesas-ra/machine_pin.c @@ -78,7 +78,7 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin uint32_t mode = pin_get_mode(self); - if (mode == GPIO_MODE_ANALOG) { + if (mode == MP_HAL_PIN_MODE_ANALOG) { // analog mp_print_str(print, "ANALOG)"); @@ -86,15 +86,15 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin // IO mode bool af = false; qstr mode_qst; - if (mode == GPIO_MODE_INPUT) { + if (mode == MP_HAL_PIN_MODE_INPUT) { mode_qst = MP_QSTR_IN; - } else if (mode == GPIO_MODE_OUTPUT_PP) { + } else if (mode == MP_HAL_PIN_MODE_OUTPUT) { mode_qst = MP_QSTR_OUT; - } else if (mode == GPIO_MODE_OUTPUT_OD) { + } else if (mode == MP_HAL_PIN_MODE_OPEN_DRAIN) { mode_qst = MP_QSTR_OPEN_DRAIN; } else { af = true; - if (mode == GPIO_MODE_AF_PP) { + if (mode == MP_HAL_PIN_MODE_ALT) { mode_qst = MP_QSTR_ALT; } else { mode_qst = MP_QSTR_ALT_OPEN_DRAIN; @@ -105,9 +105,9 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin // pull mode qstr pull_qst = MP_QSTRnull; uint32_t pull = pin_get_pull(self); - if (pull == GPIO_PULLUP) { + if (pull == MP_HAL_PIN_PULL_UP) { pull_qst = MP_QSTR_PULL_UP; - } else if (pull == GPIO_NOPULL) { + } else if (pull == MP_HAL_PIN_PULL_NONE) { pull_qst = MP_QSTR_PULL_NONE; } if (pull_qst != MP_QSTRnull) { @@ -117,12 +117,14 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin // drive qstr drive_qst = MP_QSTRnull; uint32_t drive = pin_get_drive(self); - if (drive == GPIO_HIGH_POWER) { - drive_qst = MP_QSTR_HIGH_POWER; - } else if (drive == GPIO_MED_POWER) { - drive_qst = MP_QSTR_MED_POWER; - } else if (drive == GPIO_LOW_POWER) { - drive_qst = MP_QSTR_LOW_POWER; + if (drive == MP_HAL_PIN_DRIVE_3) { + drive_qst = MP_QSTR_DRIVE_3; + } else if (drive == MP_HAL_PIN_DRIVE_2) { + drive_qst = MP_QSTR_DRIVE_2; + } else if (drive == MP_HAL_PIN_DRIVE_1) { + drive_qst = MP_QSTR_DRIVE_1; + } else if (drive == MP_HAL_PIN_DRIVE_0) { + drive_qst = MP_QSTR_DRIVE_0; } if (drive_qst != MP_QSTRnull) { mp_printf(print, ", drive=Pin.%q", drive_qst); @@ -143,14 +145,14 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin } } -// pin.init(mode, pull=None, *, value=None, driver=None, alt=FUNC_SIO) +// pin.init(mode=-1, pull=-1, *, value=None, drive=0, alt=-1) STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, - { MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy - { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - { MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = GPIO_LOW_POWER}}, + { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + { MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, { MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, }; @@ -159,29 +161,50 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // get io mode - uint mode = args[0].u_int; - if (!IS_GPIO_MODE(mode)) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode); + uint32_t mode; + if (args[ARG_mode].u_obj != mp_const_none) { + mode = mp_obj_get_int(args[ARG_mode].u_obj); + if (!IS_GPIO_MODE(mode)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode); + } + } else { + mode = ra_gpio_get_mode(self->pin); } // get pull mode - uint pull = 0; - if (args[1].u_obj != mp_const_none) { - pull = mp_obj_get_int(args[1].u_obj); + uint32_t pull; + if (args[ARG_pull].u_obj != mp_const_none) { + pull = mp_obj_get_int(args[ARG_pull].u_obj); + if (!IS_GPIO_PULL(pull)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pull mode: %d"), pull); + } + if (pull == MP_HAL_PIN_PULL_DOWN) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%q is not supported"), MP_QSTR_PULL_DOWN); + } + } else { + pull = ra_gpio_get_pull(self->pin); } // get drive - uint drive = args[4].u_int; - if (!IS_GPIO_DRIVE(drive)) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin drive: %d"), drive); + uint32_t drive; + if (args[ARG_drive].u_obj != mp_const_none) { + drive = mp_obj_get_int(args[ARG_drive].u_obj); + if (!IS_GPIO_DRIVE(drive)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin drive: %d"), drive); + } + } else { + drive = ra_gpio_get_drive(self->pin); } - mp_hal_pin_config(self, mode, pull, drive, -1); + // get alt + if (args[ARG_alt].u_int != (-1)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("alt is not supported")); + } + mp_hal_pin_config(self, mode, pull, drive, 0); // if given, set the pin value before initialising to prevent glitches - if (args[3].u_obj != MP_OBJ_NULL) { - mp_hal_pin_write(self, mp_obj_is_true(args[3].u_obj)); + if (args[ARG_value].u_obj != mp_const_none) { + mp_hal_pin_write(self, mp_obj_is_true(args[ARG_value].u_obj)); } - return mp_const_none; } @@ -249,13 +272,17 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_ enum { ARG_handler, ARG_trigger, ARG_hard }; static const mp_arg_t allowed_args[] = { { MP_QSTR_handler, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_MODE_IT_RISING | GPIO_MODE_IT_FALLING} }, + { MP_QSTR_trigger, MP_ARG_INT, {.u_int = MP_HAL_PIN_TRIGGER_RISING | MP_HAL_PIN_TRIGGER_FALLING} }, { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} }, }; machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + if (args[ARG_trigger].u_int & MP_HAL_PIN_TRIGGER_HIGHLEVEL) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%q is not supported"), MP_QSTR_IRQ_HIGH_LEVEL); + } + if (n_args > 1 || kw_args->used != 0) { // configure irq extint_register_pin(self, args[ARG_trigger].u_int, @@ -282,27 +309,23 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&pin_cpu_pins_obj_type) }, // class constants - { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_INPUT) }, - { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUTPUT_PP) }, - { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_OUTPUT_OD) }, - { MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(GPIO_MODE_AF_PP) }, - { MP_ROM_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_AF_OD) }, - { MP_ROM_QSTR(MP_QSTR_ANALOG), MP_ROM_INT(GPIO_MODE_ANALOG) }, - { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULLUP) }, - { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULLDOWN) }, - { MP_ROM_QSTR(MP_QSTR_PULL_HOLD), MP_ROM_INT(GPIO_PULLHOLD) }, - { MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(GPIO_NOPULL) }, - { MP_ROM_QSTR(MP_QSTR_LOW_POWER), MP_ROM_INT(GPIO_LOW_POWER) }, - { MP_ROM_QSTR(MP_QSTR_MED_POWER), MP_ROM_INT(GPIO_MED_POWER) }, - { MP_ROM_QSTR(MP_QSTR_HIGH_POWER), MP_ROM_INT(GPIO_HIGH_POWER) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_MODE_IT_RISING) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_MODE_IT_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_ROM_INT(GPIO_MODE_IT_RISING_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_EVT_RISING), MP_ROM_INT(GPIO_MODE_EVT_RISING) }, - { MP_ROM_QSTR(MP_QSTR_EVT_FALLING), MP_ROM_INT(GPIO_MODE_EVT_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_EVT_RISING_FALLING), MP_ROM_INT(GPIO_MODE_EVT_RISING_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_LOWLEVEL), MP_ROM_INT(GPIO_IRQ_LOWLEVEL) }, - { MP_ROM_QSTR(MP_QSTR_IRQ_HIGHLEVEL), MP_ROM_INT(GPIO_IRQ_HIGHLEVEL) }, + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(MP_HAL_PIN_MODE_INPUT) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(MP_HAL_PIN_MODE_OUTPUT) }, + { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(MP_HAL_PIN_MODE_OPEN_DRAIN) }, + { MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(MP_HAL_PIN_MODE_ALT) }, + { MP_ROM_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_ROM_INT(MP_HAL_PIN_MODE_ALT_OPEN_DRAIN) }, + { MP_ROM_QSTR(MP_QSTR_ANALOG), MP_ROM_INT(MP_HAL_PIN_MODE_ANALOG) }, + { MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(MP_HAL_PIN_PULL_NONE) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(MP_HAL_PIN_PULL_UP) }, + { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(MP_HAL_PIN_PULL_DOWN) }, + { MP_ROM_QSTR(MP_QSTR_DRIVE_0), MP_ROM_INT(MP_HAL_PIN_DRIVE_0) }, + { MP_ROM_QSTR(MP_QSTR_DRIVE_1), MP_ROM_INT(MP_HAL_PIN_DRIVE_1) }, + { MP_ROM_QSTR(MP_QSTR_DRIVE_2), MP_ROM_INT(MP_HAL_PIN_DRIVE_2) }, + { MP_ROM_QSTR(MP_QSTR_DRIVE_3), MP_ROM_INT(MP_HAL_PIN_DRIVE_3) }, + { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(MP_HAL_PIN_TRIGGER_FALLING) }, + { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(MP_HAL_PIN_TRIGGER_RISING) }, + { MP_ROM_QSTR(MP_QSTR_IRQ_LOW_LEVEL), MP_ROM_INT(MP_HAL_PIN_TRIGGER_LOWLEVEL) }, + { MP_ROM_QSTR(MP_QSTR_IRQ_HIGH_LEVEL), MP_ROM_INT(MP_HAL_PIN_TRIGGER_HIGHLEVEL) }, }; STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); @@ -352,7 +375,8 @@ uint32_t pin_get_pull(const machine_pin_obj_t *pin) { } // Returns the pin drive. The value returned by this macro should -// be one of GPIO_HIGH_POWER, GPIO_MED_POWER, or GPIO_LOW_POWER. +// be one of GPIO_HIGH_POWER, GPIO_MID_FAST_POWER, GPIO_MID_POWER, +// or GPIO_LOW_POWER. uint32_t pin_get_drive(const machine_pin_obj_t *pin) { return (uint32_t)ra_gpio_get_drive(pin->pin); diff --git a/ports/renesas-ra/mphalport.h b/ports/renesas-ra/mphalport.h index c489d1b966a7..2648e22f994c 100644 --- a/ports/renesas-ra/mphalport.h +++ b/ports/renesas-ra/mphalport.h @@ -4,7 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2018 Damien P. George - * Copyright (c) 2021 Renesas Electronics Corporation + * Copyright (c) 2021-2022 Renesas Electronics Corporation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -69,13 +69,21 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { #define MP_HAL_PIN_PULL_NONE (GPIO_NOPULL) #define MP_HAL_PIN_PULL_UP (GPIO_PULLUP) #define MP_HAL_PIN_PULL_DOWN (GPIO_PULLDOWN) +#define MP_HAL_PIN_TRIGGER_FALLING (GPIO_IRQ_FALLING) +#define MP_HAL_PIN_TRIGGER_RISING (GPIO_IRQ_RISING) +#define MP_HAL_PIN_TRIGGER_LOWLEVEL (GPIO_IRQ_LOWLEVEL) +#define MP_HAL_PIN_TRIGGER_HIGHLEVEL (GPIO_IRQ_HIGHLEVEL) +#define MP_HAL_PIN_DRIVE_0 (GPIO_LOW_POWER) +#define MP_HAL_PIN_DRIVE_1 (GPIO_MID_POWER) +#define MP_HAL_PIN_DRIVE_2 (GPIO_MID_FAST_POWER) +#define MP_HAL_PIN_DRIVE_3 (GPIO_HIGH_POWER) #define mp_hal_pin_obj_t const machine_pin_obj_t * #define mp_hal_get_pin_obj(o) machine_pin_find(o) #define mp_hal_pin_name(p) ((p)->name) #define mp_hal_pin_input(p) ra_gpio_mode_input((p)->pin) #define mp_hal_pin_output(p) ra_gpio_mode_output((p)->pin) -#define mp_hal_pin_open_drain(p) ra_gpio_config((p)->pin, GPIO_MODE_OUTPUT_OD, 0, 0, 0) +#define mp_hal_pin_open_drain(p) ra_gpio_config((p)->pin, MP_HAL_PIN_MODE_OPEN_DRAIN, MP_HAL_PIN_PULL_NONE, MP_HAL_PIN_DRIVE_0, 0) #define mp_hal_pin_high(p) ra_gpio_write((p)->pin, 1) #define mp_hal_pin_low(p) ra_gpio_write((p)->pin, 0) #define mp_hal_pin_toggle(p) ra_gpio_toggle((p)->pin) diff --git a/ports/renesas-ra/ra/ra_gpio.c b/ports/renesas-ra/ra/ra_gpio.c index 598546cb9349..a01131953c1f 100644 --- a/ports/renesas-ra/ra/ra_gpio.c +++ b/ports/renesas-ra/ra/ra_gpio.c @@ -31,23 +31,17 @@ void ra_gpio_config(uint32_t pin, uint32_t mode, uint32_t pull, uint32_t drive, uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); pwpr_unprotect(); + _PXXPFS(port, bit) &= ~(PMR_MASK | ASEL_MASK | NCODR_MASK | PCR_MASK | PDR_MASK | DSCR1_MASK | DSCR_MASK); switch (mode) { case GPIO_MODE_INPUT: - _PXXPFS(port, bit) &= ~(PMR_MASK | ASEL_MASK); // GPIO - _PXXPFS(port, bit) &= ~PDR_MASK; // input - if (pull != 0) { + if (pull == GPIO_PULLUP) { _PXXPFS(port, bit) |= PCR_MASK; // set pullup - } else { - _PXXPFS(port, bit) &= ~PCR_MASK; // clear pullup } break; case GPIO_MODE_OUTPUT_PP: - _PXXPFS(port, bit) &= ~(PMR_MASK | ASEL_MASK); // GPIO _PXXPFS(port, bit) |= PDR_MASK; // output - _PXXPFS(port, bit) &= ~PCR_MASK; // pullup clear break; case GPIO_MODE_OUTPUT_OD: - _PXXPFS(port, bit) &= ~(PMR_MASK | ASEL_MASK); // GPIO _PXXPFS(port, bit) |= (PDR_MASK | NCODR_MASK); break; case GPIO_MODE_AF_PP: @@ -56,20 +50,23 @@ void ra_gpio_config(uint32_t pin, uint32_t mode, uint32_t pull, uint32_t drive, case GPIO_MODE_AF_OD: _PXXPFS(port, bit) |= (PMR_MASK | PDR_MASK | NCODR_MASK); break; + case GPIO_MODE_ANALOG: + _PXXPFS(port, bit) |= ASEL_MASK; + break; } switch (drive) { case GPIO_HIGH_POWER: _PXXPFS(port, bit) |= (DSCR1_MASK | DSCR_MASK); break; - case GPIO_MED_POWER: - _PXXPFS(port, bit) &= ~DSCR1_MASK; + case GPIO_MID_FAST_POWER: + _PXXPFS(port, bit) |= DSCR1_MASK; + break; + case GPIO_MID_POWER: _PXXPFS(port, bit) |= DSCR_MASK; break; case GPIO_LOW_POWER: - _PXXPFS(port, bit) &= ~(DSCR1_MASK | DSCR_MASK); - break; - default: /* GPIO_NOTOUCH_POWER */ - /* do not modify */ + default: + /* Bits are already cleared */ break; } _PXXPFS(port, bit) &= ~(uint32_t)(0x1f000000); @@ -102,7 +99,6 @@ void ra_gpio_toggle(uint32_t pin) { uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); pwpr_unprotect(); - _PXXPFS(port, bit) &= ~(PMR_MASK | ASEL_MASK); // GPIO _PXXPFS(port, bit) ^= 1; pwpr_protect(); } @@ -111,7 +107,6 @@ void ra_gpio_write(uint32_t pin, uint32_t value) { uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); pwpr_unprotect(); - _PXXPFS(port, bit) &= ~(PMR_MASK | ASEL_MASK); // GPIO if (value != 0) { _PXXPFS(port, bit) |= 1; } else { @@ -123,15 +118,26 @@ void ra_gpio_write(uint32_t pin, uint32_t value) { uint32_t ra_gpio_read(uint32_t pin) { uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); - return ((_PXXPFS(port, bit) &= PIDR_MASK) != 0) ? 1 : 0; + return ((_PXXPFS(port, bit) & PIDR_MASK) != 0) ? 1 : 0; } uint32_t ra_gpio_get_mode(uint32_t pin) { uint8_t mode = 0; - uint32_t port = GPIO_PORT(pin); - uint32_t bit = GPIO_BIT(pin); - if ((_PXXPFS(port, bit) &= PDR_MASK) != 0) { - mode = GPIO_MODE_OUTPUT_PP; + uint32_t pfs = _PXXPFS(GPIO_PORT(pin), GPIO_BIT(pin)); + if ((pfs & ASEL_MASK) != 0) { + mode = GPIO_MODE_ANALOG; + } else if ((pfs & PMR_MASK) != 0) { + if ((pfs & NCODR_MASK) != 0) { + mode = GPIO_MODE_AF_OD; + } else { + mode = GPIO_MODE_AF_PP; + } + } else if ((pfs & PDR_MASK) != 0) { + if ((pfs & NCODR_MASK) != 0) { + mode = GPIO_MODE_OUTPUT_OD; + } else { + mode = GPIO_MODE_OUTPUT_PP; + } } else { mode = GPIO_MODE_INPUT; } @@ -142,7 +148,7 @@ uint32_t ra_gpio_get_pull(uint32_t pin) { uint8_t pull = 0; uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); - if ((_PXXPFS(port, bit) &= PCR_MASK) != 0) { + if ((_PXXPFS(port, bit) & PCR_MASK) != 0) { pull = GPIO_PULLUP; } else { pull = GPIO_NOPULL; @@ -153,19 +159,22 @@ uint32_t ra_gpio_get_pull(uint32_t pin) { uint32_t ra_gpio_get_af(uint32_t pin) { uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); - return (_PXXPFS(port, bit) &= PMR_MASK) != 0; + return (_PXXPFS(port, bit) & PMR_MASK) != 0; } uint32_t ra_gpio_get_drive(uint32_t pin) { uint8_t drive = 0; uint32_t port = GPIO_PORT(pin); uint32_t bit = GPIO_BIT(pin); - switch (_PXXPFS(port, bit) &= (DSCR1_MASK | DSCR_MASK)) { + switch (_PXXPFS(port, bit) & (DSCR1_MASK | DSCR_MASK)) { case (DSCR1_MASK | DSCR_MASK): drive = GPIO_HIGH_POWER; break; + case DSCR1_MASK: + drive = GPIO_MID_FAST_POWER; + break; case DSCR_MASK: - drive = GPIO_MED_POWER; + drive = GPIO_MID_POWER; break; case 0: default: diff --git a/ports/renesas-ra/ra/ra_gpio.h b/ports/renesas-ra/ra/ra_gpio.h index 7b7601663534..8c16fe3ba18c 100644 --- a/ports/renesas-ra/ra/ra_gpio.h +++ b/ports/renesas-ra/ra/ra_gpio.h @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2021 Renesas Electronics Corporation + * Copyright (c) 2021,2022 Renesas Electronics Corporation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -69,47 +69,42 @@ enum AF_INDEX { AF_END = 0xff, }; -#define GPIO_MODE_INPUT 1 -#define GPIO_MODE_OUTPUT_PP 2 -#define GPIO_MODE_OUTPUT_OD 3 -#define GPIO_MODE_AF_PP 4 -#define GPIO_MODE_AF_OD 5 -#define GPIO_MODE_ANALOG 6 -#define GPIO_MODE_IT_RISING 7 -#define GPIO_MODE_IT_FALLING 8 -#define GPIO_MODE_IT_RISING_FALLING 9 -#define GPIO_MODE_EVT_RISING 10 -#define GPIO_MODE_EVT_FALLING 11 -#define GPIO_MODE_EVT_RISING_FALLING 12 -#define GPIO_NOPULL 13 -#define GPIO_PULLUP 14 -#define GPIO_PULLDOWN 15 -#define GPIO_PULLHOLD 16 -#define GPIO_LOW_POWER 17 -#define GPIO_MED_POWER 18 -#define GPIO_HIGH_POWER 19 -#define GPIO_NOTOUCH_POWER 20 -#define GPIO_IRQ_LOWLEVEL 21 -#define GPIO_IRQ_HIGHLEVEL 22 +#define GPIO_MODE_INPUT 0 +#define GPIO_MODE_OUTPUT_PP 1 +#define GPIO_MODE_OUTPUT_OD 2 +#define GPIO_MODE_AF_PP 3 +#define GPIO_MODE_AF_OD 4 +#define GPIO_MODE_ANALOG 5 + +#define GPIO_IRQ_FALLING 0x1 +#define GPIO_IRQ_RISING 0x2 +#define GPIO_IRQ_LOWLEVEL 0x4 +#define GPIO_IRQ_HIGHLEVEL 0x8 + +#define GPIO_NOPULL 0 +#define GPIO_PULLUP 1 +#define GPIO_PULLDOWN 2 + +#define GPIO_LOW_POWER 0 +#define GPIO_MID_POWER 1 +#define GPIO_MID_FAST_POWER 2 +#define GPIO_HIGH_POWER 3 #define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) || \ ((MODE) == GPIO_MODE_OUTPUT_PP) || \ ((MODE) == GPIO_MODE_OUTPUT_OD) || \ ((MODE) == GPIO_MODE_AF_PP) || \ ((MODE) == GPIO_MODE_AF_OD) || \ - ((MODE) == GPIO_MODE_IT_RISING) || \ - ((MODE) == GPIO_MODE_IT_FALLING) || \ - ((MODE) == GPIO_MODE_IT_RISING_FALLING) || \ - ((MODE) == GPIO_MODE_EVT_RISING) || \ - ((MODE) == GPIO_MODE_EVT_FALLING) || \ - ((MODE) == GPIO_MODE_EVT_RISING_FALLING) || \ ((MODE) == GPIO_MODE_ANALOG)) #define IS_GPIO_DRIVE(DRIVE) (((DRIVE) == GPIO_LOW_POWER) || \ - ((DRIVE) == GPIO_MED_POWER) || \ + ((DRIVE) == GPIO_MID_POWER) || \ + ((DRIVE) == GPIO_MID_FAST_POWER) || \ ((DRIVE) == GPIO_HIGH_POWER)) -#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP)) +#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || \ + ((PULL) == GPIO_PULLUP) || \ + ((PULL) == GPIO_PULLDOWN)) #define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x1F) diff --git a/ports/renesas-ra/ra/ra_i2c.c b/ports/renesas-ra/ra/ra_i2c.c index 64bbd6f501b4..ad1e3a74e0de 100644 --- a/ports/renesas-ra/ra/ra_i2c.c +++ b/ports/renesas-ra/ra/ra_i2c.c @@ -362,8 +362,8 @@ void ra_i2c_set_baudrate(R_IIC0_Type *i2c_inst, uint32_t baudrate) { void ra_i2c_init(R_IIC0_Type *i2c_inst, uint32_t scl, uint32_t sda, uint32_t baudrate) { ra_i2c_module_start(i2c_inst); - ra_gpio_config(scl, GPIO_MODE_AF_OD, 0, GPIO_NOTOUCH_POWER, AF_I2C); - ra_gpio_config(sda, GPIO_MODE_AF_OD, 0, GPIO_NOTOUCH_POWER, AF_I2C); + ra_gpio_config(scl, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_LOW_POWER, AF_I2C); + ra_gpio_config(sda, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_LOW_POWER, AF_I2C); ra_i2c_priority(i2c_inst, RA_PRI_I2C); i2c_inst->ICCR1_b.ICE = 0; // I2C disable i2c_inst->ICCR1_b.IICRST = 1; // I2C internal reset diff --git a/ports/renesas-ra/ra/ra_sci.c b/ports/renesas-ra/ra/ra_sci.c index 8cf26680cc6e..2e7c81c4ac47 100644 --- a/ports/renesas-ra/ra/ra_sci.c +++ b/ports/renesas-ra/ra/ra_sci.c @@ -788,7 +788,7 @@ static void ra_sci_tx_set_pin(uint32_t pin) { uint32_t af; find = ra_af_find_ch_af((ra_af_pin_t *)&ra_sci_tx_pins, SCI_TX_PINS_SIZE, pin, &ch, &af); if (find) { - ra_gpio_config(pin, GPIO_MODE_AF_PP, 0, 0, af); + ra_gpio_config(pin, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_LOW_POWER, af); } } @@ -798,7 +798,7 @@ static void ra_sci_rx_set_pin(uint32_t pin) { uint32_t af; find = ra_af_find_ch_af((ra_af_pin_t *)&ra_sci_rx_pins, SCI_RX_PINS_SIZE, pin, &ch, &af); if (find) { - ra_gpio_config(pin, GPIO_MODE_INPUT, 1, 0, af); + ra_gpio_config(pin, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_LOW_POWER, af); } } @@ -808,7 +808,7 @@ static void ra_sci_cts_set_pin(uint32_t pin) { uint32_t af; find = ra_af_find_ch_af((ra_af_pin_t *)&ra_sci_cts_pins, SCI_CTS_PINS_SIZE, pin, &ch, &af); if (find) { - ra_gpio_config(pin, GPIO_MODE_INPUT, 1, 0, af); + ra_gpio_config(pin, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_LOW_POWER, af); } } @@ -1134,7 +1134,7 @@ void ra_sci_init_with_flow(uint32_t ch, uint32_t tx_pin, uint32_t rx_pin, uint32 } if (rts_pin != (uint32_t)PIN_END) { m_rts_pin[idx] = rts_pin; - ra_gpio_config(rts_pin, GPIO_MODE_OUTPUT_PP, false, 0, 0); + ra_gpio_config(rts_pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_LOW_POWER, 0); ra_gpio_write(rts_pin, 0); } } diff --git a/ports/renesas-ra/ra/ra_spi.c b/ports/renesas-ra/ra/ra_spi.c index b7f78cd6dead..096519ffd640 100644 --- a/ports/renesas-ra/ra/ra_spi.c +++ b/ports/renesas-ra/ra/ra_spi.c @@ -196,9 +196,9 @@ static void ra_spi_module_stop(uint32_t ch) { static void ra_spi_set_pin(uint32_t pin, bool miso) { if (miso) { - ra_gpio_config(pin, GPIO_MODE_INPUT, 1, 0, AF_SPI); + ra_gpio_config(pin, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_LOW_POWER, AF_SPI); } else { - ra_gpio_config(pin, GPIO_MODE_AF_PP, 0, 0, AF_SPI); + ra_gpio_config(pin, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_LOW_POWER, AF_SPI); } } diff --git a/ports/renesas-ra/usrsw.c b/ports/renesas-ra/usrsw.c index 5e11f48e6392..572510816b1f 100644 --- a/ports/renesas-ra/usrsw.c +++ b/ports/renesas-ra/usrsw.c @@ -54,7 +54,7 @@ // this function inits the switch GPIO so that it can be used void switch_init0(void) { - mp_hal_pin_config(MICROPY_HW_USRSW_PIN, MP_HAL_PIN_MODE_INPUT, MICROPY_HW_USRSW_PULL, GPIO_LOW_POWER, 0); + mp_hal_pin_config(MICROPY_HW_USRSW_PIN, MP_HAL_PIN_MODE_INPUT, MICROPY_HW_USRSW_PULL, MP_HAL_PIN_DRIVE_0, 0); } int switch_get(void) { From 2f2fd36713c2c02f56093338e8c1f3cd7b8d403a Mon Sep 17 00:00:00 2001 From: Takeo Takahashi Date: Thu, 23 Jun 2022 22:28:35 +0900 Subject: [PATCH 1682/4290] tests/renesas-ra: Update pin test to support all boards. Signed-off-by: Takeo Takahashi --- tests/renesas-ra/pin.py | 46 ++++++++----------------------------- tests/renesas-ra/pin.py.exp | 12 ++-------- 2 files changed, 11 insertions(+), 47 deletions(-) diff --git a/tests/renesas-ra/pin.py b/tests/renesas-ra/pin.py index 61d76cca7c74..4617cce11110 100644 --- a/tests/renesas-ra/pin.py +++ b/tests/renesas-ra/pin.py @@ -1,43 +1,15 @@ from machine import Pin -import os -n = os.uname().machine -if "RA4W1_EK" in n: - try_pin = "P004" - try_s = "Pin(Pin.cpu.P004, mode=Pin.IN, pull=Pin.PULL_NONE, drive=Pin.LOW_POWER)" +p = Pin("SW1", Pin.IN) +if p.value() == 1: + print("pass") else: - try_pin = "P000" - try_s = "Pin(Pin.cpu.P000, mode=Pin.IN, pull=Pin.PULL_NONE, drive=Pin.LOW_POWER)" + print("FAIL") -p = Pin(try_pin, Pin.IN) -if str(p) == try_s: - print("OK") +p = Pin("LED1", Pin.OUT) +p.high() +if p.value() == 1: + print("pass") else: - print("NG") - print("exp: " + try_s) - print("out: " + str(p)) - -p.init(p.IN, p.PULL_UP) -p.init(p.IN, pull=p.PULL_UP) -p.init(mode=p.IN, pull=p.PULL_UP) -print(p.value()) - -p.init(p.OUT) -p.init(p.OPEN_DRAIN) + print("FAIL") p.low() -print(p.value()) -p.high() -print(p.value()) -p.value(0) -print(p.value()) -p.value(1) -print(p.value()) -p.value(False) -print(p.value()) -p.value(True) -print(p.value()) -p.off() -print(p.value()) -p.on() -print(p.value()) -p.off() diff --git a/tests/renesas-ra/pin.py.exp b/tests/renesas-ra/pin.py.exp index 4c8cc50b0c06..0c34cd7a39ca 100644 --- a/tests/renesas-ra/pin.py.exp +++ b/tests/renesas-ra/pin.py.exp @@ -1,10 +1,2 @@ -OK -1 -0 -1 -0 -1 -0 -1 -0 -1 +pass +pass From af100b70290d20d7e9c3e7d49713e3916b6f05b6 Mon Sep 17 00:00:00 2001 From: Takeo Takahashi Date: Thu, 23 Jun 2022 22:29:00 +0900 Subject: [PATCH 1683/4290] docs/renesas-ra: Add pin drive keyword argument description. Signed-off-by: Takeo Takahashi --- docs/renesas-ra/quickref.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/renesas-ra/quickref.rst b/docs/renesas-ra/quickref.rst index 23ffab50eb80..47b49575bd5b 100644 --- a/docs/renesas-ra/quickref.rst +++ b/docs/renesas-ra/quickref.rst @@ -110,6 +110,24 @@ Use the :ref:`machine.Pin ` class:: Pin id is available corresponding to the RA MCU's pin name which are Pin.cpu.P106 and 'P106'. The RA MCU has many feature's pins. However, there are some cases that pin feature is fixed or not connected by the board. Please confirm the board manual for the pin mapping. +The following *drive* keyword argument are available if the port drive capability of the Pin is supported by the MCU:: + + Pin.DRIVE_0: Low drive + Pin.DRIVE_1: Middle drive + Pin.DRIVE_2: Middle drive for I2C Fast-mode + Pin.DRIVE_3: High drive + +The *alt* keyword argument is not supported. + +The following functions are not supported:: + + Pin.irq(priority=) # priority keyword argument is not supported + Pin.irq(wake=) # wake keyword argument is not supported + Pin.irq(hard=) # hard keyword argument is ignored because hardware interrupt is used + Pin.mode() + Pin.pull() + Pin.drive() + UART (serial bus) ----------------- From 0b26efe73dd3396bdc2b77651a78d9f2edeb9004 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 28 Aug 2022 18:14:53 +0200 Subject: [PATCH 1684/4290] extmod/machine_i2c: Call MICROPY_PY_EVENT_HOOK during i2c.scan(). Avoiding a watchdog reset during i2c.scan() if the hardware is not properly set up (eg on esp8266), and also allowing to stop the scan with a KeyboardInterrupt. Fixes issue #8876. --- extmod/machine_i2c.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index 2aa217914bfb..ff597b58c5e5 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -328,6 +328,9 @@ STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) { if (ret == 0) { mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr)); } + #ifdef MICROPY_EVENT_POLL_HOOK + MICROPY_EVENT_POLL_HOOK + #endif } return list; } From da7f2537a124191371cbc3bc625ed96a43dc29c7 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 10 Aug 2022 22:53:39 +1000 Subject: [PATCH 1685/4290] top: Use micropython-lib unconditionally in manifests. micropython-lib is now a submodule, and the manifest compilation process will ensure it is available, so manifests no longer need to check that it is available. Signed-off-by: Jim Mussared --- ports/esp8266/boards/GENERIC/manifest.py | 18 ++++++++---------- .../ARDUINO_NANO_RP2040_CONNECT/manifest.py | 3 +-- ports/rp2/boards/PICO_W/manifest.py | 3 +-- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/ports/esp8266/boards/GENERIC/manifest.py b/ports/esp8266/boards/GENERIC/manifest.py index 9ce3ffe3aae1..ef25040ef8a7 100644 --- a/ports/esp8266/boards/GENERIC/manifest.py +++ b/ports/esp8266/boards/GENERIC/manifest.py @@ -7,15 +7,13 @@ # drivers freeze("$(MPY_DIR)/drivers/display", "ssd1306.py") -# Libraries from micropython-lib, include only if the library directory exists -if os.path.isdir(convert_path("$(MPY_LIB_DIR)")): - # file utilities - freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") +# micropython-lib: file utilities +freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") - # requests - freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") - freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py") +# micropython-lib: requests +freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") +freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py") - # umqtt - freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") - freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") +# micropython-lib: umqtt +freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py index 0448aa89a11e..7a2f1c9e2738 100644 --- a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py @@ -8,5 +8,4 @@ l2cap=True, security=True, ) -if os.path.isdir(convert_path("$(MPY_LIB_DIR)")): - freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") +freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") diff --git a/ports/rp2/boards/PICO_W/manifest.py b/ports/rp2/boards/PICO_W/manifest.py index eb748da485c9..d2c76602affe 100644 --- a/ports/rp2/boards/PICO_W/manifest.py +++ b/ports/rp2/boards/PICO_W/manifest.py @@ -4,5 +4,4 @@ freeze("$(MPY_DIR)/tools", "upip_utarfile.py") freeze("$(MPY_DIR)/extmod", "ntptime.py") -if os.path.isdir(convert_path("$(MPY_LIB_DIR)")): - freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") +freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") From f3cdb052db1784b38e02f043cb72bda5a57b8696 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 13 Jul 2022 23:36:45 +1000 Subject: [PATCH 1686/4290] tools/manifestfile.py: Add library for working with manifests. This splits the manifest file loading logic from makemanifest.py and updates makemanifest.py to use it. This will allow non-freezing uses of manifests, such as defining packages and dependencies in micropython-lib. Also adds additional methods to the manifest "API": - require() - to get a package from micropython-lib. - module() - to define a single-file module - package() - to define a multi-file package module() and package() should replace most uses of freeze() and can also be also used in non-freezing scenarios. Signed-off-by: Jim Mussared --- tools/makemanifest.py | 302 +++++++----------------------- tools/manifestfile.py | 416 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 477 insertions(+), 241 deletions(-) create mode 100644 tools/manifestfile.py diff --git a/tools/makemanifest.py b/tools/makemanifest.py index e69698d3f234..800a25435eb9 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -29,127 +29,10 @@ import os import subprocess - -########################################################################### -# Public functions to be used in the manifest - - -def include(manifest, **kwargs): - """Include another manifest. - - The manifest argument can be a string (filename) or an iterable of - strings. - - Relative paths are resolved with respect to the current manifest file. - - Optional kwargs can be provided which will be available to the - included script via the `options` variable. - - e.g. include("path.py", extra_features=True) - - in path.py: - options.defaults(standard_features=True) - - # freeze minimal modules. - if options.standard_features: - # freeze standard modules. - if options.extra_features: - # freeze extra modules. - """ - - if not isinstance(manifest, str): - for m in manifest: - include(m) - else: - manifest = convert_path(manifest) - with open(manifest) as f: - # Make paths relative to this manifest file while processing it. - # Applies to includes and input files. - prev_cwd = os.getcwd() - os.chdir(os.path.dirname(manifest)) - exec(f.read(), globals(), {"options": IncludeOptions(**kwargs)}) - os.chdir(prev_cwd) - - -def freeze(path, script=None, opt=0): - """Freeze the input, automatically determining its type. A .py script - will be compiled to a .mpy first then frozen, and a .mpy file will be - frozen directly. - - `path` must be a directory, which is the base directory to search for - files from. When importing the resulting frozen modules, the name of - the module will start after `path`, ie `path` is excluded from the - module name. - - If `path` is relative, it is resolved to the current manifest.py. - Use $(MPY_DIR), $(MPY_LIB_DIR), $(PORT_DIR), $(BOARD_DIR) if you need - to access specific paths. - - If `script` is None all files in `path` will be frozen. - - If `script` is an iterable then freeze() is called on all items of the - iterable (with the same `path` and `opt` passed through). - - If `script` is a string then it specifies the file or directory to - freeze, and can include extra directories before the file or last - directory. The file or directory will be searched for in `path`. If - `script` is a directory then all files in that directory will be frozen. - - `opt` is the optimisation level to pass to mpy-cross when compiling .py - to .mpy. - """ - - freeze_internal(KIND_AUTO, path, script, opt) - - -def freeze_as_str(path): - """Freeze the given `path` and all .py scripts within it as a string, - which will be compiled upon import. - """ - - freeze_internal(KIND_AS_STR, path, None, 0) - - -def freeze_as_mpy(path, script=None, opt=0): - """Freeze the input (see above) by first compiling the .py scripts to - .mpy files, then freezing the resulting .mpy files. - """ - - freeze_internal(KIND_AS_MPY, path, script, opt) - - -def freeze_mpy(path, script=None, opt=0): - """Freeze the input (see above), which must be .mpy files that are - frozen directly. - """ - - freeze_internal(KIND_MPY, path, script, opt) - - -########################################################################### -# Internal implementation - -KIND_AUTO = 0 -KIND_AS_STR = 1 -KIND_AS_MPY = 2 -KIND_MPY = 3 +import manifestfile VARS = {} -manifest_list = [] - - -class IncludeOptions: - def __init__(self, **kwargs): - self._kwargs = kwargs - self._defaults = {} - - def defaults(self, **kwargs): - self._defaults = kwargs - - def __getattr__(self, name): - return self._kwargs.get(name, self._defaults.get(name, None)) - class FreezeError(Exception): pass @@ -163,15 +46,6 @@ def system(cmd): return -1, er.output -def convert_path(path): - # Perform variable substituion. - for name, value in VARS.items(): - path = path.replace("$({})".format(name), value) - # Convert to absolute path (so that future operations don't rely on - # still being chdir'ed). - return os.path.abspath(path) - - def get_timestamp(path, default=None): try: stat = os.stat(path) @@ -182,119 +56,64 @@ def get_timestamp(path, default=None): return default -def get_timestamp_newest(path): - ts_newest = 0 - for dirpath, dirnames, filenames in os.walk(path, followlinks=True): - for f in filenames: - ts_newest = max(ts_newest, get_timestamp(os.path.join(dirpath, f))) - return ts_newest - - def mkdir(filename): path = os.path.dirname(filename) if not os.path.isdir(path): os.makedirs(path) -def freeze_internal(kind, path, script, opt): - path = convert_path(path) - if not os.path.isdir(path): - raise FreezeError("freeze path must be a directory: {}".format(path)) - if script is None and kind == KIND_AS_STR: - manifest_list.append((KIND_AS_STR, path, script, opt)) - elif script is None or isinstance(script, str) and script.find(".") == -1: - # Recursively search `path` for files to freeze, optionally restricted - # to a subdirectory specified by `script` - if script is None: - subdir = "" - else: - subdir = "/" + script - for dirpath, dirnames, filenames in os.walk(path + subdir, followlinks=True): - for f in filenames: - freeze_internal(kind, path, (dirpath + "/" + f)[len(path) + 1 :], opt) - elif not isinstance(script, str): - # `script` is an iterable of items to freeze - for s in script: - freeze_internal(kind, path, s, opt) - else: - # `script` should specify an individual file to be frozen - extension_kind = {KIND_AS_MPY: ".py", KIND_MPY: ".mpy"} - if kind == KIND_AUTO: - for k, ext in extension_kind.items(): - if script.endswith(ext): - kind = k - break - else: - print("warn: unsupported file type, skipped freeze: {}".format(script)) - return - wanted_extension = extension_kind[kind] - if not script.endswith(wanted_extension): - raise FreezeError("expecting a {} file, got {}".format(wanted_extension, script)) - manifest_list.append((kind, path, script, opt)) - - # Formerly make-frozen.py. # This generates: # - MP_FROZEN_STR_NAMES macro # - mp_frozen_str_sizes # - mp_frozen_str_content -def generate_frozen_str_content(paths): - def module_name(f): - return f - - modules = [] - output = [b"#include \n"] - - for path in paths: - root = path.rstrip("/") - root_len = len(root) - - for dirpath, dirnames, filenames in os.walk(root): - for f in filenames: - fullpath = dirpath + "/" + f - st = os.stat(fullpath) - modules.append((path, fullpath[root_len + 1 :], st)) - - output.append(b"#define MP_FROZEN_STR_NAMES \\\n") - for _path, f, st in modules: - m = module_name(f) - output.append(b'"%s\\0" \\\n' % m.encode()) +def generate_frozen_str_content(modules): + output = [ + b"#include \n", + b"#define MP_FROZEN_STR_NAMES \\\n", + ] + + for _, target_path in modules: + print("STR", target_path) + output.append(b'"%s\\0" \\\n' % target_path.encode()) output.append(b"\n") output.append(b"const uint32_t mp_frozen_str_sizes[] = { ") - for _path, f, st in modules: + for full_path, _ in modules: + st = os.stat(full_path) output.append(b"%d, " % st.st_size) output.append(b"0 };\n") output.append(b"const char mp_frozen_str_content[] = {\n") - for path, f, st in modules: - data = open(path + "/" + f, "rb").read() - - # We need to properly escape the script data to create a C string. - # When C parses hex characters of the form \x00 it keeps parsing the hex - # data until it encounters a non-hex character. Thus one must create - # strings of the form "data\x01" "abc" to properly encode this kind of - # data. We could just encode all characters as hex digits but it's nice - # to be able to read the resulting C code as ASCII when possible. - - data = bytearray(data) # so Python2 extracts each byte as an integer - esc_dict = {ord("\n"): b"\\n", ord("\r"): b"\\r", ord('"'): b'\\"', ord("\\"): b"\\\\"} - output.append(b'"') - break_str = False - for c in data: - try: - output.append(esc_dict[c]) - except KeyError: - if 32 <= c <= 126: - if break_str: - output.append(b'" "') - break_str = False - output.append(chr(c).encode()) - else: - output.append(b"\\x%02x" % c) - break_str = True - output.append(b'\\0"\n') + for full_path, _ in modules: + with open(full_path, "rb") as f: + data = f.read() + + # We need to properly escape the script data to create a C string. + # When C parses hex characters of the form \x00 it keeps parsing the hex + # data until it encounters a non-hex character. Thus one must create + # strings of the form "data\x01" "abc" to properly encode this kind of + # data. We could just encode all characters as hex digits but it's nice + # to be able to read the resulting C code as ASCII when possible. + + data = bytearray(data) # so Python2 extracts each byte as an integer + esc_dict = {ord("\n"): b"\\n", ord("\r"): b"\\r", ord('"'): b'\\"', ord("\\"): b"\\\\"} + output.append(b'"') + break_str = False + for c in data: + try: + output.append(esc_dict[c]) + except KeyError: + if 32 <= c <= 126: + if break_str: + output.append(b'" "') + break_str = False + output.append(chr(c).encode()) + else: + output.append(b"\\x%02x" % c) + break_str = True + output.append(b'\\0"\n') output.append(b'"\\0"\n};\n\n') return b"".join(output) @@ -340,14 +159,13 @@ def main(): print("mpy-cross not found at {}, please build it first".format(MPY_CROSS)) sys.exit(1) + manifest = manifestfile.ManifestFile(manifestfile.MODE_FREEZE, VARS) + # Include top-level inputs, to generate the manifest for input_manifest in args.files: try: - if input_manifest.endswith(".py"): - include(input_manifest) - else: - exec(input_manifest) - except FreezeError as er: + manifest.execute(input_manifest) + except manifestfile.ManifestFileError as er: print('freeze error executing "{}": {}'.format(input_manifest, er.args[0])) sys.exit(1) @@ -355,22 +173,25 @@ def main(): str_paths = [] mpy_files = [] ts_newest = 0 - for kind, path, script, opt in manifest_list: - if kind == KIND_AS_STR: - str_paths.append(path) - ts_outfile = get_timestamp_newest(path) - elif kind == KIND_AS_MPY: - infile = "{}/{}".format(path, script) - outfile = "{}/frozen_mpy/{}.mpy".format(args.build_dir, script[:-3]) - ts_infile = get_timestamp(infile) + for full_path, target_path, timestamp, kind, version, opt in manifest.files(): + if kind == manifestfile.KIND_FREEZE_AS_STR: + str_paths.append( + ( + full_path, + target_path, + ) + ) + ts_outfile = timestamp + elif kind == manifestfile.KIND_FREEZE_AS_MPY: + outfile = "{}/frozen_mpy/{}.mpy".format(args.build_dir, target_path[:-3]) ts_outfile = get_timestamp(outfile, 0) - if ts_infile >= ts_outfile: - print("MPY", script) + if timestamp >= ts_outfile: + print("MPY", target_path) mkdir(outfile) res, out = system( [MPY_CROSS] + args.mpy_cross_flags.split() - + ["-o", outfile, "-s", script, "-O{}".format(opt), infile] + + ["-o", outfile, "-s", target_path, "-O{}".format(opt), full_path] ) if res != 0: print("error compiling {}:".format(infile)) @@ -379,10 +200,9 @@ def main(): ts_outfile = get_timestamp(outfile) mpy_files.append(outfile) else: - assert kind == KIND_MPY - infile = "{}/{}".format(path, script) - mpy_files.append(infile) - ts_outfile = get_timestamp(infile) + assert kind == manifestfile.KIND_FREEZE_MPY + mpy_files.append(full_path) + ts_outfile = timestamp ts_newest = max(ts_newest, ts_outfile) # Check if output file needs generating diff --git a/tools/manifestfile.py b/tools/manifestfile.py new file mode 100644 index 000000000000..cb155da2101c --- /dev/null +++ b/tools/manifestfile.py @@ -0,0 +1,416 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2022 Jim Mussared +# Copyright (c) 2019 Damien P. George +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +from __future__ import print_function +import os +import sys +import glob + +__all__ = ["ManifestFileError", "ManifestFile"] + +# Allow freeze*() etc. +MODE_FREEZE = 1 +# Only allow include/require/module/package. +MODE_COMPILE = 2 + + +# In compile mode, .py -> KIND_COMPILE_AS_MPY +# In freeze mode, .py -> KIND_FREEZE_AS_MPY, .mpy->KIND_FREEZE_MPY +KIND_AUTO = 1 +# Freeze-mode only, .py -> KIND_FREEZE_AS_MPY, .mpy->KIND_FREEZE_MPY +KIND_FREEZE_AUTO = 2 + +# Freeze-mode only, The .py file will be frozen as text. +KIND_FREEZE_AS_STR = 3 +# Freeze-mode only, The .py file will be compiled and frozen as bytecode. +KIND_FREEZE_AS_MPY = 4 +# Freeze-mode only, The .mpy file will be frozen directly. +KIND_FREEZE_MPY = 5 +# Compile mode only, the .py file should be compiled to .mpy. +KIND_COMPILE_AS_MPY = 6 + +# File on the local filesystem. +FILE_TYPE_LOCAL = 1 +# URL to file. (TODO) +FILE_TYPE_HTTP = 2 + + +class ManifestFileError(Exception): + pass + + +# Turns a dict of options into a object with attributes used to turn the +# kwargs passed to include() and require into the "options" global in the +# included manifest. +# options = IncludeOptions(foo="bar", blah="stuff") +# options.foo # "bar" +# options.blah # "stuff" +class IncludeOptions: + def __init__(self, **kwargs): + self._kwargs = kwargs + self._defaults = {} + + def defaults(self, **kwargs): + self._defaults = kwargs + + def __getattr__(self, name): + return self._kwargs.get(name, self._defaults.get(name, None)) + + +class ManifestFile: + def __init__(self, mode, path_vars=None): + # Either MODE_FREEZE or MODE_COMPILE. + self._mode = mode + # Path substition variables. + self._path_vars = path_vars or {} + # List of files references by this manifest. + # Tuple of (file_type, full_path, target_path, timestamp, kind, version, opt) + self._manifest_files = [] + # Don't allow including the same file twice. + self._visited = set() + + def _resolve_path(self, path): + # Convert path to an absolute path, applying variable substitutions. + for name, value in self._path_vars.items(): + if value is not None: + path = path.replace("$({})".format(name), value) + return os.path.abspath(path) + + def _manifest_globals(self, kwargs): + # This is the "API" available to a manifest file. + return { + "metadata": self.metadata, + "include": self.include, + "require": self.require, + "package": self.package, + "module": self.module, + "freeze": self.freeze, + "freeze_as_str": self.freeze_as_str, + "freeze_as_mpy": self.freeze_as_mpy, + "freeze_mpy": self.freeze_mpy, + "options": IncludeOptions(**kwargs), + } + + def files(self): + return self._manifest_files + + def execute(self, manifest_file): + if manifest_file.endswith(".py"): + # Execute file from filesystem. + self.include(manifest_file) + else: + # Execute manifest code snippet. + try: + exec(manifest_file, self._manifest_globals({})) + except Exception as er: + raise ManifestFileError("Error in manifest: {}".format(er)) + + def _add_file(self, full_path, target_path, kind=KIND_AUTO, version=None, opt=None): + # Check file exists and get timestamp. + try: + stat = os.stat(full_path) + timestamp = stat.st_mtime + except OSError: + raise ManifestFileError("cannot stat {}".format(full_path)) + + # Map the AUTO kinds to their actual kind based on mode and extension. + _, ext = os.path.splitext(full_path) + if self._mode == MODE_FREEZE: + if kind in ( + KIND_AUTO, + KIND_FREEZE_AUTO, + ): + if ext.lower() == ".py": + kind = KIND_FREEZE_AS_MPY + elif ext.lower() == ".mpy": + kind = KIND_FREEZE_MPY + else: + if kind != KIND_AUTO: + raise ManifestFileError("Not in freeze mode") + if ext.lower() != ".py": + raise ManifestFileError("Expected .py file") + kind = KIND_COMPILE_AS_MPY + + self._manifest_files.append( + (FILE_TYPE_LOCAL, full_path, target_path, timestamp, kind, version, opt) + ) + + def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=False): + base_path = self._resolve_path(base_path) + + if files: + # Use explicit list of files (relative to package_path). + for file in files: + if package_path: + file = os.path.join(package_path, file) + self._add_file( + os.path.join(base_path, file), file, kind=kind, version=None, opt=opt + ) + else: + if base_path: + prev_cwd = os.getcwd() + os.chdir(self._resolve_path(base_path)) + + # Find all candidate files. + for dirpath, _, filenames in os.walk(package_path or ".", followlinks=True): + for file in filenames: + file = os.path.relpath(os.path.join(dirpath, file), ".") + _, ext = os.path.splitext(file) + if ext.lower() in exts: + self._add_file( + os.path.join(base_path, file), + file, + kind=kind, + version=None, + opt=opt, + ) + elif strict: + raise ManifestFileError("Unexpected file type") + + if base_path: + os.chdir(prev_cwd) + + def metadata(self, description=None, version=None): + # TODO + pass + + def include_maybe(self, manifest_path, **kwargs): + """ + Include the manifest file if it exists. See docs for include(). + """ + if os.path.exists(manifest_path): + self.include(manifest_path, **kwargs) + + def include(self, manifest_path, **kwargs): + """ + Include another manifest. + + The manifest argument can be a string (filename) or an iterable of + strings. + + Relative paths are resolved with respect to the current manifest file. + + Optional kwargs can be provided which will be available to the + included script via the `options` variable. + + e.g. include("path.py", extra_features=True) + + in path.py: + options.defaults(standard_features=True) + + # freeze minimal modules. + if options.standard_features: + # freeze standard modules. + if options.extra_features: + # freeze extra modules. + """ + if not isinstance(manifest_path, str): + for m in manifest_path: + self.include(m) + else: + manifest_path = self._resolve_path(manifest_path) + if manifest_path in self._visited: + return + self._visited.add(manifest_path) + with open(manifest_path) as f: + # Make paths relative to this manifest file while processing it. + # Applies to includes and input files. + prev_cwd = os.getcwd() + os.chdir(os.path.dirname(manifest_path)) + try: + exec(f.read(), self._manifest_globals(kwargs)) + except Exception as er: + raise ManifestFileError( + "Error in manifest file: {}: {}".format(manifest_path, er) + ) + os.chdir(prev_cwd) + + def require(self, name, version=None, **kwargs): + """ + Require a module by name from micropython-lib. + + This is a shortcut for + """ + if self._path_vars["MPY_LIB_DIR"]: + for manifest_path in glob.glob( + os.path.join(self._path_vars["MPY_LIB_DIR"], "**", name, "manifest.py"), + recursive=True, + ): + self.include(manifest_path, **kwargs) + return + raise ValueError("Library not found in local micropython-lib: {}".format(name)) + else: + # TODO: HTTP request to obtain URLs from manifest.json. + raise ValueError("micropython-lib not available for require('{}').", name) + + def package(self, package_path, files=None, base_path=".", opt=None): + """ + Define a package, optionally restricting to a set of files. + + Simple case, a package in the current directory: + package("foo") + will include all .py files in foo, and will be stored as foo/bar/baz.py. + + If the package isn't in the current directory, use base_path: + package("foo", base_path="src") + + To restrict to certain files in the package use files (note: paths should be relative to the package): + package("foo", files=["bar/baz.py"]) + """ + # Include "base_path/package_path/**/*.py" --> "package_path/**/*.py" + self._search(base_path, package_path, files, exts=(".py",), kind=KIND_AUTO, opt=opt) + + def module(self, module_path, base_path=".", opt=None): + """ + Include a single Python file as a module. + + If the file is in the current directory: + module("foo.py") + + Otherwise use base_path to locate the file: + module("foo.py", "src/drivers") + """ + # Include "base_path/module_path" --> "module_path" + base_path = self._resolve_path(base_path) + _, ext = os.path.splitext(module_path) + if ext.lower() != ".py": + raise ManifestFileError("module must be .py file") + # TODO: version None + self._add_file(os.path.join(base_path, module_path), module_path, version=None, opt=opt) + + def _freeze_internal(self, path, script, exts, kind, opt): + if script is None: + self._search(path, None, None, exts=exts, kind=kind, opt=opt) + elif isinstance(script, str) and os.path.isdir(os.path.join(path, script)): + self._search(path, script, None, exts=exts, kind=kind, opt=opt) + elif not isinstance(script, str): + self._search(path, None, script, exts=exts, kind=kind, opt=opt) + else: + self._search(path, None, (script,), exts=exts, kind=kind, opt=opt) + + def freeze(self, path, script=None, opt=None): + """ + Freeze the input, automatically determining its type. A .py script + will be compiled to a .mpy first then frozen, and a .mpy file will be + frozen directly. + + `path` must be a directory, which is the base directory to _search for + files from. When importing the resulting frozen modules, the name of + the module will start after `path`, ie `path` is excluded from the + module name. + + If `path` is relative, it is resolved to the current manifest.py. + Use $(MPY_DIR), $(MPY_LIB_DIR), $(PORT_DIR), $(BOARD_DIR) if you need + to access specific paths. + + If `script` is None all files in `path` will be frozen. + + If `script` is an iterable then freeze() is called on all items of the + iterable (with the same `path` and `opt` passed through). + + If `script` is a string then it specifies the file or directory to + freeze, and can include extra directories before the file or last + directory. The file or directory will be _searched for in `path`. If + `script` is a directory then all files in that directory will be frozen. + + `opt` is the optimisation level to pass to mpy-cross when compiling .py + to .mpy. + """ + self._freeze_internal(path, script, exts=(".py", ".mpy"), kind=KIND_FREEZE_AUTO, opt=opt) + + def freeze_as_str(self, path): + """ + Freeze the given `path` and all .py scripts within it as a string, + which will be compiled upon import. + """ + self._search(path, None, None, exts=(".py"), kind=KIND_FREEZE_AS_STR) + + def freeze_as_mpy(self, path, script=None, opt=None): + """ + Freeze the input (see above) by first compiling the .py scripts to + .mpy files, then freezing the resulting .mpy files. + """ + self._freeze_internal(path, script, exts=(".py"), kind=KIND_FREEZE_AS_MPY, opt=opt) + + def freeze_mpy(self, path, script=None, opt=None): + """ + Freeze the input (see above), which must be .mpy files that are + frozen directly. + """ + self._freeze_internal(path, script, exts=(".mpy"), kind=KIND_FREEZE_MPY, opt=opt) + + +def main(): + import argparse + + cmd_parser = argparse.ArgumentParser(description="List the files referenced by a manifest.") + cmd_parser.add_argument("--freeze", action="store_true", help="freeze mode") + cmd_parser.add_argument("--compile", action="store_true", help="compile mode") + cmd_parser.add_argument( + "--lib", + default=os.path.join(os.path.dirname(__file__), "../lib/micropython-lib"), + help="path to micropython-lib repo", + ) + cmd_parser.add_argument("--port", default=None, help="path to port dir") + cmd_parser.add_argument("--board", default=None, help="path to board dir") + cmd_parser.add_argument( + "--top", + default=os.path.join(os.path.dirname(__file__), ".."), + help="path to micropython repo", + ) + cmd_parser.add_argument("files", nargs="+", help="input manifest.py") + args = cmd_parser.parse_args() + + path_vars = { + "MPY_DIR": os.path.abspath(args.top) if args.top else None, + "BOARD_DIR": os.path.abspath(args.board) if args.board else None, + "PORT_DIR": os.path.abspath(args.port) if args.port else None, + "MPY_LIB_DIR": os.path.abspath(args.lib) if args.lib else None, + } + + mode = None + if args.freeze: + mode = MODE_FREEZE + elif args.compile: + mode = MODE_COMPILE + else: + print("Error: No mode specified.", file=sys.stderr) + exit(1) + + m = ManifestFile(mode, path_vars) + for manifest_file in args.files: + try: + m.execute(manifest_file) + except ManifestFileError as er: + print(er, file=sys.stderr) + exit(1) + for f in m.files(): + print(f) + + +if __name__ == "__main__": + main() From e42809531f735b376409d458e51e25f9708ec551 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 15 Jul 2022 23:01:06 +1000 Subject: [PATCH 1687/4290] mpy-cross/mpy_cross: Add Python wrapper for mpy-cross. Rather than invoking mpy-cross directly via system/subprocess in our build tools and other tools, this provides a Python interface for it. Based on https://gitlab.com/alelec/mpy_cross (with the intention of eventually replacing that as the "official" pypi distribution once setup.py etc are added). Signed-off-by: Jim Mussared --- mpy-cross/mpy_cross/__init__.py | 113 ++++++++++++++++++++++++++++++++ mpy-cross/mpy_cross/__main__.py | 38 +++++++++++ 2 files changed, 151 insertions(+) create mode 100644 mpy-cross/mpy_cross/__init__.py create mode 100644 mpy-cross/mpy_cross/__main__.py diff --git a/mpy-cross/mpy_cross/__init__.py b/mpy-cross/mpy_cross/__init__.py new file mode 100644 index 000000000000..d4c0930bb919 --- /dev/null +++ b/mpy-cross/mpy_cross/__init__.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2022 Andrew Leech +# Copyright (c) 2022 Jim Mussared +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +from __future__ import print_function +import os +import stat +import subprocess + +NATIVE_ARCH_X86 = "x86" +NATIVE_ARCH_X64 = "x64" +NATIVE_ARCH_ARMV6 = "armv6" +NATIVE_ARCH_ARMV6M = "armv6m" +NATIVE_ARCH_ARMV7M = "armv7m" +NATIVE_ARCH_ARMV7EM = "armv7em" +NATIVE_ARCH_ARMV7EMSP = "armv7emsp" +NATIVE_ARCH_ARMV7EMDP = "armv7emdp" +NATIVE_ARCH_XTENSA = "xtensa" +NATIVE_ARCH_XTENSAWIN = "xtensawin" + +NATIVE_ARCHS = [ + NATIVE_ARCH_X86, + NATIVE_ARCH_X64, + NATIVE_ARCH_ARMV6, + NATIVE_ARCH_ARMV6M, + NATIVE_ARCH_ARMV7M, + NATIVE_ARCH_ARMV7EM, + NATIVE_ARCH_ARMV7EMSP, + NATIVE_ARCH_ARMV7EMDP, + NATIVE_ARCH_XTENSA, + NATIVE_ARCH_XTENSAWIN, +] + +__all__ = ["compile", "run", "CrossCompileError"] + + +class CrossCompileError(Exception): + pass + + +def find_mpy_cross_binary(mpy_cross): + if mpy_cross: + return mpy_cross + return os.path.abspath(os.path.join(os.path.dirname(__file__), "../mpy-cross")) + + +def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, extra_args=None): + if not src: + raise ValueError("src is required") + if not os.path.exists(src): + raise CrossCompileError("Input .py file not found: {}.".format(src_py)) + + args = [] + + if src_path: + args += ["-s", src_path] + + if dest: + args += ["-o", dest] + + if march: + args += ["-march", march] + + if opt is not None: + args += ["-O{}".format(opt)] + + if extra_args: + args += extra_args + + args += [src] + + run(args, mpy_cross) + + +def run(args, mpy_cross=None): + mpy_cross = find_mpy_cross_binary(mpy_cross) + + if not os.path.exists(mpy_cross): + raise CrossCompileError("mpy-cross binary not found at {}.".format(mpy_cross)) + + try: + st = os.stat(mpy_cross) + os.chmod(mpy_cross, st.st_mode | stat.S_IEXEC) + except OSError: + pass + + try: + subprocess.check_output([mpy_cross] + args, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as er: + raise CrossCompileError(er.output) diff --git a/mpy-cross/mpy_cross/__main__.py b/mpy-cross/mpy_cross/__main__.py new file mode 100644 index 000000000000..9d957bca025d --- /dev/null +++ b/mpy-cross/mpy_cross/__main__.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2022 Andrew Leech +# Copyright (c) 2022 Jim Mussared +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +from __future__ import print_function +import argparse +import sys + +from . import run, CrossCompileError + +try: + run(sys.argv[1:]) +except CrossCompileError as er: + print(er.args[0], file=sys.stderr) + raise SystemExit(1) From 6bd0ec7a70496dc51d8dc6c706919ef398b0346e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 15 Jul 2022 23:06:15 +1000 Subject: [PATCH 1688/4290] tools/makemanifest.py: Update to use mpy_cross module. Signed-off-by: Jim Mussared --- tools/makemanifest.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 800a25435eb9..2e7021040dd9 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -29,6 +29,9 @@ import os import subprocess +sys.path.append(os.path.join(os.path.dirname(__file__), "../mpy-cross")) +import mpy_cross + import manifestfile VARS = {} @@ -173,7 +176,7 @@ def main(): str_paths = [] mpy_files = [] ts_newest = 0 - for full_path, target_path, timestamp, kind, version, opt in manifest.files(): + for _file_type, full_path, target_path, timestamp, kind, version, opt in manifest.files(): if kind == manifestfile.KIND_FREEZE_AS_STR: str_paths.append( ( @@ -188,14 +191,18 @@ def main(): if timestamp >= ts_outfile: print("MPY", target_path) mkdir(outfile) - res, out = system( - [MPY_CROSS] - + args.mpy_cross_flags.split() - + ["-o", outfile, "-s", target_path, "-O{}".format(opt), full_path] - ) - if res != 0: - print("error compiling {}:".format(infile)) - sys.stdout.buffer.write(out) + try: + mpy_cross.compile( + full_path, + dest=outfile, + src_path=target_path, + opt=opt, + mpy_cross=MPY_CROSS, + extra_args=args.mpy_cross_flags.split(), + ) + except mpy_cross.CrossCompileError as ex: + print("error compiling {}:".format(target_path)) + print(ex.args[0]) raise SystemExit(1) ts_outfile = get_timestamp(outfile) mpy_files.append(outfile) From e9a28ce312b75a4f2b3b7a8c3e38b7766cb567b3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 15 Jul 2022 23:42:51 +1000 Subject: [PATCH 1689/4290] tools/manifestfile.py: Allow include of directory path. If an include path is a directory, then it implicitly grabs the manifest.py file inside that directory. This simplifies most manifest.py files. Signed-off-by: Jim Mussared --- tools/manifestfile.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/manifestfile.py b/tools/manifestfile.py index cb155da2101c..bf626c22b38d 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -198,13 +198,6 @@ def metadata(self, description=None, version=None): # TODO pass - def include_maybe(self, manifest_path, **kwargs): - """ - Include the manifest file if it exists. See docs for include(). - """ - if os.path.exists(manifest_path): - self.include(manifest_path, **kwargs) - def include(self, manifest_path, **kwargs): """ Include another manifest. @@ -214,6 +207,9 @@ def include(self, manifest_path, **kwargs): Relative paths are resolved with respect to the current manifest file. + If the path is to a directory, then it implicitly includes the + manifest.py file inside that directory. + Optional kwargs can be provided which will be available to the included script via the `options` variable. @@ -233,6 +229,9 @@ def include(self, manifest_path, **kwargs): self.include(m) else: manifest_path = self._resolve_path(manifest_path) + # Including a directory grabs the manifest.py inside it. + if os.path.isdir(manifest_path): + manifest_path = os.path.join(manifest_path, "manifest.py") if manifest_path in self._visited: return self._visited.add(manifest_path) From bc23f207cefed82172551288ebb8686ee2c512a3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 11 Aug 2022 00:16:48 +1000 Subject: [PATCH 1690/4290] tools/manifestfile.py: Allow require() to specify unix packages. By default, don't include micropython-lib/unix-ffi in the search. If unix_ffi=True is passed to require(), then include unix-ffi and make it take precedence over the other locations (e.g. python-stdlib). This does two things: - Prevents non-unix builds from using unix-only packages. - Allows the unix build to optionally use a more full-featured (e.g. ffi) based package, even with the same name as one from e.g. stdlib. Signed-off-by: Jim Mussared --- tools/manifestfile.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tools/manifestfile.py b/tools/manifestfile.py index bf626c22b38d..61560e4565ab 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -248,19 +248,28 @@ def include(self, manifest_path, **kwargs): ) os.chdir(prev_cwd) - def require(self, name, version=None, **kwargs): + def require(self, name, version=None, unix_ffi=False, **kwargs): """ Require a module by name from micropython-lib. - This is a shortcut for + Optionally specify unix_ffi=True to use a module from the unix-ffi directory. """ if self._path_vars["MPY_LIB_DIR"]: - for manifest_path in glob.glob( - os.path.join(self._path_vars["MPY_LIB_DIR"], "**", name, "manifest.py"), - recursive=True, - ): - self.include(manifest_path, **kwargs) - return + lib_dirs = ["micropython", "python-stdlib", "python-ecosys"] + if unix_ffi: + # Search unix-ffi only if unix_ffi=True, and make unix-ffi modules + # take precedence. + lib_dirs = ["unix-ffi"] + lib_dirs + + for lib_dir in lib_dirs: + for manifest_path in glob.glob( + os.path.join( + self._path_vars["MPY_LIB_DIR"], lib_dir, "**", name, "manifest.py" + ), + recursive=True, + ): + self.include(manifest_path, **kwargs) + return raise ValueError("Library not found in local micropython-lib: {}".format(name)) else: # TODO: HTTP request to obtain URLs from manifest.json. From 5852fd7708d02d6ca85e4a5ed01d8263e3962631 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 12 Aug 2022 11:30:56 +1000 Subject: [PATCH 1691/4290] tools/manifestfile.py: Allow manifests to set metadata. The metadata can be version, description, and license. After executing a manifest, the top-level metadata can be queried, and also each file output from the manifest will have the metadata of the containing manifest. Use the version metadata to "tag" files before freezing such that they have __version__ available. --- tools/makemanifest.py | 46 +++++++++++----------- tools/manifestfile.py | 92 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 102 insertions(+), 36 deletions(-) diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 2e7021040dd9..d059d4a2660f 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -176,34 +176,36 @@ def main(): str_paths = [] mpy_files = [] ts_newest = 0 - for _file_type, full_path, target_path, timestamp, kind, version, opt in manifest.files(): - if kind == manifestfile.KIND_FREEZE_AS_STR: + for result in manifest.files(): + if result.kind == manifestfile.KIND_FREEZE_AS_STR: str_paths.append( ( - full_path, - target_path, + result.full_path, + result.target_path, ) ) - ts_outfile = timestamp - elif kind == manifestfile.KIND_FREEZE_AS_MPY: - outfile = "{}/frozen_mpy/{}.mpy".format(args.build_dir, target_path[:-3]) + ts_outfile = result.timestamp + elif result.kind == manifestfile.KIND_FREEZE_AS_MPY: + outfile = "{}/frozen_mpy/{}.mpy".format(args.build_dir, result.target_path[:-3]) ts_outfile = get_timestamp(outfile, 0) - if timestamp >= ts_outfile: - print("MPY", target_path) + if result.timestamp >= ts_outfile: + print("MPY", result.target_path) mkdir(outfile) - try: - mpy_cross.compile( - full_path, - dest=outfile, - src_path=target_path, - opt=opt, - mpy_cross=MPY_CROSS, - extra_args=args.mpy_cross_flags.split(), - ) - except mpy_cross.CrossCompileError as ex: - print("error compiling {}:".format(target_path)) - print(ex.args[0]) - raise SystemExit(1) + # Add __version__ to the end of the file before compiling. + with manifestfile.tagged_py_file(result.full_path, result.metadata) as tagged_path: + try: + mpy_cross.compile( + tagged_path, + dest=outfile, + src_path=result.target_path, + opt=result.opt, + mpy_cross=MPY_CROSS, + extra_args=args.mpy_cross_flags.split(), + ) + except mpy_cross.CrossCompileError as ex: + print("error compiling {}:".format(target_path)) + print(ex.args[0]) + raise SystemExit(1) ts_outfile = get_timestamp(outfile) mpy_files.append(outfile) else: diff --git a/tools/manifestfile.py b/tools/manifestfile.py index 61560e4565ab..84c79ed82b28 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -26,9 +26,12 @@ # THE SOFTWARE. from __future__ import print_function +import contextlib import os import sys import glob +import tempfile +from collections import namedtuple __all__ = ["ManifestFileError", "ManifestFile"] @@ -63,6 +66,37 @@ class ManifestFileError(Exception): pass +# The set of files that this manifest references. +ManifestOutput = namedtuple( + "ManifestOutput", + [ + "file_type", # FILE_TYPE_*. + "full_path", # The input file full path. + "target_path", # The target path on the device. + "timestamp", # Last modified date of the input file. + "kind", # KIND_*. + "metadata", # Metadata for the containing package. + "opt", # Optimisation level (or None). + ], +) + + +# Represent the metadata for a package. +class ManifestMetadata: + def __init__(self): + self.version = None + self.description = None + self.license = None + + def update(self, description=None, version=None, license=None): + if description: + self.description = description + if version: + self.version = version + if license: + self.license = version + + # Turns a dict of options into a object with attributes used to turn the # kwargs passed to include() and require into the "options" global in the # included manifest. @@ -87,11 +121,12 @@ def __init__(self, mode, path_vars=None): self._mode = mode # Path substition variables. self._path_vars = path_vars or {} - # List of files references by this manifest. - # Tuple of (file_type, full_path, target_path, timestamp, kind, version, opt) + # List of files (as ManifestFileResult) references by this manifest. self._manifest_files = [] # Don't allow including the same file twice. self._visited = set() + # Stack of metadata for each level. + self._metadata = [ManifestMetadata()] def _resolve_path(self, path): # Convert path to an absolute path, applying variable substitutions. @@ -121,7 +156,7 @@ def files(self): def execute(self, manifest_file): if manifest_file.endswith(".py"): # Execute file from filesystem. - self.include(manifest_file) + self.include(manifest_file, top_level=True) else: # Execute manifest code snippet. try: @@ -129,7 +164,7 @@ def execute(self, manifest_file): except Exception as er: raise ManifestFileError("Error in manifest: {}".format(er)) - def _add_file(self, full_path, target_path, kind=KIND_AUTO, version=None, opt=None): + def _add_file(self, full_path, target_path, kind=KIND_AUTO, opt=None): # Check file exists and get timestamp. try: stat = os.stat(full_path) @@ -156,7 +191,9 @@ def _add_file(self, full_path, target_path, kind=KIND_AUTO, version=None, opt=No kind = KIND_COMPILE_AS_MPY self._manifest_files.append( - (FILE_TYPE_LOCAL, full_path, target_path, timestamp, kind, version, opt) + ManifestOutput( + FILE_TYPE_LOCAL, full_path, target_path, timestamp, kind, self._metadata[-1], opt + ) ) def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=False): @@ -167,9 +204,7 @@ def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=F for file in files: if package_path: file = os.path.join(package_path, file) - self._add_file( - os.path.join(base_path, file), file, kind=kind, version=None, opt=opt - ) + self._add_file(os.path.join(base_path, file), file, kind=kind, opt=opt) else: if base_path: prev_cwd = os.getcwd() @@ -185,7 +220,6 @@ def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=F os.path.join(base_path, file), file, kind=kind, - version=None, opt=opt, ) elif strict: @@ -194,11 +228,19 @@ def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=F if base_path: os.chdir(prev_cwd) - def metadata(self, description=None, version=None): - # TODO - pass + def metadata(self, description=None, version=None, license=None): + """ + From within a manifest file, use this to set the metadata for the + package described by current manifest. + + After executing a manifest file (via execute()), call this + to obtain the metadata for the top-level manifest file. + """ + + self._metadata[-1].update(description, version, license) + return self._metadata[-1] - def include(self, manifest_path, **kwargs): + def include(self, manifest_path, top_level=False, **kwargs): """ Include another manifest. @@ -235,6 +277,8 @@ def include(self, manifest_path, **kwargs): if manifest_path in self._visited: return self._visited.add(manifest_path) + if not top_level: + self._metadata.append(ManifestMetadata()) with open(manifest_path) as f: # Make paths relative to this manifest file while processing it. # Applies to includes and input files. @@ -247,6 +291,8 @@ def include(self, manifest_path, **kwargs): "Error in manifest file: {}: {}".format(manifest_path, er) ) os.chdir(prev_cwd) + if not top_level: + self._metadata.pop() def require(self, name, version=None, unix_ffi=False, **kwargs): """ @@ -308,7 +354,7 @@ def module(self, module_path, base_path=".", opt=None): if ext.lower() != ".py": raise ManifestFileError("module must be .py file") # TODO: version None - self._add_file(os.path.join(base_path, module_path), module_path, version=None, opt=opt) + self._add_file(os.path.join(base_path, module_path), module_path, opt=opt) def _freeze_internal(self, path, script, exts, kind, opt): if script is None: @@ -372,6 +418,24 @@ def freeze_mpy(self, path, script=None, opt=None): self._freeze_internal(path, script, exts=(".mpy"), kind=KIND_FREEZE_MPY, opt=opt) +# Generate a temporary file with a line appended to the end that adds __version__. +@contextlib.contextmanager +def tagged_py_file(path, metadata): + dest_fd, dest_path = tempfile.mkstemp(suffix=".py", text=True) + try: + with os.fdopen(dest_fd, "w") as dest: + with open(path, "r") as src: + contents = src.read() + dest.write(contents) + + # Don't overwrite a version definition if the file already has one in it. + if metadata.version and "__version__ =" not in contents: + dest.write("\n\n__version__ = {}\n".format(repr(metadata.version))) + yield dest_path + finally: + os.unlink(dest_path) + + def main(): import argparse From ccd210984e7a959694b2af4937ce953a822c2ea5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 5 Sep 2022 18:23:11 +1000 Subject: [PATCH 1692/4290] lib/micropython-lib: Update to latest version with manifest changes. Signed-off-by: Damien George --- lib/micropython-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/micropython-lib b/lib/micropython-lib index 70e422dc2e88..f3cfc52ab076 160000 --- a/lib/micropython-lib +++ b/lib/micropython-lib @@ -1 +1 @@ -Subproject commit 70e422dc2e885bbaafe6eb7e3d81118e17d4b555 +Subproject commit f3cfc52ab076fc913dc6e266fb7370b418c8f542 From 203dae41fbaceeea9a04dc540b22de4ddd0d5a69 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 15 Jul 2022 23:46:28 +1000 Subject: [PATCH 1693/4290] all: Update all manifest.py files to use new features. Changes in this commit: - Manifest include's now use the directory path where possible (no longer necessary to include the manifest.py file explicitly). - Add manifest.py for all drivers and components that are referenced by port/board manifests. - Replace all uses of freeze() with package()/module(), except for port and board modules. - Use opt=3 everywhere, for consistency and to reduce code size. - Use require() instead of include() for all micropython-lib references. - Remove support for optional board-level manifest.py in mimxrt port, to make it behave the same as other ports (the board must set FROZEN_MANIFEST to a custom manifest.py, which can optionally include the default, port-level manifest). - Also reinstates modules that were accidentally removed from the esp8266 512k build in fbe9417b90474dd1a08749b3a79311a8007a98fb. Signed-off-by: Jim Mussared Signed-off-by: Damien George --- drivers/codec/manifest.py | 1 + drivers/dht/manifest.py | 1 + drivers/display/manifest.py | 11 ++++++++ drivers/hts221/manifest.py | 1 + drivers/lps22h/manifest.py | 1 + drivers/lsm6dsox/manifest.py | 1 + drivers/lsm9ds1/manifest.py | 1 + drivers/neopixel/manifest.py | 6 +---- drivers/nrf24l01/manifest.py | 1 + drivers/onewire/manifest.py | 6 +++++ drivers/sdcard/manifest.py | 1 + extmod/uasyncio/manifest.py | 20 ++++++++------- extmod/webrepl/manifest.py | 3 ++- .../boards/LILYGO_TTGO_LORA32/manifest.py | 2 +- ports/esp32/boards/LOLIN_S2_PICO/manifest.py | 2 +- ports/esp32/boards/UM_FEATHERS2/manifest.py | 2 +- ports/esp32/boards/manifest.py | 25 ++++++++++--------- ports/esp8266/boards/GENERIC/manifest.py | 14 +++++------ ports/esp8266/boards/GENERIC_512K/manifest.py | 13 ++++++---- ports/esp8266/boards/manifest.py | 13 +++++----- ports/mimxrt/boards/manifest.py | 10 +++----- .../arduino_nano_33_ble_sense/manifest.py | 6 ++--- ports/nrf/modules/manifest.py | 4 +-- .../boards/RA4M1_CLICKER/manifest.py | 2 +- ports/renesas-ra/boards/RA4M1_EK/manifest.py | 2 +- ports/renesas-ra/boards/manifest.py | 8 +++--- .../ARDUINO_NANO_RP2040_CONNECT/manifest.py | 20 +++++++-------- ports/rp2/boards/PICO_W/manifest.py | 8 +++--- ports/rp2/boards/manifest.py | 8 +++--- .../boards/ARDUINO_PORTENTA_H7/manifest.py | 10 ++------ .../GARATRONIC_PYBSTICK26_F411/manifest.py | 2 +- ports/stm32/boards/LEGO_HUB_NO6/manifest.py | 2 ++ ports/stm32/boards/LEGO_HUB_NO7/manifest.py | 7 ++---- ports/stm32/boards/PYBD_SF2/manifest.py | 2 +- ports/stm32/boards/manifest.py | 9 ++++--- ports/unix/variants/dev/manifest.py | 2 +- ports/unix/variants/manifest.py | 4 +-- ports/windows/variants/dev/manifest.py | 2 +- 38 files changed, 126 insertions(+), 107 deletions(-) create mode 100644 drivers/codec/manifest.py create mode 100644 drivers/dht/manifest.py create mode 100644 drivers/display/manifest.py create mode 100644 drivers/hts221/manifest.py create mode 100644 drivers/lps22h/manifest.py create mode 100644 drivers/lsm6dsox/manifest.py create mode 100644 drivers/lsm9ds1/manifest.py create mode 100644 drivers/nrf24l01/manifest.py create mode 100644 drivers/onewire/manifest.py create mode 100644 drivers/sdcard/manifest.py diff --git a/drivers/codec/manifest.py b/drivers/codec/manifest.py new file mode 100644 index 000000000000..4ff5d9fc445e --- /dev/null +++ b/drivers/codec/manifest.py @@ -0,0 +1 @@ +module("wm8960.py", opt=3) diff --git a/drivers/dht/manifest.py b/drivers/dht/manifest.py new file mode 100644 index 000000000000..72a4e0d24fcd --- /dev/null +++ b/drivers/dht/manifest.py @@ -0,0 +1 @@ +module("dht.py", opt=3) diff --git a/drivers/display/manifest.py b/drivers/display/manifest.py new file mode 100644 index 000000000000..d1ddff3374ab --- /dev/null +++ b/drivers/display/manifest.py @@ -0,0 +1,11 @@ +# TODO: Split these into separate directories with their own manifests. +options.defaults(lcd160cr=False, ssd1306=False, test=True) + +if options.lcd160cr: + module("lcd160cr.py", opt=3) + + if options.test: + module("lcd160cr_test.py", opt=3) + +if options.ssd1306: + module("ssd1306.py", opt=3) diff --git a/drivers/hts221/manifest.py b/drivers/hts221/manifest.py new file mode 100644 index 000000000000..5f1792665943 --- /dev/null +++ b/drivers/hts221/manifest.py @@ -0,0 +1 @@ +module("hts221.py", opt=3) diff --git a/drivers/lps22h/manifest.py b/drivers/lps22h/manifest.py new file mode 100644 index 000000000000..d30108d93dce --- /dev/null +++ b/drivers/lps22h/manifest.py @@ -0,0 +1 @@ +module("lps22h.py", opt=3) diff --git a/drivers/lsm6dsox/manifest.py b/drivers/lsm6dsox/manifest.py new file mode 100644 index 000000000000..28f4b3565e9f --- /dev/null +++ b/drivers/lsm6dsox/manifest.py @@ -0,0 +1 @@ +module("lsm6dsox.py", opt=3) diff --git a/drivers/lsm9ds1/manifest.py b/drivers/lsm9ds1/manifest.py new file mode 100644 index 000000000000..6779362de7ee --- /dev/null +++ b/drivers/lsm9ds1/manifest.py @@ -0,0 +1 @@ +module("lsm9ds1.py", opt=3) diff --git a/drivers/neopixel/manifest.py b/drivers/neopixel/manifest.py index 27f610adc0ad..561d19574af3 100644 --- a/drivers/neopixel/manifest.py +++ b/drivers/neopixel/manifest.py @@ -1,5 +1 @@ -freeze( - ".", - "neopixel.py", - opt=3, -) +module("neopixel.py", opt=3) diff --git a/drivers/nrf24l01/manifest.py b/drivers/nrf24l01/manifest.py new file mode 100644 index 000000000000..babdb7a52a95 --- /dev/null +++ b/drivers/nrf24l01/manifest.py @@ -0,0 +1 @@ +module("nrf24l01.py", opt=3) diff --git a/drivers/onewire/manifest.py b/drivers/onewire/manifest.py new file mode 100644 index 000000000000..f500a65d780b --- /dev/null +++ b/drivers/onewire/manifest.py @@ -0,0 +1,6 @@ +options.defaults(ds18x20=False) + +module("onewire.py", opt=3) + +if options.ds18x20: + module("ds18x20.py", opt=3) diff --git a/drivers/sdcard/manifest.py b/drivers/sdcard/manifest.py new file mode 100644 index 000000000000..e584b97d9ca6 --- /dev/null +++ b/drivers/sdcard/manifest.py @@ -0,0 +1 @@ +module("sdcard.py", opt=3) diff --git a/extmod/uasyncio/manifest.py b/extmod/uasyncio/manifest.py index f5fa27bfcaa3..d425a467b3af 100644 --- a/extmod/uasyncio/manifest.py +++ b/extmod/uasyncio/manifest.py @@ -1,13 +1,15 @@ -# This list of frozen files doesn't include task.py because that's provided by the C module. -freeze( - "..", +# This list of package files doesn't include task.py because that's provided +# by the C module. +package( + "uasyncio", ( - "uasyncio/__init__.py", - "uasyncio/core.py", - "uasyncio/event.py", - "uasyncio/funcs.py", - "uasyncio/lock.py", - "uasyncio/stream.py", + "__init__.py", + "core.py", + "event.py", + "funcs.py", + "lock.py", + "stream.py", ), + base_path="..", opt=3, ) diff --git a/extmod/webrepl/manifest.py b/extmod/webrepl/manifest.py index c504c7305c0f..6d1a314219ca 100644 --- a/extmod/webrepl/manifest.py +++ b/extmod/webrepl/manifest.py @@ -1 +1,2 @@ -freeze(".", ("webrepl.py", "webrepl_setup.py")) +module("webrepl.py", opt=3) +module("webrepl_setup.py", opt=3) diff --git a/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py b/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py index 0709f8597c07..6c491c8f66de 100644 --- a/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py +++ b/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py @@ -1,4 +1,4 @@ include("$(PORT_DIR)/boards/manifest.py") freeze("modules") -freeze("$(MPY_DIR)/drivers/display", "ssd1306.py") +include("$(MPY_DIR)/drivers/display", ssd1306=True) diff --git a/ports/esp32/boards/LOLIN_S2_PICO/manifest.py b/ports/esp32/boards/LOLIN_S2_PICO/manifest.py index 98d4247c607a..efc37137b2cf 100644 --- a/ports/esp32/boards/LOLIN_S2_PICO/manifest.py +++ b/ports/esp32/boards/LOLIN_S2_PICO/manifest.py @@ -1,4 +1,4 @@ include("$(PORT_DIR)/boards/manifest.py") freeze("./modules") -freeze("$(MPY_DIR)/drivers/display", "ssd1306.py") +include("$(MPY_DIR)/drivers/display", ssd1306=True) diff --git a/ports/esp32/boards/UM_FEATHERS2/manifest.py b/ports/esp32/boards/UM_FEATHERS2/manifest.py index 82ad0c7e4988..3fda1dd8272c 100644 --- a/ports/esp32/boards/UM_FEATHERS2/manifest.py +++ b/ports/esp32/boards/UM_FEATHERS2/manifest.py @@ -1,3 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") -freeze("$(PORT_DIR)/boards/UM_TINYPICO/modules", "dotstar.py") +module("dotstar.py", base_path="$(PORT_DIR)/boards/UM_TINYPICO/modules", opt=3) freeze("modules") diff --git a/ports/esp32/boards/manifest.py b/ports/esp32/boards/manifest.py index 23252442ea46..658d11d5855d 100644 --- a/ports/esp32/boards/manifest.py +++ b/ports/esp32/boards/manifest.py @@ -1,14 +1,15 @@ freeze("$(PORT_DIR)/modules") -freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py")) -freeze("$(MPY_DIR)/extmod", "ntptime.py") -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -freeze("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") -include("$(MPY_DIR)/extmod/webrepl/manifest.py") -include("$(MPY_DIR)/drivers/neopixel/manifest.py") +module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) +module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) +module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/drivers/neopixel") +include("$(MPY_DIR)/extmod/uasyncio") +include("$(MPY_DIR)/extmod/webrepl") -# Freeze some micropython-lib modules. -freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") -freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") -freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") -freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") +# Require some micropython-lib modules. +require("urequests") +require("upysh") +require("umqtt.simple") +require("umqtt.robust") diff --git a/ports/esp8266/boards/GENERIC/manifest.py b/ports/esp8266/boards/GENERIC/manifest.py index ef25040ef8a7..54b916546c34 100644 --- a/ports/esp8266/boards/GENERIC/manifest.py +++ b/ports/esp8266/boards/GENERIC/manifest.py @@ -2,18 +2,18 @@ include("$(PORT_DIR)/boards/manifest.py") # uasyncio -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +include("$(MPY_DIR)/extmod/uasyncio") # drivers -freeze("$(MPY_DIR)/drivers/display", "ssd1306.py") +include("$(MPY_DIR)/drivers/display", ssd1306=True) # micropython-lib: file utilities -freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") +require("upysh") # micropython-lib: requests -freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") -freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py") +require("urequests") +require("urllib.urequest") # micropython-lib: umqtt -freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") -freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") +require("umqtt.simple") +require("umqtt.robust") diff --git a/ports/esp8266/boards/GENERIC_512K/manifest.py b/ports/esp8266/boards/GENERIC_512K/manifest.py index e43d94843fdb..57970a6b4dc1 100644 --- a/ports/esp8266/boards/GENERIC_512K/manifest.py +++ b/ports/esp8266/boards/GENERIC_512K/manifest.py @@ -1,5 +1,8 @@ -freeze("$(BOARD_DIR)", "_boot.py", opt=3) -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -freeze("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/extmod/webrepl/manifest.py") -include("$(MPY_DIR)/drivers/neopixel/manifest.py") +module("_boot.py", opt=3) +module("apa102.py", base_path="$(PORT_DIR)/modules", opt=3) +module("port_diag.py", base_path="$(PORT_DIR)/modules", opt=3) +module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/extmod/webrepl") +include("$(MPY_DIR)/drivers/neopixel") diff --git a/ports/esp8266/boards/manifest.py b/ports/esp8266/boards/manifest.py index c5809717e692..abcee253ffe5 100644 --- a/ports/esp8266/boards/manifest.py +++ b/ports/esp8266/boards/manifest.py @@ -1,7 +1,8 @@ freeze("$(PORT_DIR)/modules") -freeze("$(MPY_DIR)/extmod", "ntptime.py") -freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py")) -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -freeze("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/extmod/webrepl/manifest.py") -include("$(MPY_DIR)/drivers/neopixel/manifest.py") +module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) +module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) +module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/extmod/webrepl") +include("$(MPY_DIR)/drivers/neopixel") diff --git a/ports/mimxrt/boards/manifest.py b/ports/mimxrt/boards/manifest.py index 2e1a1d63d4e7..a273dfa37041 100644 --- a/ports/mimxrt/boards/manifest.py +++ b/ports/mimxrt/boards/manifest.py @@ -1,8 +1,4 @@ freeze("$(PORT_DIR)/modules") -freeze("$(MPY_DIR)/drivers/onewire") -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") -try: - include("$(BOARD_DIR)/manifest.py") -except FileNotFoundError: - pass +include("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/extmod/uasyncio") diff --git a/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py b/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py index dbc8104dc24f..2b0cc6c818fb 100644 --- a/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py +++ b/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py @@ -1,4 +1,4 @@ include("$(PORT_DIR)/modules/manifest.py") -freeze("$(MPY_DIR)/drivers/hts221", "hts221.py") -freeze("$(MPY_DIR)/drivers/lps22h", "lps22h.py") -freeze("$(MPY_DIR)/drivers/lsm9ds1", "lsm9ds1.py") +include("$(MPY_DIR)/drivers/hts221") +include("$(MPY_DIR)/drivers/lps22h") +include("$(MPY_DIR)/drivers/lsm9ds1") diff --git a/ports/nrf/modules/manifest.py b/ports/nrf/modules/manifest.py index b27d4648b7ea..6efaf62d79d6 100644 --- a/ports/nrf/modules/manifest.py +++ b/ports/nrf/modules/manifest.py @@ -1,2 +1,2 @@ -freeze("$(PORT_DIR)/modules/scripts", "_mkfs.py") -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +module("_mkfs.py", base_path="$(PORT_DIR)/modules/scripts", opt=3) +include("$(MPY_DIR)/extmod/uasyncio") diff --git a/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py b/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py index 4a387915d37e..c25ae79887e2 100644 --- a/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py +++ b/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py @@ -1,2 +1,2 @@ # We do not want to include default frozen modules, -freeze("$(MPY_DIR)/drivers/sdcard", "sdcard.py") +include("$(MPY_DIR)/drivers/sdcard") diff --git a/ports/renesas-ra/boards/RA4M1_EK/manifest.py b/ports/renesas-ra/boards/RA4M1_EK/manifest.py index 4a387915d37e..c25ae79887e2 100644 --- a/ports/renesas-ra/boards/RA4M1_EK/manifest.py +++ b/ports/renesas-ra/boards/RA4M1_EK/manifest.py @@ -1,2 +1,2 @@ # We do not want to include default frozen modules, -freeze("$(MPY_DIR)/drivers/sdcard", "sdcard.py") +include("$(MPY_DIR)/drivers/sdcard") diff --git a/ports/renesas-ra/boards/manifest.py b/ports/renesas-ra/boards/manifest.py index 836bf7ccc24d..c66ec92015de 100644 --- a/ports/renesas-ra/boards/manifest.py +++ b/ports/renesas-ra/boards/manifest.py @@ -1,4 +1,4 @@ -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -freeze("$(MPY_DIR)/drivers/onewire", "onewire.py") -freeze("$(MPY_DIR)/drivers/sdcard", "sdcard.py") +include("$(MPY_DIR)/extmod/uasyncio") +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/drivers/onewire", ds18x20=False) +include("$(MPY_DIR)/drivers/sdcard") diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py index 7a2f1c9e2738..e139c7d60bed 100644 --- a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py @@ -1,11 +1,11 @@ include("$(PORT_DIR)/boards/manifest.py") -include("$(MPY_DIR)/extmod/webrepl/manifest.py") -freeze("$(MPY_DIR)/drivers/lsm6dsox/", "lsm6dsox.py") -include( - "$(MPY_LIB_DIR)/micropython/bluetooth/aioble/manifest.py", - client=True, - central=True, - l2cap=True, - security=True, -) -freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") + +# Networking +include("$(MPY_DIR)/extmod/webrepl") +require("urequests") + +# Drivers +include("$(MPY_DIR)/drivers/lsm6dsox") + +# Bluetooth +require("aioble", client=True, central=True, l2cap=True, security=True) diff --git a/ports/rp2/boards/PICO_W/manifest.py b/ports/rp2/boards/PICO_W/manifest.py index d2c76602affe..66ff26b0c856 100644 --- a/ports/rp2/boards/PICO_W/manifest.py +++ b/ports/rp2/boards/PICO_W/manifest.py @@ -1,7 +1,7 @@ include("../manifest.py") -freeze("$(MPY_DIR)/tools", "upip.py") -freeze("$(MPY_DIR)/tools", "upip_utarfile.py") -freeze("$(MPY_DIR)/extmod", "ntptime.py") +module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) +module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) +module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) -freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") +require("urequests") diff --git a/ports/rp2/boards/manifest.py b/ports/rp2/boards/manifest.py index b0e5e315544f..9afcba17e85d 100644 --- a/ports/rp2/boards/manifest.py +++ b/ports/rp2/boards/manifest.py @@ -1,5 +1,5 @@ freeze("$(PORT_DIR)/modules") -freeze("$(MPY_DIR)/drivers/onewire") -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") -include("$(MPY_DIR)/drivers/neopixel/manifest.py") +include("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/extmod/uasyncio") +include("$(MPY_DIR)/drivers/neopixel") diff --git a/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py b/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py index cd721d0ac45d..0ecdcd21534f 100644 --- a/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py +++ b/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py @@ -1,9 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") -include("$(MPY_DIR)/extmod/webrepl/manifest.py") -include( - "$(MPY_LIB_DIR)/micropython/bluetooth/aioble/manifest.py", - client=True, - central=True, - l2cap=True, - security=True, -) +include("$(MPY_DIR)/extmod/webrepl") +require("aioble", client=True, central=True, l2cap=True, security=True) diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py index b09c7ab92030..69da2897ae06 100644 --- a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py @@ -1,2 +1,2 @@ -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +# Note: Freezes to display.ssd1306, so must use deprecated "freeze" function. freeze("$(MPY_DIR)/drivers/", ("display/ssd1306.py")) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/manifest.py b/ports/stm32/boards/LEGO_HUB_NO6/manifest.py index dc09d04c9f2b..107001c38eda 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/manifest.py +++ b/ports/stm32/boards/LEGO_HUB_NO6/manifest.py @@ -1,3 +1,5 @@ +# Shared manifest for LEGO_HUB_NO6 & LEGO_HUB_NO7. + include("$(PORT_DIR)/boards/manifest.py") # Modules for application firmware update. diff --git a/ports/stm32/boards/LEGO_HUB_NO7/manifest.py b/ports/stm32/boards/LEGO_HUB_NO7/manifest.py index d746381637d9..ee79864a982c 100644 --- a/ports/stm32/boards/LEGO_HUB_NO7/manifest.py +++ b/ports/stm32/boards/LEGO_HUB_NO7/manifest.py @@ -1,5 +1,2 @@ -include("$(PORT_DIR)/boards/manifest.py") - -# Modules for application firmware update. -freeze("$(PORT_DIR)/mboot", "fwupdate.py", opt=3) -freeze("$(PORT_DIR)/boards/LEGO_HUB_NO6", ("spiflash.py", "appupdate.py"), opt=3) +# Use shared manifest. +include("$(PORT_DIR)/boards/LEGO_HUB_NO6") diff --git a/ports/stm32/boards/PYBD_SF2/manifest.py b/ports/stm32/boards/PYBD_SF2/manifest.py index 3819aa01b3dc..e4736f693a98 100644 --- a/ports/stm32/boards/PYBD_SF2/manifest.py +++ b/ports/stm32/boards/PYBD_SF2/manifest.py @@ -1,2 +1,2 @@ include("$(PORT_DIR)/boards/manifest.py") -include("$(MPY_DIR)/extmod/webrepl/manifest.py") +include("$(MPY_DIR)/extmod/webrepl") diff --git a/ports/stm32/boards/manifest.py b/ports/stm32/boards/manifest.py index 81b85834101d..4bb224e2d866 100644 --- a/ports/stm32/boards/manifest.py +++ b/ports/stm32/boards/manifest.py @@ -1,4 +1,5 @@ -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") -freeze("$(MPY_DIR)/drivers/dht", "dht.py") -freeze("$(MPY_DIR)/drivers/display", ("lcd160cr.py", "lcd160cr_test.py")) -freeze("$(MPY_DIR)/drivers/onewire", "onewire.py") +include("$(MPY_DIR)/extmod/uasyncio") + +include("$(MPY_DIR)/drivers/dht") +include("$(MPY_DIR)/drivers/display", lcd160cr=True, test=True) +include("$(MPY_DIR)/drivers/onewire", ds18x20=False) diff --git a/ports/unix/variants/dev/manifest.py b/ports/unix/variants/dev/manifest.py index 92a681116a68..dd521258e1ac 100644 --- a/ports/unix/variants/dev/manifest.py +++ b/ports/unix/variants/dev/manifest.py @@ -1,3 +1,3 @@ include("$(PORT_DIR)/variants/manifest.py") -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +include("$(MPY_DIR)/extmod/uasyncio") diff --git a/ports/unix/variants/manifest.py b/ports/unix/variants/manifest.py index 7708e598dbcf..bf7ce992ade0 100644 --- a/ports/unix/variants/manifest.py +++ b/ports/unix/variants/manifest.py @@ -1,2 +1,2 @@ -freeze_as_mpy("$(MPY_DIR)/tools", "upip.py") -freeze_as_mpy("$(MPY_DIR)/tools", "upip_utarfile.py", opt=3) +module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) +module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) diff --git a/ports/windows/variants/dev/manifest.py b/ports/windows/variants/dev/manifest.py index 88a6937b4fb3..f65a3d35e9d1 100644 --- a/ports/windows/variants/dev/manifest.py +++ b/ports/windows/variants/dev/manifest.py @@ -1,2 +1,2 @@ include("$(PORT_DIR)/variants/manifest.py") -include("$(MPY_DIR)/extmod/uasyncio/manifest.py") +include("$(MPY_DIR)/extmod/uasyncio") From fb20dbe4d123c69a7770e70911e827cefef01aa3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 10:57:33 +1000 Subject: [PATCH 1694/4290] stm32/boards/LEGO_HUB_NO6: Update manifest to new format. This was added after 203dae41f and missed in the rebase. Signed-off-by: Jim Mussared --- ports/stm32/boards/LEGO_HUB_NO6/manifest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/LEGO_HUB_NO6/manifest.py b/ports/stm32/boards/LEGO_HUB_NO6/manifest.py index 107001c38eda..1be4246e3788 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/manifest.py +++ b/ports/stm32/boards/LEGO_HUB_NO6/manifest.py @@ -3,5 +3,6 @@ include("$(PORT_DIR)/boards/manifest.py") # Modules for application firmware update. -freeze("$(PORT_DIR)/mboot", "fwupdate.py", opt=3) -freeze("$(BOARD_DIR)", ("spiflash.py", "appupdate.py"), opt=3) +module("fwupdate.py", base_path="$(PORT_DIR)/mboot", opt=3) +module("spiflash.py", opt=3) +module("appupdate.py", opt=3) From 655c29351a7c4ef74612edf6088036b07f39e6c7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 6 Sep 2022 11:52:46 +1000 Subject: [PATCH 1695/4290] drivers/display: Don't include tests by default. The tests can be copied to the board if needed. Also update the docs to reflect this change. Signed-off-by: Damien George --- docs/pyboard/tutorial/lcd160cr_skin.rst | 4 ++-- docs/reference/mpremote.rst | 2 ++ drivers/display/manifest.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/pyboard/tutorial/lcd160cr_skin.rst b/docs/pyboard/tutorial/lcd160cr_skin.rst index fc9d63538261..fa0debcb1ce3 100644 --- a/docs/pyboard/tutorial/lcd160cr_skin.rst +++ b/docs/pyboard/tutorial/lcd160cr_skin.rst @@ -40,9 +40,9 @@ Testing the display There is a test program which you can use to test the features of the display, and which also serves as a basis to start creating your own code that uses the -LCD. This test program is included in recent versions of the pyboard firmware -and is also available on GitHub +LCD. This test program is available on GitHub `here `__. +Copy it to the board over USB mass storage, or by using `mpremote`. To run the test from the MicroPython prompt do:: diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index a48df9953f50..e3902f8e5d7e 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -1,3 +1,5 @@ +.. _mpremote: + MicroPython remote control: mpremote ==================================== diff --git a/drivers/display/manifest.py b/drivers/display/manifest.py index d1ddff3374ab..16f93a7d4e99 100644 --- a/drivers/display/manifest.py +++ b/drivers/display/manifest.py @@ -1,5 +1,5 @@ # TODO: Split these into separate directories with their own manifests. -options.defaults(lcd160cr=False, ssd1306=False, test=True) +options.defaults(lcd160cr=False, ssd1306=False, test=False) if options.lcd160cr: module("lcd160cr.py", opt=3) From 4e4c28bf27ff4a9e1a2ce5b6fffa641d9a332507 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 6 Sep 2022 11:53:36 +1000 Subject: [PATCH 1696/4290] stm32/boards: Only freeze LCD160CR driver in PYB board firmware. Although this driver and associated hardware can be used on any board, it makes to only freeze it for PYB and PYBD boards. It can be easily copied to any board if needed. Fixes issue #8056. Signed-off-by: Damien George --- ports/stm32/boards/PYBD_SF2/manifest.py | 1 + ports/stm32/boards/PYBLITEV10/mpconfigboard.mk | 3 +++ ports/stm32/boards/PYBV10/manifest.py | 2 ++ ports/stm32/boards/PYBV10/mpconfigboard.mk | 3 +++ ports/stm32/boards/PYBV11/mpconfigboard.mk | 3 +++ ports/stm32/boards/manifest.py | 1 - ports/stm32/boards/manifest_pyboard.py | 1 + 7 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 ports/stm32/boards/PYBV10/manifest.py create mode 100644 ports/stm32/boards/manifest_pyboard.py diff --git a/ports/stm32/boards/PYBD_SF2/manifest.py b/ports/stm32/boards/PYBD_SF2/manifest.py index e4736f693a98..a9e92848d58d 100644 --- a/ports/stm32/boards/PYBD_SF2/manifest.py +++ b/ports/stm32/boards/PYBD_SF2/manifest.py @@ -1,2 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") +include("$(PORT_DIR)/boards/manifest_pyboard.py") include("$(MPY_DIR)/extmod/webrepl") diff --git a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk index 8aeaf0e40cfb..74698664760f 100644 --- a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk @@ -24,3 +24,6 @@ endif ifeq ($(BOARD_VARIANT),"network") MICROPY_PY_NETWORK_WIZNET5K=5200 endif + +# PYB-specific frozen modules +FROZEN_MANIFEST ?= boards/PYBV10/manifest.py diff --git a/ports/stm32/boards/PYBV10/manifest.py b/ports/stm32/boards/PYBV10/manifest.py new file mode 100644 index 000000000000..ec0d4a26b785 --- /dev/null +++ b/ports/stm32/boards/PYBV10/manifest.py @@ -0,0 +1,2 @@ +include("$(PORT_DIR)/boards/manifest.py") +include("$(PORT_DIR)/boards/manifest_pyboard.py") diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.mk b/ports/stm32/boards/PYBV10/mpconfigboard.mk index 97af22b5e19b..af2878267803 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV10/mpconfigboard.mk @@ -34,3 +34,6 @@ endif ifeq ($(BOARD_VARIANT),"network") MICROPY_PY_NETWORK_WIZNET5K=5200 endif + +# PYB-specific frozen modules +FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.mk b/ports/stm32/boards/PYBV11/mpconfigboard.mk index 97af22b5e19b..cf7884cfc67a 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV11/mpconfigboard.mk @@ -34,3 +34,6 @@ endif ifeq ($(BOARD_VARIANT),"network") MICROPY_PY_NETWORK_WIZNET5K=5200 endif + +# PYB-specific frozen modules +FROZEN_MANIFEST ?= boards/PYBV10/manifest.py diff --git a/ports/stm32/boards/manifest.py b/ports/stm32/boards/manifest.py index 4bb224e2d866..723caa3eb6d1 100644 --- a/ports/stm32/boards/manifest.py +++ b/ports/stm32/boards/manifest.py @@ -1,5 +1,4 @@ include("$(MPY_DIR)/extmod/uasyncio") include("$(MPY_DIR)/drivers/dht") -include("$(MPY_DIR)/drivers/display", lcd160cr=True, test=True) include("$(MPY_DIR)/drivers/onewire", ds18x20=False) diff --git a/ports/stm32/boards/manifest_pyboard.py b/ports/stm32/boards/manifest_pyboard.py new file mode 100644 index 000000000000..e4fb0a8c4dd1 --- /dev/null +++ b/ports/stm32/boards/manifest_pyboard.py @@ -0,0 +1 @@ +include("$(MPY_DIR)/drivers/display", lcd160cr=True) From 8770cd2f4d24b1ad14c934b4161e42108fe98f84 Mon Sep 17 00:00:00 2001 From: yn386 Date: Sun, 28 Aug 2022 15:40:00 +0900 Subject: [PATCH 1697/4290] stm32/adc: Make ADCAll.read_channel reject invalid channels. pyb.ADC(channel) checks whether specified channel is valid or have ADC capability but pyb.ADCAll().read_channel() does not. This change adds checking whether specified channel is valid and throw ValueError if channel is invalid. This is same as pyb.ADC(). --- ports/stm32/adc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index 9b7788e59e33..9d58cf2e7cf0 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -856,6 +856,9 @@ STATIC mp_obj_t adc_all_make_new(const mp_obj_type_t *type, size_t n_args, size_ STATIC mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) { pyb_adc_all_obj_t *self = MP_OBJ_TO_PTR(self_in); uint32_t chan = adc_get_internal_channel(mp_obj_get_int(channel)); + if (!is_adcx_channel(chan)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("not a valid ADC Channel: %d"), chan); + } uint32_t data = adc_config_and_read_channel(&self->handle, chan); return mp_obj_new_int(data); } From da50827657d6bc3024dd6acea76cb315d1cbbae1 Mon Sep 17 00:00:00 2001 From: yn386 Date: Wed, 31 Aug 2022 19:13:00 +0900 Subject: [PATCH 1698/4290] stm32/pyb_i2c: Fix pyb.I2C to work with dma=True on F4 MCUs. Prior to this commit, excuting this code: i2c = I2C(1, I2C.CONTROLLER, dma=True) i2c.send(data, addr=i2c_addr) the call to i2c.send() does not return and the board needs a reset. This code works when dma=False. According to the specification, I2Cx_EV_IRQHandler should: - Write DR to address when Start condition generated. - Clear ADDR by reading SR2 after reading SR2 when address sent. These processes are included in HAL_I2C_EV_IRQHandler(), however the firmware size increses about 2KB if HAL_I2C_EV_IRQHandler is called. This commit adds above processes to i2c_ev_irq_handler, and increases firmware by less than 100 bytes. Fixes issue #2643. --- ports/stm32/pyb_i2c.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 436b1c9bc243..e9877422ca0b 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -472,7 +472,17 @@ void i2c_ev_irq_handler(mp_uint_t i2c_id) { #if defined(STM32F4) - if (hi2c->Instance->SR1 & I2C_FLAG_BTF && hi2c->State == HAL_I2C_STATE_BUSY_TX) { + if (hi2c->Instance->SR1 & I2C_FLAG_SB) { + if (hi2c->State == HAL_I2C_STATE_BUSY_TX) { + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); + } else { + hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); + } + } else if (hi2c->Instance->SR1 & I2C_FLAG_ADDR) { + __IO uint32_t tmp_sr2; + tmp_sr2 = hi2c->Instance->SR2; + UNUSED(tmp_sr2); + } else if (hi2c->Instance->SR1 & I2C_FLAG_BTF && hi2c->State == HAL_I2C_STATE_BUSY_TX) { if (hi2c->XferCount != 0U) { hi2c->Instance->DR = *hi2c->pBuffPtr++; hi2c->XferCount--; From 989b8c728b296969e6489908b8e94ed23625a1e8 Mon Sep 17 00:00:00 2001 From: yn386 Date: Thu, 1 Sep 2022 18:08:18 +0900 Subject: [PATCH 1699/4290] stm32/timer: Fix use of timer channel callback() method on L4 MCUs. Since L4 HAL version 1.17.0, HAL_TIM_IC_Start_IT() checks whether specified channel of timer is busy or not, which is the case if this function is called more than once without first calling HAL_TIM_IC_Stop_IT(). The fix in this commit is to call the stop function before calling start. The PWM and OC modes have the same issue with the same fix. Fixes issue #8732. --- ports/stm32/timer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index 0cef60cb62c8..518a2e23b473 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -1576,6 +1576,7 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback) switch (self->mode) { case CHANNEL_MODE_PWM_NORMAL: case CHANNEL_MODE_PWM_INVERTED: + HAL_TIM_PWM_Stop_IT(&self->timer->tim, TIMER_CHANNEL(self)); HAL_TIM_PWM_Start_IT(&self->timer->tim, TIMER_CHANNEL(self)); break; case CHANNEL_MODE_OC_TIMING: @@ -1584,9 +1585,11 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback) case CHANNEL_MODE_OC_TOGGLE: case CHANNEL_MODE_OC_FORCED_ACTIVE: case CHANNEL_MODE_OC_FORCED_INACTIVE: + HAL_TIM_OC_Stop_IT(&self->timer->tim, TIMER_CHANNEL(self)); HAL_TIM_OC_Start_IT(&self->timer->tim, TIMER_CHANNEL(self)); break; case CHANNEL_MODE_IC: + HAL_TIM_IC_Stop_IT(&self->timer->tim, TIMER_CHANNEL(self)); HAL_TIM_IC_Start_IT(&self->timer->tim, TIMER_CHANNEL(self)); break; } From 719dbbf5639cdeff99bf629c45d66b18007e9958 Mon Sep 17 00:00:00 2001 From: yn386 Date: Fri, 2 Sep 2022 18:46:10 +0900 Subject: [PATCH 1700/4290] stm32/boards: Add alternate function list for STM32F446RE. Signed-off-by: Damien George --- .../boards/NUCLEO_F446RE/mpconfigboard.mk | 2 +- ports/stm32/boards/stm32f446_af.csv | 116 ++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 ports/stm32/boards/stm32f446_af.csv diff --git a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.mk index 64a80e992bce..3a922acebfbd 100644 --- a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.mk @@ -1,6 +1,6 @@ MCU_SERIES = f4 CMSIS_MCU = STM32F446xx -AF_FILE = boards/stm32f429_af.csv +AF_FILE = boards/stm32f446_af.csv LD_FILES = boards/stm32f411.ld boards/common_ifs.ld TEXT0_ADDR = 0x08000000 TEXT1_ADDR = 0x08020000 diff --git a/ports/stm32/boards/stm32f446_af.csv b/ports/stm32/boards/stm32f446_af.csv new file mode 100644 index 000000000000..0838ed089d8f --- /dev/null +++ b/ports/stm32/boards/stm32f446_af.csv @@ -0,0 +1,116 @@ +Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15, +,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11/CEC,I2C1/2/3/4/CEC,SPI1/2/3/4,SPI2/3/4/SAI1,SPI2/3/USART1/2/3/UART5/SPDIFRX,SAI/USART6/UART4/5/SPDIFRX,CAN1/2/TIM12/13/14/QUADSPI,SAI2/QUADSPI/OTG2_HS/OTG1_FS,OTG1_FS,FMC/SDIO/OTG2_FS,DCMI,,SYS, +PortA,PA0,,TIM2_CH1/TIM2_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,,,,,,EVENTOUT,ADC123_IN0 +PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,QUADSPI_BK1_IO3,SAI2_MCLK_B,,,,,EVENTOUT,ADC123_IN1 +PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,SAI2_SCK_B,,,,,,,EVENTOUT,ADC123_IN2 +PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,SAI1_FS_A,USART2_RX,,,OTG_HS_ULPI_D0,,,,,EVENTOUT,ADC123_IN3 +PortA,PA4,,,,,,SPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,OTG_HS_SOF,DCMI_HSYNC,,EVENTOUT,ADC12_IN4 +PortA,PA5,,TIM2_CH1/TIM2_ETR,,TIM8_CH1N,,SPI1_SCK/I2S1_CK,,,,,OTG_HS_ULPI_CK,,,,,EVENTOUT,ADC12_IN5 +PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,SPI1_MISO,I2S2_MCK,,,TIM13_CH1,,,,DCMI_PIXCLK,,EVENTOUT,ADC12_IN6 +PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,,SPI1_MOSI/I2S1_SD,,,,TIM14_CH1,,,FMC_SDNWE,,,EVENTOUT,ADC12_IN7 +PortA,PA8,MCO1,TIM1_CH1,,,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,,EVENTOUT, +PortA,PA9,,TIM1_CH2,,,I2C3_SMBA,SPI2_SCK/I2S2_CK,SAI1_SD_B,USART1_TX,,,,,,DCMI_D0,,EVENTOUT, +PortA,PA10,,TIM1_CH3,,,,,,USART1_RX,,,OTG_FS_ID,,,DCMI_D1,,EVENTOUT, +PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,,EVENTOUT, +PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,SAI2_FS_B,CAN1_TX,OTG_FS_DP,,,,,EVENTOUT, +PortA,PA13,JTMS/SWDIO,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA14,JTCK/SWCLK,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,HDMI_CEC,SPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,,UART4_RTS,,,,,,,EVENTOUT, +PortB,PB0,,TIM1_CH2N,TIM3_CH3,TIM8_CH2N,,,,SPI3_MOSI/I2S3_SD,UART4_CTS,,OTG_HS_ULPI_D1,,SDIO_D1,,,EVENTOUT,ADC12_IN8 +PortB,PB1,,TIM1_CH3N,TIM3_CH4,TIM8_CH3N,,,,,,,OTG_HS_ULPI_D2,,SDIO_D2,,,EVENTOUT,ADC12_IN9 +PortB,PB2,,TIM2_CH4,,,,,SAI1_SD_A,SPI3_MOSI/I2S3_SD,,QUADSPI_CLK,OTG_HS_ULPI_D4,,SDIO_CK,,,EVENTOUT, +PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,I2C2_SDA,SPI1_SCK/I2S1_CK,SPI3_SCK/I2S3_CK,,,,,,,,,EVENTOUT, +PortB,PB4,NJTRST,,TIM3_CH1,,I2C3_SDA,SPI1_MISO,SPI3_MISO,SPI2_NSS/I2S2_WS,,,,,,,,EVENTOUT, +PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI/I2S1_SD,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,,FMC_SDCKE1,DCMI_D10,,EVENTOUT, +PortB,PB6,,,TIM4_CH1,HDMI_CEC,I2C1_SCL,,,USART1_TX,,CAN2_TX,QUADSPI_BK1_NCS,,FMC_SDNE1,DCMI_D5,,EVENTOUT, +PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,SPDIF_RX0,,,,FMC_NL,DCMI_VSYNC,,EVENTOUT, +PortB,PB8,,TIM2_CH1/TIM2_ETR,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,,SDIO_D4,DCMI_D6,,EVENTOUT, +PortB,PB9,,TIM2_CH2,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,SAI1_FS_B,,,CAN1_TX,,,SDIO_D5,DCMI_D7,,EVENTOUT, +PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCK/I2S2_CK,SAI1_SCK_A,USART3_TX,,,OTG_HS_ULPI_D3,,,,,EVENTOUT, +PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,SAI2_SD_A,,,,,,,EVENTOUT, +PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,SAI1_SCK_B,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,,OTG_HS_ID,,,EVENTOUT, +PortB,PB13,,TIM1_CH1N,,,,SPI2_SCK/I2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,,,,,EVENTOUT, +PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT, +PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT, +PortC,PC0,,,,,,,SAI1_MCLK_B,,,,OTG_HS_ULPI_STP,,FMC_SDNWE,,,EVENTOUT,ADC123_IN10 +PortC,PC1,,,,,,SPI3_MOSI/I2S3_SD,SAI1_SD_A,SPI2_MOSI/I2S2_SD,,,,,,,,EVENTOUT,ADC123_IN11 +PortC,PC2,,,,,,SPI2_MISO,,,,,OTG_HS_ULPI_DIR,,FMC_SDNE0,,,EVENTOUT,ADC123_IN12 +PortC,PC3,,,,,,SPI2_MOSI/I2S2_SD,,,,,OTG_HS_ULPI_NXT,,FMC_SDCKE0,,,EVENTOUT,ADC123_IN13 +PortC,PC4,,,,,,I2S1_MCK,,,SPDIF_RX2,,,,FMC_SDNE0,,,EVENTOUT,ADC12_IN14 +PortC,PC5,,,,,,,,USART3_RX,SPDIF_RX3,,,,FMC_SDCKE0,,,EVENTOUT,ADC12_IN15 +PortC,PC6,,,TIM3_CH1,TIM8_CH1,FMPI2C1_SCL,I2S2_MCK,,,USART6_TX,,,,SDIO_D6,DCMI_D0,,EVENTOUT, +PortC,PC7,,,TIM3_CH2,TIM8_CH2,FMPI2C1_SDA,SPI2_SCK/I2S2_CK,I2S3_MCK,SPDIF_RX1,USART6_RX,,,,SDIO_D7,DCMI_D1,,EVENTOUT, +PortC,PC8,TRACED0,,TIM3_CH3,TIM8_CH3,,,,UART5_RTS,USART6_CK,,,,SDIO_D0,DCMI_D2,,EVENTOUT, +PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,UART5_CTS,,QUADSPI_BK1_IO0,,,SDIO_D1,DCMI_D3,,EVENTOUT, +PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,QUADSPI_BK1_IO1,,,SDIO_D2,DCMI_D8,,EVENTOUT, +PortC,PC11,,,,,,,SPI3_MISO,USART3_RX,UART4_RX,QUADSPI_BK2_NCS,,,SDIO_D3,DCMI_D4,,EVENTOUT, +PortC,PC12,,,,,I2C2_SDA,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDIO_CK,DCMI_D9,,EVENTOUT, +PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT, +PortD,PD0,,,,,,SPI4_MISO,SPI3_MOSI/I2S3_SD,,,CAN1_RX,,,FMC_D2,,,EVENTOUT, +PortD,PD1,,,,,,,,SPI2_NSS/I2S2_WS,,CAN1_TX,,,FMC_D3,,,EVENTOUT, +PortD,PD2,,,TIM3_ETR,,,,,,UART5_RX,,,,SDIO_CMD,DCMI_D11,,EVENTOUT, +PortD,PD3,TRACED1,,,,,SPI2_SCK/I2S2_CK,,USART2_CTS,,QUADSPI_CLK,,,FMC_CLK,DCMI_D5,,EVENTOUT, +PortD,PD4,,,,,,,,USART2_RTS,,,,,FMC_NOE,,,EVENTOUT, +PortD,PD5,,,,,,,,USART2_TX,,,,,FMC_NWE,,,EVENTOUT, +PortD,PD6,,,,,,SPI3_MOSI/I2S3_SD,SAI1_SD_A,USART2_RX,,,,,FMC_NWAIT,DCMI_D10,,EVENTOUT, +PortD,PD7,,,,,,,,USART2_CK,SPDIF_RX0,,,,FMC_NE1,,,EVENTOUT, +PortD,PD8,,,,,,,,USART3_TX,SPDIF_RX1,,,,FMC_D13,,,EVENTOUT, +PortD,PD9,,,,,,,,USART3_RX,,,,,FMC_D14,,,EVENTOUT, +PortD,PD10,,,,,,,,USART3_CK,,,,,FMC_D15,,,EVENTOUT, +PortD,PD11,,,,,FMPI2C1_SMBA,,,USART3_CTS,,QUADSPI_BK1_IO0,SAI2_SD_A,,FMC_A16,,,EVENTOUT, +PortD,PD12,,,TIM4_CH1,,FMPI2C1_SCL,,,USART3_RTS,,QUADSPI_BK1_IO1,SAI2_FS_A,,FMC_A17,,,EVENTOUT, +PortD,PD13,,,TIM4_CH2,,FMPI2C1_SDA,,,,,QUADSPI_BK1_IO3,SAI2_SCK_A,,FMC_A18,,,EVENTOUT, +PortD,PD14,,,TIM4_CH3,,FMPI2C1_SCL,,,,SAI2_SCK_A,,,,FMC_D0,,,EVENTOUT, +PortD,PD15,,,TIM4_CH4,,FMPI2C1_SDA,,,,,,,,FMC_D1,,,EVENTOUT, +PortE,PE0,,,TIM4_ETR,,,,,,,,SAI2_MCLK_A,,FMC_NBL0,DCMI_D2,,EVENTOUT, +PortE,PE1,,,,,,,,,,,,,FMC_NBL1,DCMI_D3,,EVENTOUT, +PortE,PE2,TRACECLK,,,,,SPI4_SCK,SAI1_MCLK_A,,,QUADSPI_BK1_IO2,,,FMC_A23,,,EVENTOUT, +PortE,PE3,TRACED0,,,,,,SAI1_SD_B,,,,,,FMC_A19,,,EVENTOUT, +PortE,PE4,TRACED1,,,,,SPI4_NSS,SAI1_FS_A,,,,,,FMC_A20,DCMI_D4,,EVENTOUT, +PortE,PE5,TRACED2,,,TIM9_CH1,,SPI4_MISO,SAI1_SCK_A,,,,,,FMC_A21,DCMI_D6,,EVENTOUT, +PortE,PE6,TRACED3,,,TIM9_CH2,,SPI4_MOSI,SAI1_SD_A,,,,,,FMC_A22,DCMI_D7,,EVENTOUT, +PortE,PE7,,TIM1_ETR,,,,,,,UART5_RX,,QUADSPI_BK2_IO0,,FMC_D4,,,EVENTOUT, +PortE,PE8,,TIM1_CH1N,,,,,,,UART5_TX,,QUADSPI_BK2_IO1,,FMC_D5,,,EVENTOUT, +PortE,PE9,,TIM1_CH1,,,,,,,,,QUADSPI_BK2_IO2,,FMC_D6,,,EVENTOUT, +PortE,PE10,,TIM1_CH2N,,,,,,,,,QUADSPI_BK2_IO3,,FMC_D7,,,EVENTOUT, +PortE,PE11,,TIM1_CH2,,,,SPI4_NSS,,,,,SAI2_SD_B,,FMC_D8,,,EVENTOUT, +PortE,PE12,,TIM1_CH3N,,,,SPI4_SCK,,,,,SAI2_SCK_B,,FMC_D9,,,EVENTOUT, +PortE,PE13,,TIM1_CH3,,,,SPI4_MISO,,,,,SAI2_FS_B,,FMC_D10,,,EVENTOUT, +PortE,PE14,,TIM1_CH4,,,,SPI4_MOSI,,,,,SAI2_MCLK_B,,FMC_D11,,,EVENTOUT, +PortE,PE15,,TIM1_BKIN,,,,,,,,,,,FMC_D12,,,EVENTOUT, +PortF,PF0,,,,,I2C2_SDA,,,,,,,,FMC_A0,,,EVENTOUT, +PortF,PF1,,,,,I2C2_SCL,,,,,,,,FMC_A1,,,EVENTOUT, +PortF,PF2,,,,,I2C2_SMBA,,,,,,,,FMC_A2,,,EVENTOUT, +PortF,PF3,,,,,,,,,,,,,FMC_A3,,,EVENTOUT,ADC3_IN9 +PortF,PF4,,,,,,,,,,,,,FMC_A4,,,EVENTOUT,ADC3_IN14 +PortF,PF5,,,,,,,,,,,,,FMC_A5,,,EVENTOUT,ADC3_IN15 +PortF,PF6,,,,TIM10_CH1,,,SAI1_SD_B,,,QUADSPI_BK1_IO3,,,,,,EVENTOUT,ADC3_IN4 +PortF,PF7,,,,TIM11_CH1,,,SAI1_MCLK_B,,,QUADSPI_BK1_IO2,,,,,,EVENTOUT,ADC3_IN5 +PortF,PF8,,,,,,,SAI1_SCK_B,,,TIM13_CH1,QUADSPI_BK1_IO0,,,,,EVENTOUT,ADC3_IN6 +PortF,PF9,,,,,,,SAI1_FS_B,,,TIM14_CH1,QUADSPI_BK1_IO1,,,,,EVENTOUT,ADC3_IN7 +PortF,PF10,,,,,,,,,,,,,,DCMI_D11,,EVENTOUT,ADC3_IN8 +PortF,PF11,,,,,,,,,,,SAI2_SD_B,,FMC_SDNRAS,DCMI_D12,,EVENTOUT, +PortF,PF12,,,,,,,,,,,,,FMC_A6,,,EVENTOUT, +PortF,PF13,,,,,FMPI2C1_SMBA,,,,,,,,FMC_A7,,,EVENTOUT, +PortF,PF14,,,,,FMPI2C1_SCL,,,,,,,,FMC_A8,,,EVENTOUT, +PortF,PF15,,,,,FMPI2C1_SDA,,,,,,,,FMC_A9,,,EVENTOUT, +PortG,PG0,,,,,,,,,,,,,FMC_A10,,,EVENTOUT, +PortG,PG1,,,,,,,,,,,,,FMC_A11,,,EVENTOUT, +PortG,PG2,,,,,,,,,,,,,FMC_A12,,,EVENTOUT, +PortG,PG3,,,,,,,,,,,,,FMC_A13,,,EVENTOUT, +PortG,PG4,,,,,,,,,,,,,FMC_A14/FMC_BA0,,,EVENTOUT, +PortG,PG5,,,,,,,,,,,,,FMC_A15/FMC_BA1,,,EVENTOUT, +PortG,PG6,,,,,,,,,,,QUADSPI_BK1_NCS,,,DCMI_D12,,EVENTOUT, +PortG,PG7,,,,,,,,,USART6_CK,,,,FMC_INT,DCMI_D13,,EVENTOUT, +PortG,PG8,,,,,,,,SPDIFRX_IN2,USART6_RTS,,,,FMC_SDCLK,,,EVENTOUT, +PortG,PG9,,,,,,,,SPDIFRX_IN3,USART6_RX,QUADSPI_BK2_IO2,SAI2_FS_B,,FMC_NE2/FMC_NCE3,DCMI_VSYNC,,EVENTOUT, +PortG,PG10,,,,,,,,,,,SAI2_SD_B,,FMC_NE3,DCMI_D2,,EVENTOUT, +PortG,PG11,,,,,,,SPI4_SCK,SPDIFRX_IN0,,,,,,DCMI_D3,,EVENTOUT, +PortG,PG12,,,,,,,SPI4_MISO,SPDIFRX_IN1,USART6_RTS,,,,FMC_NE4,,,EVENTOUT, +PortG,PG13,TRACED2,,,,,,SPI4_MOSI,,USART6_CTS,,,,FMC_A24,,,EVENTOUT, +PortG,PG14,TRACED3,,,,,,SPI4_NSS,,USART6_TX,QUADSPI_BK2_IO3,,,FMC_A25,,,EVENTOUT, +PortG,PG15,,,,,,,,,USART6_CTS,,,,FMC_SDNCAS,DCMI_D13,,EVENTOUT, +PortH,PH0,,,,,,,,,,,,,,,,EVENTOUT, +PortH,PH1,,,,,,,,,,,,,,,,EVENTOUT, From e90b85cc98a24003f2d673bab2c255ab3dce66e7 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 5 Sep 2022 07:58:04 -0500 Subject: [PATCH 1701/4290] extmod/modure: Convert byte offsets to unicode indices when necessary. And add a test. Fixes issue #9202. Signed-off-by: Jeff Epler --- extmod/modure.c | 16 ++++++++++++++++ tests/unicode/unicode_ure.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/unicode/unicode_ure.py diff --git a/extmod/modure.c b/extmod/modure.c index 799fef13b1bd..a674d664999a 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -33,6 +33,10 @@ #include "py/objstr.h" #include "py/stackctrl.h" +#if MICROPY_PY_BUILTINS_STR_UNICODE +#include "py/unicode.h" +#endif + #if MICROPY_PY_URE #define re1_5_stack_chk() MP_STACK_CHECK() @@ -121,6 +125,18 @@ STATIC void match_span_helper(size_t n_args, const mp_obj_t *args, mp_obj_t span e = self->caps[no * 2 + 1] - begin; } + #if MICROPY_PY_BUILTINS_STR_UNICODE + if (mp_obj_get_type(self->str) == &mp_type_str) { + const byte *begin = (const byte *)mp_obj_str_get_str(self->str); + if (s != -1) { + s = utf8_ptr_to_index(begin, begin + s); + } + if (e != -1) { + e = utf8_ptr_to_index(begin, begin + e); + } + } + #endif + span[0] = mp_obj_new_int(s); span[1] = mp_obj_new_int(e); } diff --git a/tests/unicode/unicode_ure.py b/tests/unicode/unicode_ure.py new file mode 100644 index 000000000000..5a5dc600545f --- /dev/null +++ b/tests/unicode/unicode_ure.py @@ -0,0 +1,32 @@ +# test match.span() for unicode strings + +try: + import ure as re +except ImportError: + try: + import re + except ImportError: + print("SKIP") + raise SystemExit + +try: + m = re.match(".", "a") + m.span +except AttributeError: + print("SKIP") + raise SystemExit + + +def print_spans(match): + print("----") + try: + i = 0 + while True: + print(match.span(i), match.start(i), match.end(i)) + i += 1 + except IndexError: + pass + + +m = re.match(r"([0-9]*)(([a-z]*)([0-9]*))", "1234\u2764567") +print_spans(m) From aeff6911d750a2d203eeb1cacd74701de5313ee6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 8 Sep 2022 11:24:18 +1000 Subject: [PATCH 1702/4290] lib/micropython-lib: Update submodule to latest. This brings in the drivers and libraries that were previously in this repo. Signed-off-by: Jim Mussared --- lib/micropython-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/micropython-lib b/lib/micropython-lib index f3cfc52ab076..58f8bec54d5b 160000 --- a/lib/micropython-lib +++ b/lib/micropython-lib @@ -1 +1 @@ -Subproject commit f3cfc52ab076fc913dc6e266fb7370b418c8f542 +Subproject commit 58f8bec54d5b3b959247b73a6e8f28e8493bd30b From d84c6ef0e8dd363881d80b2d8fb03447cc349830 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 13:49:41 +1000 Subject: [PATCH 1703/4290] ports: Use micropython-lib version of drivers in manifests. --- .../esp32/boards/LILYGO_TTGO_LORA32/manifest.py | 3 +-- ports/esp32/boards/LOLIN_S2_PICO/manifest.py | 3 +-- ports/esp32/boards/manifest.py | 17 +++++++++-------- ports/esp8266/boards/GENERIC/manifest.py | 2 +- ports/esp8266/boards/GENERIC_512K/manifest.py | 11 ++++++----- ports/esp8266/boards/manifest.py | 11 ++++++----- ports/mimxrt/boards/manifest.py | 5 +++-- .../arduino_nano_33_ble_sense/manifest.py | 6 +++--- .../renesas-ra/boards/RA4M1_CLICKER/manifest.py | 2 +- ports/renesas-ra/boards/RA4M1_EK/manifest.py | 2 +- ports/renesas-ra/boards/manifest.py | 6 +++--- .../ARDUINO_NANO_RP2040_CONNECT/manifest.py | 4 ++-- ports/rp2/boards/PICO_W/manifest.py | 2 +- ports/rp2/boards/manifest.py | 7 ++++--- .../boards/ARDUINO_PORTENTA_H7/manifest.py | 2 +- .../GARATRONIC_PYBSTICK26_F411/manifest.py | 3 +-- ports/stm32/boards/PYBD_SF2/manifest.py | 2 +- ports/stm32/boards/manifest.py | 4 ++-- ports/stm32/boards/manifest_pyboard.py | 2 +- 19 files changed, 48 insertions(+), 46 deletions(-) diff --git a/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py b/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py index 6c491c8f66de..e2cd6b3d0151 100644 --- a/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py +++ b/ports/esp32/boards/LILYGO_TTGO_LORA32/manifest.py @@ -1,4 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") freeze("modules") - -include("$(MPY_DIR)/drivers/display", ssd1306=True) +require("ssd1306") diff --git a/ports/esp32/boards/LOLIN_S2_PICO/manifest.py b/ports/esp32/boards/LOLIN_S2_PICO/manifest.py index efc37137b2cf..9ac8ade8275b 100644 --- a/ports/esp32/boards/LOLIN_S2_PICO/manifest.py +++ b/ports/esp32/boards/LOLIN_S2_PICO/manifest.py @@ -1,4 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") freeze("./modules") - -include("$(MPY_DIR)/drivers/display", ssd1306=True) +require("ssd1306") diff --git a/ports/esp32/boards/manifest.py b/ports/esp32/boards/manifest.py index 658d11d5855d..fcc48d721805 100644 --- a/ports/esp32/boards/manifest.py +++ b/ports/esp32/boards/manifest.py @@ -1,15 +1,16 @@ freeze("$(PORT_DIR)/modules") module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) -module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) -include("$(MPY_DIR)/drivers/dht") -include("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/drivers/neopixel") include("$(MPY_DIR)/extmod/uasyncio") -include("$(MPY_DIR)/extmod/webrepl") # Require some micropython-lib modules. -require("urequests") -require("upysh") -require("umqtt.simple") +require("dht") +require("ds18x20") +require("neopixel") +require("ntptime") +require("onewire") require("umqtt.robust") +require("umqtt.simple") +require("upysh") +require("urequests") +require("webrepl") diff --git a/ports/esp8266/boards/GENERIC/manifest.py b/ports/esp8266/boards/GENERIC/manifest.py index 54b916546c34..ef708846241f 100644 --- a/ports/esp8266/boards/GENERIC/manifest.py +++ b/ports/esp8266/boards/GENERIC/manifest.py @@ -5,7 +5,7 @@ include("$(MPY_DIR)/extmod/uasyncio") # drivers -include("$(MPY_DIR)/drivers/display", ssd1306=True) +require("ssd1306") # micropython-lib: file utilities require("upysh") diff --git a/ports/esp8266/boards/GENERIC_512K/manifest.py b/ports/esp8266/boards/GENERIC_512K/manifest.py index 57970a6b4dc1..15f6cffc3f94 100644 --- a/ports/esp8266/boards/GENERIC_512K/manifest.py +++ b/ports/esp8266/boards/GENERIC_512K/manifest.py @@ -1,8 +1,9 @@ module("_boot.py", opt=3) module("apa102.py", base_path="$(PORT_DIR)/modules", opt=3) module("port_diag.py", base_path="$(PORT_DIR)/modules", opt=3) -module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) -include("$(MPY_DIR)/drivers/dht") -include("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/extmod/webrepl") -include("$(MPY_DIR)/drivers/neopixel") +require("ntptime") +require("dht") +require("onewire") +require("ds18x20") +require("webrepl") +require("neopixel") diff --git a/ports/esp8266/boards/manifest.py b/ports/esp8266/boards/manifest.py index abcee253ffe5..e7defd0bb70f 100644 --- a/ports/esp8266/boards/manifest.py +++ b/ports/esp8266/boards/manifest.py @@ -1,8 +1,9 @@ freeze("$(PORT_DIR)/modules") module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) -module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) -include("$(MPY_DIR)/drivers/dht") -include("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/extmod/webrepl") -include("$(MPY_DIR)/drivers/neopixel") +require("ntptime") +require("dht") +require("onewire") +require("ds18x20") +require("neopixel") +require("webrepl") diff --git a/ports/mimxrt/boards/manifest.py b/ports/mimxrt/boards/manifest.py index a273dfa37041..e4e5a236a357 100644 --- a/ports/mimxrt/boards/manifest.py +++ b/ports/mimxrt/boards/manifest.py @@ -1,4 +1,5 @@ freeze("$(PORT_DIR)/modules") -include("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/drivers/dht") include("$(MPY_DIR)/extmod/uasyncio") +require("onewire") +require("ds18x20") +require("dht") diff --git a/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py b/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py index 2b0cc6c818fb..8396e0249cbc 100644 --- a/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py +++ b/ports/nrf/boards/arduino_nano_33_ble_sense/manifest.py @@ -1,4 +1,4 @@ include("$(PORT_DIR)/modules/manifest.py") -include("$(MPY_DIR)/drivers/hts221") -include("$(MPY_DIR)/drivers/lps22h") -include("$(MPY_DIR)/drivers/lsm9ds1") +require("hts221") +require("lps22h") +require("lsm9ds1") diff --git a/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py b/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py index c25ae79887e2..99b9c94051ed 100644 --- a/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py +++ b/ports/renesas-ra/boards/RA4M1_CLICKER/manifest.py @@ -1,2 +1,2 @@ # We do not want to include default frozen modules, -include("$(MPY_DIR)/drivers/sdcard") +require("sdcard") diff --git a/ports/renesas-ra/boards/RA4M1_EK/manifest.py b/ports/renesas-ra/boards/RA4M1_EK/manifest.py index c25ae79887e2..99b9c94051ed 100644 --- a/ports/renesas-ra/boards/RA4M1_EK/manifest.py +++ b/ports/renesas-ra/boards/RA4M1_EK/manifest.py @@ -1,2 +1,2 @@ # We do not want to include default frozen modules, -include("$(MPY_DIR)/drivers/sdcard") +require("sdcard") diff --git a/ports/renesas-ra/boards/manifest.py b/ports/renesas-ra/boards/manifest.py index c66ec92015de..01699c3d6e6a 100644 --- a/ports/renesas-ra/boards/manifest.py +++ b/ports/renesas-ra/boards/manifest.py @@ -1,4 +1,4 @@ include("$(MPY_DIR)/extmod/uasyncio") -include("$(MPY_DIR)/drivers/dht") -include("$(MPY_DIR)/drivers/onewire", ds18x20=False) -include("$(MPY_DIR)/drivers/sdcard") +require("dht") +require("onewire") +require("sdcard") diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py index e139c7d60bed..dbd45fa408e6 100644 --- a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/manifest.py @@ -1,11 +1,11 @@ include("$(PORT_DIR)/boards/manifest.py") # Networking -include("$(MPY_DIR)/extmod/webrepl") +require("webrepl") require("urequests") # Drivers -include("$(MPY_DIR)/drivers/lsm6dsox") +require("lsm6dsox") # Bluetooth require("aioble", client=True, central=True, l2cap=True, security=True) diff --git a/ports/rp2/boards/PICO_W/manifest.py b/ports/rp2/boards/PICO_W/manifest.py index 66ff26b0c856..4d9eb87f20f3 100644 --- a/ports/rp2/boards/PICO_W/manifest.py +++ b/ports/rp2/boards/PICO_W/manifest.py @@ -2,6 +2,6 @@ module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) -module("ntptime.py", base_path="$(MPY_DIR)/extmod", opt=3) +require("ntptime") require("urequests") diff --git a/ports/rp2/boards/manifest.py b/ports/rp2/boards/manifest.py index 9afcba17e85d..e62d02f30857 100644 --- a/ports/rp2/boards/manifest.py +++ b/ports/rp2/boards/manifest.py @@ -1,5 +1,6 @@ freeze("$(PORT_DIR)/modules") -include("$(MPY_DIR)/drivers/onewire") -include("$(MPY_DIR)/drivers/dht") include("$(MPY_DIR)/extmod/uasyncio") -include("$(MPY_DIR)/drivers/neopixel") +require("onewire") +require("ds18x20") +require("dht") +require("neopixel") diff --git a/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py b/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py index 0ecdcd21534f..4fa92b720532 100644 --- a/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py +++ b/ports/stm32/boards/ARDUINO_PORTENTA_H7/manifest.py @@ -1,3 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") -include("$(MPY_DIR)/extmod/webrepl") +require("webrepl") require("aioble", client=True, central=True, l2cap=True, security=True) diff --git a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py index 69da2897ae06..2600fc506241 100644 --- a/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py +++ b/ports/stm32/boards/GARATRONIC_PYBSTICK26_F411/manifest.py @@ -1,2 +1 @@ -# Note: Freezes to display.ssd1306, so must use deprecated "freeze" function. -freeze("$(MPY_DIR)/drivers/", ("display/ssd1306.py")) +require("ssd1306") diff --git a/ports/stm32/boards/PYBD_SF2/manifest.py b/ports/stm32/boards/PYBD_SF2/manifest.py index a9e92848d58d..0ee11baf4b8e 100644 --- a/ports/stm32/boards/PYBD_SF2/manifest.py +++ b/ports/stm32/boards/PYBD_SF2/manifest.py @@ -1,3 +1,3 @@ include("$(PORT_DIR)/boards/manifest.py") include("$(PORT_DIR)/boards/manifest_pyboard.py") -include("$(MPY_DIR)/extmod/webrepl") +require("webrepl") diff --git a/ports/stm32/boards/manifest.py b/ports/stm32/boards/manifest.py index 723caa3eb6d1..e6b77f8ab335 100644 --- a/ports/stm32/boards/manifest.py +++ b/ports/stm32/boards/manifest.py @@ -1,4 +1,4 @@ include("$(MPY_DIR)/extmod/uasyncio") -include("$(MPY_DIR)/drivers/dht") -include("$(MPY_DIR)/drivers/onewire", ds18x20=False) +require("dht") +require("onewire") diff --git a/ports/stm32/boards/manifest_pyboard.py b/ports/stm32/boards/manifest_pyboard.py index e4fb0a8c4dd1..789365a43307 100644 --- a/ports/stm32/boards/manifest_pyboard.py +++ b/ports/stm32/boards/manifest_pyboard.py @@ -1 +1 @@ -include("$(MPY_DIR)/drivers/display", lcd160cr=True) +require("lcd160cr") From 24678fe452e9c0d0b96575424f81fb4a5f5f4302 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 13:49:10 +1000 Subject: [PATCH 1704/4290] drivers: Remove drivers that are now in micropython-lib. Signed-off-by: Jim Mussared --- drivers/README.md | 2 +- drivers/codec/manifest.py | 1 - drivers/codec/wm8960.py | 753 ----------------------------- drivers/dht/dht.py | 46 -- drivers/dht/manifest.py | 1 - drivers/display/lcd160cr.py | 482 ------------------ drivers/display/lcd160cr_test.py | 187 ------- drivers/display/manifest.py | 11 - drivers/display/ssd1306.py | 163 ------- drivers/hts221/hts221.py | 91 ---- drivers/hts221/manifest.py | 1 - drivers/lps22h/lps22h.py | 109 ----- drivers/lps22h/manifest.py | 1 - drivers/lsm6dsox/lsm6dsox.py | 271 ----------- drivers/lsm6dsox/lsm6dsox_basic.py | 15 - drivers/lsm6dsox/lsm6dsox_mlc.py | 48 -- drivers/lsm6dsox/manifest.py | 1 - drivers/lsm9ds1/lsm9ds1.py | 189 -------- drivers/lsm9ds1/manifest.py | 1 - drivers/neopixel/manifest.py | 1 - drivers/neopixel/neopixel.py | 50 -- drivers/nrf24l01/manifest.py | 1 - drivers/nrf24l01/nrf24l01.py | 252 ---------- drivers/nrf24l01/nrf24l01test.py | 150 ------ drivers/onewire/ds18x20.py | 52 -- drivers/onewire/manifest.py | 6 - drivers/onewire/onewire.py | 92 ---- drivers/sdcard/manifest.py | 1 - drivers/sdcard/sdcard.py | 299 ------------ drivers/sdcard/sdtest.py | 61 --- extmod/ntptime.py | 48 -- extmod/webrepl/manifest.py | 2 - extmod/webrepl/webrepl.py | 177 ------- extmod/webrepl/webrepl_setup.py | 107 ---- 34 files changed, 1 insertion(+), 3671 deletions(-) delete mode 100644 drivers/codec/manifest.py delete mode 100644 drivers/codec/wm8960.py delete mode 100644 drivers/dht/dht.py delete mode 100644 drivers/dht/manifest.py delete mode 100644 drivers/display/lcd160cr.py delete mode 100644 drivers/display/lcd160cr_test.py delete mode 100644 drivers/display/manifest.py delete mode 100644 drivers/display/ssd1306.py delete mode 100644 drivers/hts221/hts221.py delete mode 100644 drivers/hts221/manifest.py delete mode 100644 drivers/lps22h/lps22h.py delete mode 100644 drivers/lps22h/manifest.py delete mode 100644 drivers/lsm6dsox/lsm6dsox.py delete mode 100644 drivers/lsm6dsox/lsm6dsox_basic.py delete mode 100644 drivers/lsm6dsox/lsm6dsox_mlc.py delete mode 100644 drivers/lsm6dsox/manifest.py delete mode 100644 drivers/lsm9ds1/lsm9ds1.py delete mode 100644 drivers/lsm9ds1/manifest.py delete mode 100644 drivers/neopixel/manifest.py delete mode 100644 drivers/neopixel/neopixel.py delete mode 100644 drivers/nrf24l01/manifest.py delete mode 100644 drivers/nrf24l01/nrf24l01.py delete mode 100644 drivers/nrf24l01/nrf24l01test.py delete mode 100644 drivers/onewire/ds18x20.py delete mode 100644 drivers/onewire/manifest.py delete mode 100644 drivers/onewire/onewire.py delete mode 100644 drivers/sdcard/manifest.py delete mode 100644 drivers/sdcard/sdcard.py delete mode 100644 drivers/sdcard/sdtest.py delete mode 100644 extmod/ntptime.py delete mode 100644 extmod/webrepl/manifest.py delete mode 100644 extmod/webrepl/webrepl.py delete mode 100644 extmod/webrepl/webrepl_setup.py diff --git a/drivers/README.md b/drivers/README.md index 854acc50b62c..e4fac9fe8d43 100644 --- a/drivers/README.md +++ b/drivers/README.md @@ -1,2 +1,2 @@ -This directory contains drivers for specific hardware. The drivers are +This directory contains C drivers for specific hardware. The drivers are intended to work across multiple ports. diff --git a/drivers/codec/manifest.py b/drivers/codec/manifest.py deleted file mode 100644 index 4ff5d9fc445e..000000000000 --- a/drivers/codec/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("wm8960.py", opt=3) diff --git a/drivers/codec/wm8960.py b/drivers/codec/wm8960.py deleted file mode 100644 index ad1cb1cbf872..000000000000 --- a/drivers/codec/wm8960.py +++ /dev/null @@ -1,753 +0,0 @@ -# -# Driver class for the WM8960 Codec to be used e.g. with MIMXRT_1xxx Boards. -# Derived from the NXP SDK drivers. -# -# Copyright (c) 2015, Freescale Semiconductor, Inc., (C-Code) -# Copyright 2016-2021 NXP, (C-Code) -# All rights reserved. -# -# Translated to MicroPython by Robert Hammelrath, 2022 -# -# SPDX-License-Identifier: BSD-3-Clause -# - -import array -from micropython import const - -# Define the register addresses of WM8960. -_LINVOL = const(0x0) -_RINVOL = const(0x1) -_LOUT1 = const(0x2) -_ROUT1 = const(0x3) -_CLOCK1 = const(0x4) -_DACCTL1 = const(0x5) -_DACCTL2 = const(0x6) -_IFACE1 = const(0x7) -_CLOCK2 = const(0x8) -_IFACE2 = const(0x9) -_LDAC = const(0xA) -_RDAC = const(0xB) -_RESET = const(0xF) -_3D = const(0x10) -_ALC1 = const(0x11) -_ALC2 = const(0x12) -_ALC3 = const(0x13) -_NOISEG = const(0x14) -_LADC = const(0x15) -_RADC = const(0x16) -_ADDCTL1 = const(0x17) -# Register _ADDCTL2 = const(0x18) -_POWER1 = const(0x19) -_POWER2 = const(0x1A) -_ADDCTL3 = const(0x1B) -# Register _APOP1 = const(0x1C) -# Register _APOP2 = const(0x1D) -_LINPATH = const(0x20) -_RINPATH = const(0x21) -_LOUTMIX = const(0x22) -_ROUTMIX = const(0x25) -_MONOMIX1 = const(0x26) -_MONOMIX2 = const(0x27) -_LOUT2 = const(0x28) -_ROUT2 = const(0x29) -_MONO = const(0x2A) -_INBMIX1 = const(0x2B) -_INBMIX2 = const(0x2C) -_BYPASS1 = const(0x2D) -_BYPASS2 = const(0x2E) -_POWER3 = const(0x2F) -_ADDCTL4 = const(0x30) -_CLASSD1 = const(0x31) -# Register _CLASSD3 = const(0x33) -_PLL1 = const(0x34) -_PLL2 = const(0x35) -_PLL3 = const(0x36) -_PLL4 = const(0x37) - -# WM8960 PLLN range */ -_PLL_N_MIN_VALUE = const(6) -_PLL_N_MAX_VALUE = const(12) - -# WM8960 CLOCK2 bits -_CLOCK2_BCLK_DIV_MASK = const(0x0F) -_CLOCK2_DCLK_DIV_MASK = const(0x1C0) -_CLOCK2_DCLK_DIV_SHIFT = const(0x06) - -# Register _IFACE1 -_IFACE1_FORMAT_MASK = const(0x03) -_IFACE1_WL_MASK = const(0x0C) -_IFACE1_WL_SHIFT = const(0x02) -_IFACE1_LRP_MASK = const(0x10) -_IFACE1_MS_MASK = const(0x40) -_IFACE1_DLRSWAP_MASK = const(0x20) -_IFACE1_ALRSWAP_MASK = const(0x100) - -# Register _POWER1 -_POWER1_VREF_MASK = const(0x40) -_POWER1_VREF_SHIFT = const(0x06) -_POWER1_AINL_MASK = const(0x20) -_POWER1_AINR_MASK = const(0x10) -_POWER1_ADCL_MASK = const(0x08) -_POWER1_ADCR_MASK = const(0x0) -_POWER1_MICB_MASK = const(0x02) -_POWER1_MICB_SHIFT = const(0x01) - -# Register _POWER2 -_POWER2_DACL_MASK = const(0x100) -_POWER2_DACR_MASK = const(0x80) -_POWER2_LOUT1_MASK = const(0x40) -_POWER2_ROUT1_MASK = const(0x20) -_POWER2_SPKL_MASK = const(0x10) -_POWER2_SPKR_MASK = const(0x08) -_POWER3_LMIC_MASK = const(0x20) -_POWER3_RMIC_MASK = const(0x10) -_POWER3_LOMIX_MASK = const(0x08) -_POWER3_ROMIX_MASK = const(0x04) - -# Register _DACCTL1 .. 3 -_DACCTL1_MONOMIX_MASK = const(0x10) -_DACCTL1_MONOMIX_SHIFT = const(0x4) -_DACCTL1_DACMU_MASK = const(0x08) -_DACCTL1_DEEM_MASK = const(0x06) -_DACCTL1_DEEM_SHIFT = const(0x01) -_DACCTL2_DACSMM_MASK = const(0x08) -_DACCTL2_DACMR_MASK = const(0x04) -_DACCTL3_ALCSR_MASK = const(0x07) - -# _WM8060_ALC1 .. 3 -_ALC_CHANNEL_MASK = const(0x180) -_ALC_CHANNEL_SHIFT = const(0x7) -_ALC_MODE_MASK = const(0x100) -_ALC_MODE_SHIFT = const(0x8) -_ALC_GAIN_MASK = const(0x70) -_ALC_GAIN_SHIFT = const(0x4) -_ALC_TARGET_MASK = const(0x0F) -_ALC_ATTACK_MASK = const(0x0F) -_ALC_DECAY_MASK = const(0xF0) -_ALC_DECAY_SHIFT = const(4) -_ALC_HOLD_MASK = const(0xF) - -# Register _NOISEG -_NOISEG_LEVEL_SHIFT = const(3) - -_I2C_ADDR = const(0x1A) - -# WM8960 maximum volume values -_MAX_VOLUME_ADC = const(0xFF) -_MAX_VOLUME_DAC = const(0xFF) -_MAX_VOLUME_HEADPHONE = const(0x7F) -_MAX_VOLUME_LINEIN = const(0x3F) -_MAX_VOLUME_SPEAKER = const(0x7F) - -# Config symbol names -# Modules -MODULE_ADC = const(0) # ADC module in WM8960 -MODULE_DAC = const(1) # DAC module in WM8960 -MODULE_VREF = const(2) # VREF module -MODULE_HEADPHONE = const(3) # Headphone -MODULE_MIC_BIAS = const(4) # Mic bias -MODULE_MIC = const(5) # Input Mic -MODULE_LINE_IN = const(6) # Analog in PGA -MODULE_LINE_OUT = const(7) # Line out module -MODULE_SPEAKER = const(8) # Speaker module -MODULE_OMIX = const(9) # Output mixer -MODULE_MONO_OUT = const(10) # Mono mix - -# Route -ROUTE_BYPASS = const(0) # LINEIN->Headphone. -ROUTE_PLAYBACK = const(1) # I2SIN->DAC->Headphone. -ROUTE_PLAYBACK_RECORD = const(2) # I2SIN->DAC->Headphone, LINEIN->ADC->I2SOUT. -ROUTE_RECORD = const(5) # LINEIN->ADC->I2SOUT. - -# Input -INPUT_CLOSED = const(0) # Input device is closed -INPUT_MIC1 = const(1) # Input as single ended mic, only use L/RINPUT1 -INPUT_MIC2 = const(2) # Input as diff. mic, use L/RINPUT1 and L/RINPUT2 -INPUT_MIC3 = const(3) # Input as diff. mic, use L/RINPUT1 and L/RINPUT3 -INPUT_LINE2 = const(4) # Input as line input, only use L/RINPUT2 -INPUT_LINE3 = const(5) # Input as line input, only use L/RINPUT3 - -# ADC sync input -SYNC_ADC = const(0) # Use ADCLRC pin for ADC sync -SYNC_DAC = const(1) # used DACLRC pin for ADC sync - -# Protocol type -BUS_I2S = const(2) # I2S type -BUS_LEFT_JUSTIFIED = const(1) # Left justified mode -BUS_RIGHT_JUSTIFIED = const(0) # Right justified mode -BUS_PCMA = const(3) # PCM A mode -BUS_PCMB = const(3 | (1 << 4)) # PCM B mode - -# Channel swap -SWAP_NONE = const(0) -SWAP_INPUT = const(1) -SWAP_OUTPUT = const(2) - -# Mute settings -MUTE_FAST = const(0) -MUTE_SLOW = const(1) - -# ALC settings -ALC_OFF = const(0) -ALC_RIGHT = const(1) -ALC_LEFT = const(2) -ALC_STEREO = const(3) -ALC_MODE = const(0) # ALC mode -ALC_LIMITER = const(1) # Limiter mode - -# Clock Source -SYSCLK_MCLK = const(0) # sysclk source from external MCLK -SYSCLK_PLL = const(1) # sysclk source from internal PLL - - -class Regs: - # register cache of 56 register. Since registers cannot be read back, they are - # kept in the table for modification - # fmt: off - cache = array.array("H", ( - 0x0097, 0x0097, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, - 0x000a, 0x01c0, 0x0000, 0x00ff, 0x00ff, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x007b, 0x0100, 0x0032, 0x0000, - 0x00c3, 0x00c3, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x0050, - 0x0050, 0x0050, 0x0050, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0040, 0x0000, 0x0000, 0x0050, 0x0050, 0x0000, 0x0002, - 0x0037, 0x004d, 0x0080, 0x0008, 0x0031, 0x0026, 0x00e9 - )) - # fmt: on - - def __init__(self, i2c, i2c_address=_I2C_ADDR): - self.value_buffer = bytearray(2) - self.i2c = i2c - self.i2c_address = i2c_address - - def __getitem__(self, reg): - return self.cache[reg] - - def __setitem__(self, reg, value): - if type(reg) is tuple: - if type(value) is tuple: - self[reg[0]] = value[0] - self[reg[1]] = value[1] - else: - self[reg[0]] = value - self[reg[1]] = value - else: - if type(value) is tuple: - val = (self.cache[reg] & (~value[0] & 0xFFFF)) | value[1] - else: - val = value - self.cache[reg] = val - self.value_buffer[0] = (reg << 1) | ((val >> 8) & 0x01) - self.value_buffer[1] = val & 0xFF - self.i2c.writeto(self.i2c_address, self.value_buffer) - - -class WM8960: - - _bit_clock_divider_table = { - 2: 0, - 3: 1, - 4: 2, - 6: 3, - 8: 4, - 11: 5, - 12: 6, - 16: 7, - 22: 8, - 24: 9, - 32: 10, - 44: 11, - 48: 12, - } - - _dac_divider_table = { - 1.0 * 256: 0b000, - 1.5 * 256: 0b001, - 2 * 256: 0b010, - 3 * 256: 0b011, - 4 * 256: 0b100, - 5.5 * 256: 0b101, - 6 * 256: 0b110, - } - - _audio_word_length_table = { - 16: 0b00, - 20: 0b01, - 24: 0b10, - 32: 0b11, - } - - _alc_sample_rate_table = { - 48000: 0, - 44100: 0, - 32000: 1, - 24000: 2, - 22050: 2, - 16000: 3, - 12000: 4, - 11025: 4, - 8000: 5, - } - - _volume_config_table = { - MODULE_ADC: (_MAX_VOLUME_ADC, _LADC, 0x100), - MODULE_DAC: (_MAX_VOLUME_DAC, _LDAC, 0x100), - MODULE_HEADPHONE: (_MAX_VOLUME_HEADPHONE, _LOUT1, 0x180), - MODULE_LINE_IN: (_MAX_VOLUME_LINEIN, _LINVOL, 0x140), - MODULE_SPEAKER: (_MAX_VOLUME_SPEAKER, _LOUT2, 0x180), - } - - _input_config_table = { - INPUT_CLOSED: None, - INPUT_MIC1: (0x138, 0x117), - INPUT_MIC2: (0x178, 0x117), - INPUT_MIC3: (0x1B8, 0x117), - INPUT_LINE2: (0, 0xE), - INPUT_LINE3: (0, 0x70), - } - - def __init__( - self, - i2c, - sample_rate=16000, - bits=16, - swap=SWAP_NONE, - route=ROUTE_PLAYBACK_RECORD, - left_input=INPUT_MIC3, - right_input=INPUT_MIC2, - sysclk_source=SYSCLK_MCLK, - mclk_freq=None, - primary=False, - adc_sync=SYNC_DAC, - protocol=BUS_I2S, - i2c_address=_I2C_ADDR, - ): - self.regs = regs = Regs(i2c, i2c_address) - self.sample_rate = sample_rate - - # check parameter consistency and set the sysclk value - if sysclk_source == SYSCLK_PLL: - if sample_rate in (11025, 22050, 44100): - sysclk = 11289600 - else: - sysclk = 12288000 - if sysclk < sample_rate * 256: - sysclk = sample_rate * 256 - if mclk_freq is None: - mclk_freq = sysclk - else: # sysclk_source == SYSCLK_MCLK - if mclk_freq is None: - mclk_freq = sample_rate * 256 - sysclk = mclk_freq - - regs[_RESET] = 0x00 - # VMID=50K, Enable VREF, AINL, AINR, ADCL and ADCR - # I2S_IN (bit 0), I2S_OUT (bit 1), DAP (bit 4), DAC (bit 5), ADC (bit 6) are powered on - regs[_POWER1] = 0xFE - # Enable DACL, DACR, LOUT1, ROUT1, PLL down, SPKL, SPKR - regs[_POWER2] = 0x1F8 - # Enable left and right channel input PGA, left and right output mixer - regs[_POWER3] = 0x3C - - if adc_sync == SYNC_ADC: - # ADC and DAC use different Frame Clock Pins - regs[_IFACE2] = 0x00 # ADCLRC 0x00:Input 0x40:output. - else: - # ADC and DAC use the same Frame Clock Pin - regs[_IFACE2] = 0x40 # ADCLRC 0x00:Input 0x40:output. - self.set_data_route(route) - self.set_protocol(protocol) - - if sysclk_source == SYSCLK_PLL: - self.set_internal_pll_config(mclk_freq, sysclk) - if primary: - self.set_master_clock(sysclk, sample_rate, bits) - # set master bit. - self.regs[_IFACE1] = (0, _IFACE1_MS_MASK) - - self.set_speaker_clock(sysclk) - - # swap channels - if swap & SWAP_INPUT: - regs[_IFACE1] = (0, _IFACE1_ALRSWAP_MASK) - if swap & SWAP_OUTPUT: - regs[_IFACE1] = (0, _IFACE1_DLRSWAP_MASK) - - self.set_left_input(left_input) - self.set_right_input(right_input) - - regs[_ADDCTL1] = 0x0C0 - regs[_ADDCTL4] = 0x60 # Set GPIO1 to 0. - - regs[_BYPASS1] = regs[_BYPASS2] = 0x0 - # ADC volume, 0dB - regs[_LADC, _RADC] = 0x1C3 - # Digital DAC volume, 0dB - regs[_LDAC, _RDAC] = 0x1FF - # Headphone volume, LOUT1 and ROUT1, 0dB - regs[_LOUT1, _ROUT1] = 0x16F - # speaker volume 6dB - regs[_LOUT2, _ROUT2] = 0x1FF - # enable class D output - regs[_CLASSD1] = 0xF7 - # Unmute DAC. - regs[_DACCTL1] = 0x0000 - # Input PGA volume 0 dB - regs[_LINVOL, _RINVOL] = 0x117 - - self.config_data_format(sysclk, sample_rate, bits) - - def deinit(self): - - self.set_module(MODULE_ADC, False) - self.set_module(MODULE_DAC, False) - self.set_module(MODULE_VREF, False) - self.set_module(MODULE_LINE_IN, False) - self.set_module(MODULE_LINE_OUT, False) - self.set_module(MODULE_SPEAKER, False) - - def set_internal_pll_config(self, input_mclk, output_clk): - regs = self.regs - pllF2 = output_clk * 4 - pll_prescale = 0 - sysclk_div = 1 - frac_mode = 0 - - # disable PLL power - regs[_POWER2] = (1, 0) - regs[_CLOCK1] = (7, 0) - - pllN = pllF2 // input_mclk - if pllN < _PLL_N_MIN_VALUE: - input_mclk //= 2 - pll_prescale = 1 - pllN = pllF2 // input_mclk - if pllN < _PLL_N_MIN_VALUE: - sysclk_div = 2 - pllF2 *= 2 - pllN = pllF2 // input_mclk - - if (pllN < _PLL_N_MIN_VALUE) or (pllN > _PLL_N_MAX_VALUE): - raise ValueError("Invalid MCLK vs. sysclk ratio") - - pllK = ((pllF2 % input_mclk) * (1 << 24)) // input_mclk - if pllK != 0: - frac_mode = 1 - - regs[_PLL1] = (frac_mode << 5) | (pll_prescale << 4) | (pllN & 0x0F) - regs[_PLL2] = (pllK >> 16) & 0xFF - regs[_PLL3] = (pllK >> 8) & 0xFF - regs[_PLL4] = pllK & 0xFF - # enable PLL power - regs[_POWER2] = (1, 1) - regs[_CLOCK1] = (7, ((0 if sysclk_div == 1 else sysclk_div) << 1) | 1) - - def set_master_clock(self, sysclk, sample_rate, bit_width): - bit_clock_divider = (sysclk * 2) // (sample_rate * bit_width * 2) - try: - reg_divider = self._bit_clock_divider_table[bit_clock_divider] - except: - raise ValueError("Invalid ratio of sysclk sample rate and bits") - # configure the master bit clock divider - self.regs[_CLOCK2] = (_CLOCK2_BCLK_DIV_MASK, reg_divider) - - def set_speaker_clock(self, sysclk): - speaker_divider_table = (1.5, 2, 3, 4, 6, 8, 12, 16) - for val in range(8): - divider = speaker_divider_table[val] - f = sysclk / divider - if 500_000 < f < 1_000_000: - break - else: - val = 7 - self.regs[_CLOCK2] = ( - _CLOCK2_DCLK_DIV_MASK, - val << _CLOCK2_DCLK_DIV_SHIFT, - ) - - def set_module(self, module, is_enabled): - - is_enabled = 1 if is_enabled else 0 - regs = self.regs - - if module == MODULE_ADC: - - regs[_POWER1] = ( - _POWER1_ADCL_MASK | _POWER1_ADCR_MASK, - (_POWER1_ADCL_MASK | _POWER1_ADCR_MASK) * is_enabled, - ) - - elif module == MODULE_DAC: - - regs[_POWER2] = ( - _POWER2_DACL_MASK | _POWER2_DACR_MASK, - (_POWER2_DACL_MASK | _POWER2_DACR_MASK) * is_enabled, - ) - - elif module == MODULE_VREF: - - regs[_POWER1] = ( - _POWER1_VREF_MASK, - (is_enabled << _POWER1_VREF_SHIFT), - ) - - elif module == MODULE_LINE_IN: - - regs[_POWER1] = ( - _POWER1_AINL_MASK | _POWER1_AINR_MASK, - (_POWER1_AINL_MASK | _POWER1_AINR_MASK) * is_enabled, - ) - regs[_POWER3] = ( - _POWER3_LMIC_MASK | _POWER3_RMIC_MASK, - (_POWER3_LMIC_MASK | _POWER3_RMIC_MASK) * is_enabled, - ) - - elif module == MODULE_LINE_OUT: - - regs[_POWER2] = ( - _POWER2_LOUT1_MASK | _POWER2_ROUT1_MASK, - (_POWER2_LOUT1_MASK | _POWER2_ROUT1_MASK) * is_enabled, - ) - - elif module == MODULE_MIC_BIAS: - - regs[_POWER1] = ( - _POWER1_MICB_MASK, - (is_enabled << _POWER1_MICB_SHIFT), - ) - - elif module == MODULE_SPEAKER: - - regs[_POWER2] = ( - _POWER2_SPKL_MASK | _POWER2_SPKR_MASK, - (_POWER2_SPKL_MASK | _POWER2_SPKR_MASK) * is_enabled, - ) - regs[_CLASSD1] = 0xF7 - - elif module == MODULE_OMIX: - - regs[_POWER3] = ( - _POWER3_LOMIX_MASK | _POWER3_ROMIX_MASK, - (_POWER3_LOMIX_MASK | _POWER3_ROMIX_MASK) * is_enabled, - ) - - elif module == MODULE_MONO_OUT: - - regs[_MONOMIX1] = regs[_MONOMIX2] = is_enabled << 7 - regs[_MONO] = is_enabled << 6 - - else: - raise ValueError("Invalid module") - - def enable_module(self, module): - self.set_module(module, True) - - def disable_module(self, module): - self.set_module(module, False) - - def set_data_route(self, route): - regs = self.regs - if route == ROUTE_BYPASS: - # Bypass means from line-in to HP - # Left LINPUT3 to left output mixer, LINPUT3 left output mixer volume = 0dB - # Right RINPUT3 to right output mixer, RINPUT3 right output mixer volume = 0dB - regs[_LOUTMIX, _ROUTMIX] = 0x80 - - elif route == ROUTE_PLAYBACK: - # Data route I2S_IN-> DAC-> HP - # - # Left DAC to left output mixer, LINPUT3 left output mixer volume = 0dB - # Right DAC to right output mixer, RINPUT3 right output mixer volume = 0dB - regs[_LOUTMIX, _ROUTMIX] = 0x100 - regs[_POWER3] = 0x0C - # Set power for DAC - self.set_module(MODULE_DAC, True) - self.set_module(MODULE_OMIX, True) - self.set_module(MODULE_LINE_OUT, True) - - elif route == ROUTE_PLAYBACK_RECORD: - # - # Left DAC to left output mixer, LINPUT3 left output mixer volume = 0dB - # Right DAC to right output mixer, RINPUT3 right output mixer volume = 0dB - regs[_LOUTMIX, _ROUTMIX] = 0x100 - regs[_POWER3] = 0x3C - self.set_module(MODULE_DAC, True) - self.set_module(MODULE_ADC, True) - self.set_module(MODULE_LINE_IN, True) - self.set_module(MODULE_OMIX, True) - self.set_module(MODULE_LINE_OUT, True) - - elif route == ROUTE_RECORD: - # LINE_IN->ADC->I2S_OUT - # Left and right input boost, LIN3BOOST and RIN3BOOST = 0dB - regs[_POWER3] = 0x30 - # Power up ADC and AIN - self.set_module(MODULE_LINE_IN, True) - self.set_module(MODULE_ADC, True) - - else: - raise ValueError("Invalid route") - - def set_left_input(self, input): - if not input in self._input_config_table.keys(): - raise ValueError("Invalid input") - - input = self._input_config_table[input] - - regs = self.regs - if input is None: - regs[_POWER1] = (_POWER1_AINL_MASK | _POWER1_ADCL_MASK, 0) - elif input[0] == 0: - regs[_POWER1] = (0, _POWER1_AINL_MASK | _POWER1_ADCL_MASK) - regs[_INBMIX1] = input - else: - regs[_POWER1] = (0, _POWER1_AINL_MASK | _POWER1_ADCL_MASK | _POWER1_MICB_MASK) - regs[_LINPATH] = input[0] - regs[_LINVOL] = input[1] - - def set_right_input(self, input): - if not input in self._input_config_table.keys(): - raise ValueError("Invalid input name") - - input = self._input_config_table[input] - - regs = self.regs - if input is None: - regs[_POWER1] = (_POWER1_AINR_MASK | _POWER1_ADCR_MASK, 0) - elif input[0] == 0: - regs[_POWER1] = (0, _POWER1_AINL_MASK | _POWER1_ADCR_MASK) - regs[_INBMIX2] = input - else: - regs[_POWER1] = (0, _POWER1_AINR_MASK | _POWER1_ADCR_MASK | _POWER1_MICB_MASK) - regs[_RINPATH] = input[0] - regs[_RINVOL] = input[1] - - def set_protocol(self, protocol): - self.regs[_IFACE1] = ( - _IFACE1_FORMAT_MASK | _IFACE1_LRP_MASK, - protocol, - ) - - def config_data_format(self, sysclk, sample_rate, bits): - # Compute sample rate divider, dac and adc are the same sample rate - try: - divider = self._dac_divider_table[sysclk // sample_rate] - wl = self._audio_word_length_table[bits] - except: - raise ValueError("Invalid ratio sysclk/sample_rate or invalid bit length") - - self.regs[_CLOCK1] = (0x1F8, divider << 6 | divider << 3) - self.regs[_IFACE1] = (_IFACE1_WL_MASK, wl << _IFACE1_WL_SHIFT) - - def volume(self, module, volume_l=None, volume_r=None): - if not module in self._volume_config_table.keys(): - raise ValueError("Invalid module") - - if volume_l is None: # get volume - vol_max, regnum, _ = self._volume_config_table[module] - return ( - int((self.regs[regnum] & vol_max) * 100 / vol_max + 0.5), - int((self.regs[regnum + 1] & vol_max) * 100 / vol_max + 0.5), - ) - else: # set volume - if volume_r is None: - volume_r = volume_l - - if not ((0 <= volume_l <= 100) and (0 <= volume_r <= 100)): - raise ValueError("Invalid value for volume") - elif not module in self._volume_config_table.keys(): - raise ValueError("Invalid module") - - vol_max, regnum, flags = self._volume_config_table[module] - self.regs[regnum] = int(volume_l * vol_max / 100 + 0.5) | flags - self.regs[regnum + 1] = int(volume_r * vol_max / 100 + 0.5) | flags - - def mute(self, enable, soft=True, ramp=MUTE_FAST): - enable = _DACCTL1_DACMU_MASK if enable else 0 - soft = _DACCTL2_DACSMM_MASK if soft else 0 - ramp = _DACCTL2_DACMR_MASK if ramp == MUTE_SLOW else 0 - self.regs[_DACCTL1] = (_DACCTL1_DACMU_MASK, enable) - self.regs[_DACCTL2] = ( - _DACCTL2_DACSMM_MASK | _DACCTL2_DACMR_MASK, - soft | ramp, - ) - - def expand_3d(self, depth=0): - depth &= 0x0F - cutoff = 0 if self.sample_rate >= 32000 else 0b1100000 - self.regs[_3D] = cutoff | depth << 1 | (1 if depth > 0 else 0) - - def mono(self, enable): - enable = 1 if enable else 0 - self.regs[_DACCTL1] = ( - _DACCTL1_MONOMIX_MASK, - enable << _DACCTL1_MONOMIX_SHIFT, - ) - - def alc_mode(self, channel, mode=ALC_MODE): - if mode != ALC_MODE: - mode = ALC_LIMITER - channel &= 3 - self.regs[_ALC1] = ( - _ALC_CHANNEL_MASK, - channel << _ALC_CHANNEL_SHIFT, - ) - self.regs[_ALC3] = (_ALC_MODE_MASK, mode << _ALC_MODE_SHIFT) - try: - rate = _alc_sample_rate_table[self.sample_rate] - except: - rate = 0 - self.regs[_ADDCTL3] = (_DACCTL3_ALCSR_MASK, rate) - - def alc_gain(self, target=-12, max_gain=30, min_gain=-17.25, noise_gate=-78): - def limit(value, minval, maxval): - value = int(value) - if value < minval: - value = minval - if value > maxval: - value = maxval - return value - - target = limit((16 + (target * 2) // 3), 0, 15) - max_gain = limit((max_gain + 12) // 6, 0, 7) - min_gain = limit((min_gain * 4 + 69) // 24, 0, 7) - noise_gate = limit((noise_gate * 2 + 153) // 3, -1, 31) - self.regs[_ALC1] = ( - _ALC_GAIN_MASK | _ALC_TARGET_MASK, - (max_gain << _ALC_GAIN_SHIFT) | target, - ) - self.regs[_ALC2] = (_ALC_GAIN_MASK, (min_gain << _ALC_GAIN_SHIFT)) - if noise_gate >= 0: - self.regs[_NOISEG] = noise_gate << _NOISEG_LEVEL_SHIFT | 1 - else: - self.regs[_NOISEG] = 0 - - def alc_time(self, attack=24, decay=192, hold=0): - def logb(value, limit): - value = int(value) - lb = 0 - while value > 1: - value >>= 1 - lb += 1 - if lb > limit: - lb = limit - return lb - - attack = logb(attack / 6, 7) - decay = logb(decay / 24, 7) - hold = logb((hold * 3) / 8, 15) - self.regs[_ALC2] = (_ALC_HOLD_MASK, hold) - self.regs[_ALC3] = ( - _ALC_DECAY_MASK | _ALC_ATTACK_MASK, - (decay << _ALC_DECAY_SHIFT) | attack, - ) - - def deemphasis(self, enable): - deem_table = (32000, 44100, 48000) - enable = not not enable - if enable and self.sample_rate in deem_table: - val = deem_table.index(self.sample_rate) + 1 - else: - val = 0 - self.regs[_DACCTL1] = (_DACCTL1_DEEM_MASK, val << _DACCTL1_DEEM_SHIFT) diff --git a/drivers/dht/dht.py b/drivers/dht/dht.py deleted file mode 100644 index 411e9a8d28a6..000000000000 --- a/drivers/dht/dht.py +++ /dev/null @@ -1,46 +0,0 @@ -# DHT11/DHT22 driver for MicroPython on ESP8266 -# MIT license; Copyright (c) 2016 Damien P. George - -import sys - -if sys.platform.startswith("esp"): - from esp import dht_readinto -elif sys.platform == "mimxrt": - from mimxrt import dht_readinto -elif sys.platform == "rp2": - from rp2 import dht_readinto -elif sys.platform == "pyboard": - from pyb import dht_readinto -else: - from machine import dht_readinto - - -class DHTBase: - def __init__(self, pin): - self.pin = pin - self.buf = bytearray(5) - - def measure(self): - buf = self.buf - dht_readinto(self.pin, buf) - if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]: - raise Exception("checksum error") - - -class DHT11(DHTBase): - def humidity(self): - return self.buf[0] - - def temperature(self): - return self.buf[2] - - -class DHT22(DHTBase): - def humidity(self): - return (self.buf[0] << 8 | self.buf[1]) * 0.1 - - def temperature(self): - t = ((self.buf[2] & 0x7F) << 8 | self.buf[3]) * 0.1 - if self.buf[2] & 0x80: - t = -t - return t diff --git a/drivers/dht/manifest.py b/drivers/dht/manifest.py deleted file mode 100644 index 72a4e0d24fcd..000000000000 --- a/drivers/dht/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("dht.py", opt=3) diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py deleted file mode 100644 index f792418aa2b5..000000000000 --- a/drivers/display/lcd160cr.py +++ /dev/null @@ -1,482 +0,0 @@ -# Driver for official MicroPython LCD160CR display -# MIT license; Copyright (c) 2017 Damien P. George - -from micropython import const -from utime import sleep_ms -from ustruct import calcsize, pack_into -import uerrno, machine - -# for set_orient -PORTRAIT = const(0) -LANDSCAPE = const(1) -PORTRAIT_UPSIDEDOWN = const(2) -LANDSCAPE_UPSIDEDOWN = const(3) - -# for set_startup_deco; can be or'd -STARTUP_DECO_NONE = const(0) -STARTUP_DECO_MLOGO = const(1) -STARTUP_DECO_INFO = const(2) - -_uart_baud_table = { - 2400: 0, - 4800: 1, - 9600: 2, - 19200: 3, - 38400: 4, - 57600: 5, - 115200: 6, - 230400: 7, - 460800: 8, -} - - -class LCD160CR: - def __init__(self, connect=None, *, pwr=None, i2c=None, spi=None, i2c_addr=98): - if connect in ("X", "Y", "XY", "YX"): - i = connect[-1] - j = connect[0] - y = j + "4" - elif connect == "C": - i = 2 - j = 2 - y = "A7" - else: - if pwr is None or i2c is None or spi is None: - raise ValueError('must specify valid "connect" or all of "pwr", "i2c" and "spi"') - - if pwr is None: - pwr = machine.Pin(y, machine.Pin.OUT) - if i2c is None: - i2c = machine.I2C(i, freq=1000000) - if spi is None: - spi = machine.SPI(j, baudrate=13500000, polarity=0, phase=0) - - if not pwr.value(): - pwr(1) - sleep_ms(10) - # else: - # alread have power - # lets be optimistic... - - # set connections - self.pwr = pwr - self.i2c = i2c - self.spi = spi - self.i2c_addr = i2c_addr - - # create temp buffers and memoryviews - self.buf16 = bytearray(16) - self.buf19 = bytearray(19) - self.buf = [None] * 10 - for i in range(1, 10): - self.buf[i] = memoryview(self.buf16)[0:i] - self.buf1 = self.buf[1] - self.array4 = [0, 0, 0, 0] - - # set default orientation and window - self.set_orient(PORTRAIT) - self._fcmd2b("= n: - self.i2c.readfrom_into(self.i2c_addr, buf) - return - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - def oflush(self, n=255): - t = 5000 - while t: - self.i2c.readfrom_into(self.i2c_addr + 1, self.buf1) - r = self.buf1[0] - if r >= n: - return - t -= 1 - machine.idle() - raise OSError(uerrno.ETIMEDOUT) - - def iflush(self): - t = 5000 - while t: - self.i2c.readfrom_into(self.i2c_addr, self.buf16) - if self.buf16[0] == 0: - return - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - #### MISC METHODS #### - - @staticmethod - def rgb(r, g, b): - return ((b & 0xF8) << 8) | ((g & 0xFC) << 3) | (r >> 3) - - @staticmethod - def clip_line(c, w, h): - while True: - ca = ce = 0 - if c[1] < 0: - ca |= 8 - elif c[1] > h: - ca |= 4 - if c[0] < 0: - ca |= 1 - elif c[0] > w: - ca |= 2 - if c[3] < 0: - ce |= 8 - elif c[3] > h: - ce |= 4 - if c[2] < 0: - ce |= 1 - elif c[2] > w: - ce |= 2 - if ca & ce: - return False - elif ca | ce: - ca |= ce - if ca & 1: - if c[2] < c[0]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[1] += ((-c[0]) * (c[3] - c[1])) // (c[2] - c[0]) - c[0] = 0 - elif ca & 2: - if c[2] < c[0]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[3] += ((w - 1 - c[2]) * (c[3] - c[1])) // (c[2] - c[0]) - c[2] = w - 1 - elif ca & 4: - if c[0] == c[2]: - if c[1] >= h: - c[1] = h - 1 - if c[3] >= h: - c[3] = h - 1 - else: - if c[3] < c[1]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[2] += ((h - 1 - c[3]) * (c[2] - c[0])) // (c[3] - c[1]) - c[3] = h - 1 - else: - if c[0] == c[2]: - if c[1] < 0: - c[1] = 0 - if c[3] < 0: - c[3] = 0 - else: - if c[3] < c[1]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[0] += ((-c[1]) * (c[2] - c[0])) // (c[3] - c[1]) - c[1] = 0 - else: - return True - - #### SETUP COMMANDS #### - - def set_power(self, on): - self.pwr(on) - sleep_ms(15) - - def set_orient(self, orient): - self._fcmd2("= 2: - self.i2c.readfrom_into(self.i2c_addr, self.buf[3]) - return self.buf[3][1] | self.buf[3][2] << 8 - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - def get_line(self, x, y, buf): - l = len(buf) // 2 - self._fcmd2b("= l: - self.i2c.readfrom_into(self.i2c_addr, buf) - return - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - def screen_dump(self, buf, x=0, y=0, w=None, h=None): - if w is None: - w = self.w - x - if h is None: - h = self.h - y - if w <= 127: - line = bytearray(2 * w + 1) - line2 = None - else: - # split line if more than 254 bytes needed - buflen = (w + 1) // 2 - line = bytearray(2 * buflen + 1) - line2 = memoryview(line)[: 2 * (w - buflen) + 1] - for i in range(min(len(buf) // (2 * w), h)): - ix = i * w * 2 - self.get_line(x, y + i, line) - buf[ix : ix + len(line) - 1] = memoryview(line)[1:] - ix += len(line) - 1 - if line2: - self.get_line(x + buflen, y + i, line2) - buf[ix : ix + len(line2) - 1] = memoryview(line2)[1:] - ix += len(line2) - 1 - - def screen_load(self, buf): - l = self.w * self.h * 2 + 2 - self._fcmd2b("= 0x200: - self._send(ar[n : n + 0x200]) - n += 0x200 - else: - self._send(ar[n:]) - while n < self.w * self.h * 2: - self._send(b"\x00") - n += 1 - - #### TEXT COMMANDS #### - - def set_pos(self, x, y): - self._fcmd2("= self.w or y >= self.h: - return - elif x < 0 or y < 0: - left = top = True - if x < 0: - left = False - w += x - x = 0 - if y < 0: - top = False - h += y - y = 0 - if cmd == 0x51 or cmd == 0x72: - # draw interior - self._fcmd2b("> 7 != 0 - - def get_touch(self): - self._send(b"\x02T") # implicit LCD output flush - b = self.buf[4] - self._waitfor(3, b) - return b[1] >> 7, b[2], b[3] - - #### ADVANCED COMMANDS #### - - def set_spi_win(self, x, y, w, h): - pack_into( - " 32: - raise ValueError("length must be 32 or less") - self._fcmd2(" 0xFFFF: - raise ValueError("length must be 65535 or less") - self.oflush() - self._fcmd2(" 0: - s = "%6.3fV" % data[i] - else: - s = "%5.1f°C" % data[i] - if lcd.h == 160: - lcd.set_font(1, bold=0, scale=1) - else: - lcd.set_font(1, bold=0, scale=1, trans=1) - lcd.set_pos(45, lcd.h - 60 + i * 16) - lcd.write(s) - - -def test_features(lcd, orient=lcd160cr.PORTRAIT): - # if we run on pyboard then use ADC and RTC features - try: - import pyb - - adc = pyb.ADCAll(12, 0xF0000) - rtc = pyb.RTC() - except: - adc = None - rtc = None - - # set orientation and clear screen - lcd = get_lcd(lcd) - lcd.set_orient(orient) - lcd.set_pen(0, 0) - lcd.erase() - - # create M-logo - mlogo = framebuf.FrameBuffer(bytearray(17 * 17 * 2), 17, 17, framebuf.RGB565) - mlogo.fill(0) - mlogo.fill_rect(1, 1, 15, 15, 0xFFFFFF) - mlogo.vline(4, 4, 12, 0) - mlogo.vline(8, 1, 12, 0) - mlogo.vline(12, 4, 12, 0) - mlogo.vline(14, 13, 2, 0) - - # create inline framebuf - offx = 14 - offy = 19 - w = 100 - h = 75 - fbuf = framebuf.FrameBuffer(bytearray(w * h * 2), w, h, framebuf.RGB565) - lcd.set_spi_win(offx, offy, w, h) - - # initialise loop parameters - tx = ty = 0 - t0 = time.ticks_us() - - for i in range(300): - # update position of cross-hair - t, tx2, ty2 = lcd.get_touch() - if t: - tx2 -= offx - ty2 -= offy - if tx2 >= 0 and ty2 >= 0 and tx2 < w and ty2 < h: - tx, ty = tx2, ty2 - else: - tx = (tx + 1) % w - ty = (ty + 1) % h - - # create and show the inline framebuf - fbuf.fill(lcd.rgb(128 + int(64 * math.cos(0.1 * i)), 128, 192)) - fbuf.line( - w // 2, - h // 2, - w // 2 + int(40 * math.cos(0.2 * i)), - h // 2 + int(40 * math.sin(0.2 * i)), - lcd.rgb(128, 255, 64), - ) - fbuf.hline(0, ty, w, lcd.rgb(64, 64, 64)) - fbuf.vline(tx, 0, h, lcd.rgb(64, 64, 64)) - fbuf.rect(tx - 3, ty - 3, 7, 7, lcd.rgb(64, 64, 64)) - for phase in (-0.2, 0, 0.2): - x = w // 2 - 8 + int(50 * math.cos(0.05 * i + phase)) - y = h // 2 - 8 + int(32 * math.sin(0.05 * i + phase)) - fbuf.blit(mlogo, x, y) - for j in range(-3, 3): - fbuf.text( - "MicroPython", - 5, - h // 2 + 9 * j + int(20 * math.sin(0.1 * (i + j))), - lcd.rgb(128 + 10 * j, 0, 128 - 10 * j), - ) - lcd.show_framebuf(fbuf) - - # show results from the ADC - if adc: - show_adc(lcd, adc) - - # show the time - if rtc: - lcd.set_pos(2, 0) - lcd.set_font(1) - t = rtc.datetime() - lcd.write( - "%4d-%02d-%02d %2d:%02d:%02d.%01d" - % (t[0], t[1], t[2], t[4], t[5], t[6], t[7] // 100000) - ) - - # compute the frame rate - t1 = time.ticks_us() - dt = time.ticks_diff(t1, t0) - t0 = t1 - - # show the frame rate - lcd.set_pos(2, 9) - lcd.write("%.2f fps" % (1000000 / dt)) - - -def test_mandel(lcd, orient=lcd160cr.PORTRAIT): - # set orientation and clear screen - lcd = get_lcd(lcd) - lcd.set_orient(orient) - lcd.set_pen(0, 0xFFFF) - lcd.erase() - - # function to compute Mandelbrot pixels - def in_set(c): - z = 0 - for i in range(32): - z = z * z + c - if abs(z) > 100: - return i - return 0 - - # cache width and height of LCD - w = lcd.w - h = lcd.h - - # create the buffer for each line and set SPI parameters - line = bytearray(w * 2) - lcd.set_spi_win(0, 0, w, h) - spi = lcd.fast_spi() - - # draw the Mandelbrot set line-by-line - hh = (h - 1) / 3.2 - ww = (w - 1) / 2.4 - for v in range(h): - for u in range(w): - c = in_set((v / hh - 2.3) + (u / ww - 1.2) * 1j) - if c < 16: - rgb = c << 12 | c << 6 - else: - rgb = 0xF800 | c << 6 - line[2 * u] = rgb - line[2 * u + 1] = rgb >> 8 - spi.write(line) - - -def test_all(lcd, orient=lcd160cr.PORTRAIT): - lcd = get_lcd(lcd) - test_features(lcd, orient) - test_mandel(lcd, orient) - - -print("To run all tests: test_all()") -print("Individual tests are: test_features, test_mandel") -print(' argument should be a connection, eg "X", or an LCD160CR object') diff --git a/drivers/display/manifest.py b/drivers/display/manifest.py deleted file mode 100644 index 16f93a7d4e99..000000000000 --- a/drivers/display/manifest.py +++ /dev/null @@ -1,11 +0,0 @@ -# TODO: Split these into separate directories with their own manifests. -options.defaults(lcd160cr=False, ssd1306=False, test=False) - -if options.lcd160cr: - module("lcd160cr.py", opt=3) - - if options.test: - module("lcd160cr_test.py", opt=3) - -if options.ssd1306: - module("ssd1306.py", opt=3) diff --git a/drivers/display/ssd1306.py b/drivers/display/ssd1306.py deleted file mode 100644 index a504cdadcc94..000000000000 --- a/drivers/display/ssd1306.py +++ /dev/null @@ -1,163 +0,0 @@ -# MicroPython SSD1306 OLED driver, I2C and SPI interfaces - -from micropython import const -import framebuf - - -# register definitions -SET_CONTRAST = const(0x81) -SET_ENTIRE_ON = const(0xA4) -SET_NORM_INV = const(0xA6) -SET_DISP = const(0xAE) -SET_MEM_ADDR = const(0x20) -SET_COL_ADDR = const(0x21) -SET_PAGE_ADDR = const(0x22) -SET_DISP_START_LINE = const(0x40) -SET_SEG_REMAP = const(0xA0) -SET_MUX_RATIO = const(0xA8) -SET_IREF_SELECT = const(0xAD) -SET_COM_OUT_DIR = const(0xC0) -SET_DISP_OFFSET = const(0xD3) -SET_COM_PIN_CFG = const(0xDA) -SET_DISP_CLK_DIV = const(0xD5) -SET_PRECHARGE = const(0xD9) -SET_VCOM_DESEL = const(0xDB) -SET_CHARGE_PUMP = const(0x8D) - -# Subclassing FrameBuffer provides support for graphics primitives -# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html -class SSD1306(framebuf.FrameBuffer): - def __init__(self, width, height, external_vcc): - self.width = width - self.height = height - self.external_vcc = external_vcc - self.pages = self.height // 8 - self.buffer = bytearray(self.pages * self.width) - super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB) - self.init_display() - - def init_display(self): - for cmd in ( - SET_DISP, # display off - # address setting - SET_MEM_ADDR, - 0x00, # horizontal - # resolution and layout - SET_DISP_START_LINE, # start at line 0 - SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 - SET_MUX_RATIO, - self.height - 1, - SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 - SET_DISP_OFFSET, - 0x00, - SET_COM_PIN_CFG, - 0x02 if self.width > 2 * self.height else 0x12, - # timing and driving scheme - SET_DISP_CLK_DIV, - 0x80, - SET_PRECHARGE, - 0x22 if self.external_vcc else 0xF1, - SET_VCOM_DESEL, - 0x30, # 0.83*Vcc - # display - SET_CONTRAST, - 0xFF, # maximum - SET_ENTIRE_ON, # output follows RAM contents - SET_NORM_INV, # not inverted - SET_IREF_SELECT, - 0x30, # enable internal IREF during display on - # charge pump - SET_CHARGE_PUMP, - 0x10 if self.external_vcc else 0x14, - SET_DISP | 0x01, # display on - ): # on - self.write_cmd(cmd) - self.fill(0) - self.show() - - def poweroff(self): - self.write_cmd(SET_DISP) - - def poweron(self): - self.write_cmd(SET_DISP | 0x01) - - def contrast(self, contrast): - self.write_cmd(SET_CONTRAST) - self.write_cmd(contrast) - - def invert(self, invert): - self.write_cmd(SET_NORM_INV | (invert & 1)) - - def rotate(self, rotate): - self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3)) - self.write_cmd(SET_SEG_REMAP | (rotate & 1)) - - def show(self): - x0 = 0 - x1 = self.width - 1 - if self.width != 128: - # narrow displays use centred columns - col_offset = (128 - self.width) // 2 - x0 += col_offset - x1 += col_offset - self.write_cmd(SET_COL_ADDR) - self.write_cmd(x0) - self.write_cmd(x1) - self.write_cmd(SET_PAGE_ADDR) - self.write_cmd(0) - self.write_cmd(self.pages - 1) - self.write_data(self.buffer) - - -class SSD1306_I2C(SSD1306): - def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False): - self.i2c = i2c - self.addr = addr - self.temp = bytearray(2) - self.write_list = [b"\x40", None] # Co=0, D/C#=1 - super().__init__(width, height, external_vcc) - - def write_cmd(self, cmd): - self.temp[0] = 0x80 # Co=1, D/C#=0 - self.temp[1] = cmd - self.i2c.writeto(self.addr, self.temp) - - def write_data(self, buf): - self.write_list[1] = buf - self.i2c.writevto(self.addr, self.write_list) - - -class SSD1306_SPI(SSD1306): - def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): - self.rate = 10 * 1024 * 1024 - dc.init(dc.OUT, value=0) - res.init(res.OUT, value=0) - cs.init(cs.OUT, value=1) - self.spi = spi - self.dc = dc - self.res = res - self.cs = cs - import time - - self.res(1) - time.sleep_ms(1) - self.res(0) - time.sleep_ms(10) - self.res(1) - super().__init__(width, height, external_vcc) - - def write_cmd(self, cmd): - self.spi.init(baudrate=self.rate, polarity=0, phase=0) - self.cs(1) - self.dc(0) - self.cs(0) - self.spi.write(bytearray([cmd])) - self.cs(1) - - def write_data(self, buf): - self.spi.init(baudrate=self.rate, polarity=0, phase=0) - self.cs(1) - self.dc(1) - self.cs(0) - self.spi.write(buf) - self.cs(1) diff --git a/drivers/hts221/hts221.py b/drivers/hts221/hts221.py deleted file mode 100644 index fec52a7389a9..000000000000 --- a/drivers/hts221/hts221.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -The MIT License (MIT) - -Copyright (c) 2013-2022 Ibrahim Abdelkader -Copyright (c) 2013-2022 Kwabena W. Agyeman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -HTS221 driver driver for MicroPython. -Original source: https://github.com/ControlEverythingCommunity/HTS221/blob/master/Python/HTS221.py - -Example usage: - -import time -import hts221 -from machine import Pin, I2C - -bus = I2C(1, scl=Pin(15), sda=Pin(14)) -hts = hts221.HTS221(bus) - -while (True): - rH = hts.humidity() - temp = hts.temperature() - print ("rH: %.2f%% T: %.2fC" %(rH, temp)) - time.sleep_ms(100) -""" - -import struct - - -class HTS221: - def __init__(self, i2c, data_rate=1, address=0x5F): - self.bus = i2c - self.odr = data_rate - self.slv_addr = address - - # Set configuration register - # Humidity and temperature average configuration - self.bus.writeto_mem(self.slv_addr, 0x10, b"\x1B") - - # Set control register - # PD | BDU | ODR - cfg = 0x80 | 0x04 | (self.odr & 0x3) - self.bus.writeto_mem(self.slv_addr, 0x20, bytes([cfg])) - - # Read Calibration values from non-volatile memory of the device - # Humidity Calibration values - self.H0 = self._read_reg(0x30, 1) / 2 - self.H1 = self._read_reg(0x31, 1) / 2 - self.H2 = self._read_reg(0x36, 2) - self.H3 = self._read_reg(0x3A, 2) - - # Temperature Calibration values - raw = self._read_reg(0x35, 1) - self.T0 = ((raw & 0x03) * 256) + self._read_reg(0x32, 1) - self.T1 = ((raw & 0x0C) * 64) + self._read_reg(0x33, 1) - self.T2 = self._read_reg(0x3C, 2) - self.T3 = self._read_reg(0x3E, 2) - - def _read_reg(self, reg_addr, size): - fmt = "B" if size == 1 else "H" - reg_addr = reg_addr if size == 1 else reg_addr | 0x80 - return struct.unpack(fmt, self.bus.readfrom_mem(self.slv_addr, reg_addr, size))[0] - - def humidity(self): - rH = self._read_reg(0x28, 2) - return (self.H1 - self.H0) * (rH - self.H2) / (self.H3 - self.H2) + self.H0 - - def temperature(self): - temp = self._read_reg(0x2A, 2) - if temp > 32767: - temp -= 65536 - return ((self.T1 - self.T0) / 8.0) * (temp - self.T2) / (self.T3 - self.T2) + ( - self.T0 / 8.0 - ) diff --git a/drivers/hts221/manifest.py b/drivers/hts221/manifest.py deleted file mode 100644 index 5f1792665943..000000000000 --- a/drivers/hts221/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("hts221.py", opt=3) diff --git a/drivers/lps22h/lps22h.py b/drivers/lps22h/lps22h.py deleted file mode 100644 index ca29efce2d6f..000000000000 --- a/drivers/lps22h/lps22h.py +++ /dev/null @@ -1,109 +0,0 @@ -""" -The MIT License (MIT) - -Copyright (c) 2016-2019 shaoziyang -Copyright (c) 2022 Ibrahim Abdelkader - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -LPS22HB/HH pressure sensor driver for MicroPython. - -Example usage: - -import time -from lps22h import LPS22H -from machine import Pin, I2C - -bus = I2C(1, scl=Pin(15), sda=Pin(14)) -lps = LPS22H(bus, oneshot=False) - -while (True): - print("Pressure: %.2f hPa Temperature: %.2f C"%(lps.pressure(), lps.temperature())) - time.sleep_ms(10) -""" -import machine - -_LPS22_CTRL_REG1 = const(0x10) -_LPS22_CTRL_REG2 = const(0x11) -_LPS22_STATUS = const(0x27) -_LPS22_TEMP_OUT_L = const(0x2B) -_LPS22_PRESS_OUT_XL = const(0x28) -_LPS22_PRESS_OUT_L = const(0x29) - - -class LPS22H: - def __init__(self, i2c, address=0x5C, oneshot=False): - self.i2c = i2c - self.addr = address - self.oneshot = oneshot - self.buf = bytearray(1) - # ODR=1 EN_LPFP=1 BDU=1 - self._write_reg(_LPS22_CTRL_REG1, 0x1A) - self.set_oneshot_mode(self.oneshot) - - def _int16(self, d): - return d if d < 0x8000 else d - 0x10000 - - def _write_reg(self, reg, dat): - self.buf[0] = dat - self.i2c.writeto_mem(self.addr, reg, self.buf) - - def _read_reg(self, reg, width=8): - self.i2c.readfrom_mem_into(self.addr, reg, self.buf) - val = self.buf[0] - if width == 16: - val |= self._read_reg(reg + 1) << 8 - return val - - def _tigger_oneshot(self, b): - if self.oneshot: - self._write_reg(_LPS22_CTRL_REG2, self._read_reg(_LPS22_CTRL_REG2) | 0x01) - self._read_reg(0x28 + b * 2) - while True: - if self._read_reg(_LPS22_STATUS) & b: - return - machine.idle() - - def set_oneshot_mode(self, oneshot): - self._read_reg(_LPS22_CTRL_REG1) - self.oneshot = oneshot - if oneshot: - self.buf[0] &= 0x0F - else: - self.buf[0] |= 0x10 - self._write_reg(_LPS22_CTRL_REG1, self.buf[0]) - - def pressure(self): - if self.oneshot: - self._tigger_oneshot(1) - return ( - self._read_reg(_LPS22_PRESS_OUT_XL) + self._read_reg(_LPS22_PRESS_OUT_L, 16) * 256 - ) / 4096 - - def temperature(self): - if self.oneshot: - self._tigger_oneshot(2) - return self._int16(self._read_reg(_LPS22_TEMP_OUT_L, 16)) / 100 - - def altitude(self): - return ( - (((1013.25 / self.pressure()) ** (1 / 5.257)) - 1.0) - * (self.temperature() + 273.15) - / 0.0065 - ) diff --git a/drivers/lps22h/manifest.py b/drivers/lps22h/manifest.py deleted file mode 100644 index d30108d93dce..000000000000 --- a/drivers/lps22h/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("lps22h.py", opt=3) diff --git a/drivers/lsm6dsox/lsm6dsox.py b/drivers/lsm6dsox/lsm6dsox.py deleted file mode 100644 index 98e19fa4ca7b..000000000000 --- a/drivers/lsm6dsox/lsm6dsox.py +++ /dev/null @@ -1,271 +0,0 @@ -""" -LSM6DSOX STMicro driver for MicroPython based on LSM9DS1: -Source repo: https://github.com/hoihu/projects/tree/master/raspi-hat - -The MIT License (MIT) - -Copyright (c) 2021 Damien P. George -Copyright (c) 2021-2022 Ibrahim Abdelkader - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -Basic example usage: - -import time -from lsm6dsox import LSM6DSOX - -from machine import Pin, SPI, I2C -# Init in I2C mode. -lsm = LSM6DSOX(I2C(0, scl=Pin(13), sda=Pin(12))) - -# Or init in SPI mode. -#lsm = LSM6DSOX(SPI(5), cs_pin=Pin(10)) - -while (True): - print('Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_accel())) - print('Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_gyro())) - print("") - time.sleep_ms(100) -""" - -import array -from micropython import const - - -class LSM6DSOX: - _CTRL3_C = const(0x12) - _CTRL1_XL = const(0x10) - _CTRL8_XL = const(0x17) - _CTRL9_XL = const(0x18) - - _CTRL2_G = const(0x11) - _CTRL7_G = const(0x16) - - _OUTX_L_G = const(0x22) - _OUTX_L_XL = const(0x28) - _MLC_STATUS = const(0x38) - - _DEFAULT_ADDR = const(0x6A) - _WHO_AM_I_REG = const(0x0F) - - _FUNC_CFG_ACCESS = const(0x01) - _FUNC_CFG_BANK_USER = const(0) - _FUNC_CFG_BANK_HUB = const(1) - _FUNC_CFG_BANK_EMBED = const(2) - - _MLC0_SRC = const(0x70) - _MLC_INT1 = const(0x0D) - _TAP_CFG0 = const(0x56) - - _EMB_FUNC_EN_A = const(0x04) - _EMB_FUNC_EN_B = const(0x05) - - def __init__( - self, - bus, - cs_pin=None, - address=_DEFAULT_ADDR, - gyro_odr=104, - accel_odr=104, - gyro_scale=2000, - accel_scale=4, - ucf=None, - ): - """Initalizes Gyro and Accelerator. - accel_odr: (0, 1.6Hz, 3.33Hz, 6.66Hz, 12.5Hz, 26Hz, 52Hz, 104Hz, 208Hz, 416Hz, 888Hz) - gyro_odr: (0, 1.6Hz, 3.33Hz, 6.66Hz, 12.5Hz, 26Hz, 52Hz, 104Hz, 208Hz, 416Hz, 888Hz) - gyro_scale: (245dps, 500dps, 1000dps, 2000dps) - accel_scale: (+/-2g, +/-4g, +/-8g, +-16g) - ucf: MLC program to load. - """ - self.bus = bus - self.cs_pin = cs_pin - self.address = address - self._use_i2c = hasattr(self.bus, "readfrom_mem") - - if not self._use_i2c and cs_pin is None: - raise ValueError("A CS pin must be provided in SPI mode") - - # check the id of the Accelerometer/Gyro - if self.__read_reg(_WHO_AM_I_REG) != 108: - raise OSError("No LSM6DS device was found at address 0x%x" % (self.address)) - - # allocate scratch buffer for efficient conversions and memread op's - self.scratch_int = array.array("h", [0, 0, 0]) - - SCALE_GYRO = {250: 0, 500: 1, 1000: 2, 2000: 3} - SCALE_ACCEL = {2: 0, 4: 2, 8: 3, 16: 1} - # XL_HM_MODE = 0 by default. G_HM_MODE = 0 by default. - ODR = { - 0: 0x00, - 1.6: 0x08, - 3.33: 0x09, - 6.66: 0x0A, - 12.5: 0x01, - 26: 0x02, - 52: 0x03, - 104: 0x04, - 208: 0x05, - 416: 0x06, - 888: 0x07, - } - - gyro_odr = round(gyro_odr, 2) - accel_odr = round(accel_odr, 2) - - # Sanity checks - if not gyro_odr in ODR: - raise ValueError("Invalid sampling rate: %d" % accel_odr) - if not gyro_scale in SCALE_GYRO: - raise ValueError("invalid gyro scaling: %d" % gyro_scale) - if not accel_odr in ODR: - raise ValueError("Invalid sampling rate: %d" % accel_odr) - if not accel_scale in SCALE_ACCEL: - raise ValueError("invalid accelerometer scaling: %d" % accel_scale) - - # Soft-reset the device. - self.reset() - - # Load and configure MLC if UCF file is provided - if ucf != None: - self.load_mlc(ucf) - - # Set Gyroscope datarate and scale. - # Note output from LPF2 second filtering stage is selected. See Figure 18. - self.__write_reg(_CTRL1_XL, (ODR[accel_odr] << 4) | (SCALE_ACCEL[accel_scale] << 2) | 2) - - # Enable LPF2 and HPF fast-settling mode, ODR/4 - self.__write_reg(_CTRL8_XL, 0x09) - - # Set Gyroscope datarate and scale. - self.__write_reg(_CTRL2_G, (ODR[gyro_odr] << 4) | (SCALE_GYRO[gyro_scale] << 2) | 0) - - self.gyro_scale = 32768 / gyro_scale - self.accel_scale = 32768 / accel_scale - - def __read_reg(self, reg, size=1): - if self._use_i2c: - buf = self.bus.readfrom_mem(self.address, reg, size) - else: - try: - self.cs_pin(0) - self.bus.write(bytes([reg | 0x80])) - buf = self.bus.read(size) - finally: - self.cs_pin(1) - if size == 1: - return int(buf[0]) - return [int(x) for x in buf] - - def __write_reg(self, reg, val): - if self._use_i2c: - self.bus.writeto_mem(self.address, reg, bytes([val])) - else: - try: - self.cs_pin(0) - self.bus.write(bytes([reg, val])) - finally: - self.cs_pin(1) - - def __read_reg_into(self, reg, buf): - if self._use_i2c: - self.bus.readfrom_mem_into(self.address, reg, buf) - else: - try: - self.cs_pin(0) - self.bus.write(bytes([reg | 0x80])) - self.bus.readinto(buf) - finally: - self.cs_pin(1) - - def reset(self): - self.__write_reg(_CTRL3_C, self.__read_reg(_CTRL3_C) | 0x1) - for i in range(0, 10): - if (self.__read_reg(_CTRL3_C) & 0x01) == 0: - return - time.sleep_ms(10) - raise OSError("Failed to reset LSM6DS device.") - - def set_mem_bank(self, bank): - cfg = self.__read_reg(_FUNC_CFG_ACCESS) & 0x3F - self.__write_reg(_FUNC_CFG_ACCESS, cfg | (bank << 6)) - - def set_embedded_functions(self, enable, emb_ab=None): - self.set_mem_bank(_FUNC_CFG_BANK_EMBED) - if enable: - self.__write_reg(_EMB_FUNC_EN_A, emb_ab[0]) - self.__write_reg(_EMB_FUNC_EN_B, emb_ab[1]) - else: - emb_a = self.__read_reg(_EMB_FUNC_EN_A) - emb_b = self.__read_reg(_EMB_FUNC_EN_B) - self.__write_reg(_EMB_FUNC_EN_A, (emb_a & 0xC7)) - self.__write_reg(_EMB_FUNC_EN_B, (emb_b & 0xE6)) - emb_ab = (emb_a, emb_b) - - self.set_mem_bank(_FUNC_CFG_BANK_USER) - return emb_ab - - def load_mlc(self, ucf): - # Load MLC config from file - with open(ucf, "r") as ucf_file: - for l in ucf_file: - if l.startswith("Ac"): - v = [int(v, 16) for v in l.strip().split(" ")[1:3]] - self.__write_reg(v[0], v[1]) - - emb_ab = self.set_embedded_functions(False) - - # Disable I3C interface - self.__write_reg(_CTRL9_XL, self.__read_reg(_CTRL9_XL) | 0x01) - - # Enable Block Data Update - self.__write_reg(_CTRL3_C, self.__read_reg(_CTRL3_C) | 0x40) - - # Route signals on interrupt pin 1 - self.set_mem_bank(_FUNC_CFG_BANK_EMBED) - self.__write_reg(_MLC_INT1, self.__read_reg(_MLC_INT1) & 0x01) - self.set_mem_bank(_FUNC_CFG_BANK_USER) - - # Configure interrupt pin mode - self.__write_reg(_TAP_CFG0, self.__read_reg(_TAP_CFG0) | 0x41) - - self.set_embedded_functions(True, emb_ab) - - def read_mlc_output(self): - buf = None - if self.__read_reg(_MLC_STATUS) & 0x1: - self.__read_reg(0x1A, size=12) - self.set_mem_bank(_FUNC_CFG_BANK_EMBED) - buf = self.__read_reg(_MLC0_SRC, 8) - self.set_mem_bank(_FUNC_CFG_BANK_USER) - return buf - - def read_gyro(self): - """Returns gyroscope vector in degrees/sec.""" - mv = memoryview(self.scratch_int) - f = self.gyro_scale - self.__read_reg_into(_OUTX_L_G, mv) - return (mv[0] / f, mv[1] / f, mv[2] / f) - - def read_accel(self): - """Returns acceleration vector in gravity units (9.81m/s^2).""" - mv = memoryview(self.scratch_int) - f = self.accel_scale - self.__read_reg_into(_OUTX_L_XL, mv) - return (mv[0] / f, mv[1] / f, mv[2] / f) diff --git a/drivers/lsm6dsox/lsm6dsox_basic.py b/drivers/lsm6dsox/lsm6dsox_basic.py deleted file mode 100644 index 0ffe9e92b768..000000000000 --- a/drivers/lsm6dsox/lsm6dsox_basic.py +++ /dev/null @@ -1,15 +0,0 @@ -# LSM6DSOX Basic Example. -import time -from lsm6dsox import LSM6DSOX - -from machine import Pin, I2C - -lsm = LSM6DSOX(I2C(0, scl=Pin(13), sda=Pin(12))) -# Or init in SPI mode. -# lsm = LSM6DSOX(SPI(5), cs_pin=Pin(10)) - -while True: - print("Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}".format(*lsm.read_accel())) - print("Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}".format(*lsm.read_gyro())) - print("") - time.sleep_ms(100) diff --git a/drivers/lsm6dsox/lsm6dsox_mlc.py b/drivers/lsm6dsox/lsm6dsox_mlc.py deleted file mode 100644 index 866498d0ce13..000000000000 --- a/drivers/lsm6dsox/lsm6dsox_mlc.py +++ /dev/null @@ -1,48 +0,0 @@ -# LSM6DSOX IMU MLC (Machine Learning Core) Example. -# Download the raw UCF file, copy to storage and reset. - -# NOTE: The pre-trained models (UCF files) for the examples can be found here: -# https://github.com/STMicroelectronics/STMems_Machine_Learning_Core/tree/master/application_examples/lsm6dsox - -import time -from lsm6dsox import LSM6DSOX -from machine import Pin, I2C - -INT_MODE = True # Run in interrupt mode. -INT_FLAG = False # Set True on interrupt. - - -def imu_int_handler(pin): - global INT_FLAG - INT_FLAG = True - - -if INT_MODE == True: - int_pin = Pin(24) - int_pin.irq(handler=imu_int_handler, trigger=Pin.IRQ_RISING) - -i2c = I2C(0, scl=Pin(13), sda=Pin(12)) - -# Vibration detection example -UCF_FILE = "lsm6dsox_vibration_monitoring.ucf" -UCF_LABELS = {0: "no vibration", 1: "low vibration", 2: "high vibration"} -# NOTE: Selected data rate and scale must match the MLC data rate and scale. -lsm = LSM6DSOX(i2c, gyro_odr=26, accel_odr=26, gyro_scale=2000, accel_scale=4, ucf=UCF_FILE) - -# Head gestures example -# UCF_FILE = "lsm6dsox_head_gestures.ucf" -# UCF_LABELS = {0:"Nod", 1:"Shake", 2:"Stationary", 3:"Swing", 4:"Walk"} -# NOTE: Selected data rate and scale must match the MLC data rate and scale. -# lsm = LSM6DSOX(i2c, gyro_odr=26, accel_odr=26, gyro_scale=250, accel_scale=2, ucf=UCF_FILE) - -print("MLC configured...") - -while True: - if INT_MODE: - if INT_FLAG: - INT_FLAG = False - print(UCF_LABELS[lsm.read_mlc_output()[0]]) - else: - buf = lsm.read_mlc_output() - if buf != None: - print(UCF_LABELS[buf[0]]) diff --git a/drivers/lsm6dsox/manifest.py b/drivers/lsm6dsox/manifest.py deleted file mode 100644 index 28f4b3565e9f..000000000000 --- a/drivers/lsm6dsox/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("lsm6dsox.py", opt=3) diff --git a/drivers/lsm9ds1/lsm9ds1.py b/drivers/lsm9ds1/lsm9ds1.py deleted file mode 100644 index 5d9942a7b346..000000000000 --- a/drivers/lsm9ds1/lsm9ds1.py +++ /dev/null @@ -1,189 +0,0 @@ -""" -The MIT License (MIT) - -Copyright (c) 2013, 2014 Damien P. George - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -LSM9DS1 - 9DOF inertial sensor of STMicro driver for MicroPython. -The sensor contains an accelerometer / gyroscope / magnetometer -Uses the internal FIFO to store up to 16 gyro/accel data, use the iter_accel_gyro generator to access it. - -Example usage: - -import time -from lsm9ds1 import LSM9DS1 -from machine import Pin, I2C - -lsm = LSM9DS1(I2C(1, scl=Pin(15), sda=Pin(14))) - -while (True): - #for g,a in lsm.iter_accel_gyro(): print(g,a) # using fifo - print('Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.accel())) - print('Magnetometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.magnet())) - print('Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.gyro())) - print("") - time.sleep_ms(100) -""" -import array - - -_WHO_AM_I = const(0xF) -_CTRL_REG1_G = const(0x10) -_INT_GEN_SRC_G = const(0x14) -_OUT_TEMP = const(0x15) -_OUT_G = const(0x18) -_CTRL_REG4_G = const(0x1E) -_STATUS_REG = const(0x27) -_OUT_XL = const(0x28) -_FIFO_CTRL_REG = const(0x2E) -_FIFO_SRC = const(0x2F) -_OFFSET_REG_X_M = const(0x05) -_CTRL_REG1_M = const(0x20) -_OUT_M = const(0x28) -_SCALE_GYRO = const(((245, 0), (500, 1), (2000, 3))) -_SCALE_ACCEL = const(((2, 0), (4, 2), (8, 3), (16, 1))) - - -class LSM9DS1: - def __init__(self, i2c, address_gyro=0x6B, address_magnet=0x1E): - self.i2c = i2c - self.address_gyro = address_gyro - self.address_magnet = address_magnet - # check id's of accelerometer/gyro and magnetometer - if (self.magent_id() != b"=") or (self.gyro_id() != b"h"): - raise OSError( - "Invalid LSM9DS1 device, using address {}/{}".format(address_gyro, address_magnet) - ) - # allocate scratch buffer for efficient conversions and memread op's - self.scratch = array.array("B", [0, 0, 0, 0, 0, 0]) - self.scratch_int = array.array("h", [0, 0, 0]) - self.init_gyro_accel() - self.init_magnetometer() - - def init_gyro_accel(self, sample_rate=6, scale_gyro=0, scale_accel=0): - """Initalizes Gyro and Accelerator. - sample rate: 0-6 (off, 14.9Hz, 59.5Hz, 119Hz, 238Hz, 476Hz, 952Hz) - scale_gyro: 0-2 (245dps, 500dps, 2000dps ) - scale_accel: 0-3 (+/-2g, +/-4g, +/-8g, +-16g) - """ - assert sample_rate <= 6, "invalid sampling rate: %d" % sample_rate - assert scale_gyro <= 2, "invalid gyro scaling: %d" % scale_gyro - assert scale_accel <= 3, "invalid accelerometer scaling: %d" % scale_accel - - i2c = self.i2c - addr = self.address_gyro - mv = memoryview(self.scratch) - # angular control registers 1-3 / Orientation - mv[0] = ((sample_rate & 0x07) << 5) | ((_SCALE_GYRO[scale_gyro][1] & 0x3) << 3) - mv[1:4] = b"\x00\x00\x00" - i2c.writeto_mem(addr, _CTRL_REG1_G, mv[:5]) - # ctrl4 - enable x,y,z, outputs, no irq latching, no 4D - # ctrl5 - enable all axes, no decimation - # ctrl6 - set scaling and sample rate of accel - # ctrl7,8 - leave at default values - # ctrl9 - FIFO enabled - mv[0] = mv[1] = 0x38 - mv[2] = ((sample_rate & 7) << 5) | ((_SCALE_ACCEL[scale_accel][1] & 0x3) << 3) - mv[3] = 0x00 - mv[4] = 0x4 - mv[5] = 0x2 - i2c.writeto_mem(addr, _CTRL_REG4_G, mv[:6]) - - # fifo: use continous mode (overwrite old data if overflow) - i2c.writeto_mem(addr, _FIFO_CTRL_REG, b"\x00") - i2c.writeto_mem(addr, _FIFO_CTRL_REG, b"\xc0") - - self.scale_gyro = 32768 / _SCALE_GYRO[scale_gyro][0] - self.scale_accel = 32768 / _SCALE_ACCEL[scale_accel][0] - - def init_magnetometer(self, sample_rate=7, scale_magnet=0): - """ - sample rates = 0-7 (0.625, 1.25, 2.5, 5, 10, 20, 40, 80Hz) - scaling = 0-3 (+/-4, +/-8, +/-12, +/-16 Gauss) - """ - assert sample_rate < 8, "invalid sample rate: %d (0-7)" % sample_rate - assert scale_magnet < 4, "invalid scaling: %d (0-3)" % scale_magnet - i2c = self.i2c - addr = self.address_magnet - mv = memoryview(self.scratch) - mv[0] = 0x40 | (sample_rate << 2) # ctrl1: high performance mode - mv[1] = scale_magnet << 5 # ctrl2: scale, normal mode, no reset - mv[2] = 0x00 # ctrl3: continous conversion, no low power, I2C - mv[3] = 0x08 # ctrl4: high performance z-axis - mv[4] = 0x00 # ctr5: no fast read, no block update - i2c.writeto_mem(addr, _CTRL_REG1_M, mv[:5]) - self.scale_factor_magnet = 32768 / ((scale_magnet + 1) * 4) - - def calibrate_magnet(self, offset): - """ - offset is a magnet vecor that will be substracted by the magnetometer - for each measurement. It is written to the magnetometer's offset register - """ - offset = [int(i * self.scale_factor_magnet) for i in offset] - mv = memoryview(self.scratch) - mv[0] = offset[0] & 0xFF - mv[1] = offset[0] >> 8 - mv[2] = offset[1] & 0xFF - mv[3] = offset[1] >> 8 - mv[4] = offset[2] & 0xFF - mv[5] = offset[2] >> 8 - self.i2c.writeto_mem(self.address_magnet, _OFFSET_REG_X_M, mv[:6]) - - def gyro_id(self): - return self.i2c.readfrom_mem(self.address_gyro, _WHO_AM_I, 1) - - def magent_id(self): - return self.i2c.readfrom_mem(self.address_magnet, _WHO_AM_I, 1) - - def magnet(self): - """Returns magnetometer vector in gauss. - raw_values: if True, the non-scaled adc values are returned - """ - mv = memoryview(self.scratch_int) - f = self.scale_factor_magnet - self.i2c.readfrom_mem_into(self.address_magnet, _OUT_M | 0x80, mv) - return (mv[0] / f, mv[1] / f, mv[2] / f) - - def gyro(self): - """Returns gyroscope vector in degrees/sec.""" - mv = memoryview(self.scratch_int) - f = self.scale_gyro - self.i2c.readfrom_mem_into(self.address_gyro, _OUT_G | 0x80, mv) - return (mv[0] / f, mv[1] / f, mv[2] / f) - - def accel(self): - """Returns acceleration vector in gravity units (9.81m/s^2).""" - mv = memoryview(self.scratch_int) - f = self.scale_accel - self.i2c.readfrom_mem_into(self.address_gyro, _OUT_XL | 0x80, mv) - return (mv[0] / f, mv[1] / f, mv[2] / f) - - def iter_accel_gyro(self): - """A generator that returns tuples of (gyro,accelerometer) data from the fifo.""" - while True: - fifo_state = int.from_bytes( - self.i2c.readfrom_mem(self.address_gyro, _FIFO_SRC, 1), "big" - ) - if fifo_state & 0x3F: - # print("Available samples=%d" % (fifo_state & 0x1f)) - yield self.gyro(), self.accel() - else: - break diff --git a/drivers/lsm9ds1/manifest.py b/drivers/lsm9ds1/manifest.py deleted file mode 100644 index 6779362de7ee..000000000000 --- a/drivers/lsm9ds1/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("lsm9ds1.py", opt=3) diff --git a/drivers/neopixel/manifest.py b/drivers/neopixel/manifest.py deleted file mode 100644 index 561d19574af3..000000000000 --- a/drivers/neopixel/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("neopixel.py", opt=3) diff --git a/drivers/neopixel/neopixel.py b/drivers/neopixel/neopixel.py deleted file mode 100644 index caa12dc84536..000000000000 --- a/drivers/neopixel/neopixel.py +++ /dev/null @@ -1,50 +0,0 @@ -# NeoPixel driver for MicroPython -# MIT license; Copyright (c) 2016 Damien P. George, 2021 Jim Mussared - -from machine import bitstream - - -class NeoPixel: - # G R B W - ORDER = (1, 0, 2, 3) - - def __init__(self, pin, n, bpp=3, timing=1): - self.pin = pin - self.n = n - self.bpp = bpp - self.buf = bytearray(n * bpp) - self.pin.init(pin.OUT) - # Timing arg can either be 1 for 800kHz or 0 for 400kHz, - # or a user-specified timing ns tuple (high_0, low_0, high_1, low_1). - self.timing = ( - ((400, 850, 800, 450) if timing else (800, 1700, 1600, 900)) - if isinstance(timing, int) - else timing - ) - - def __len__(self): - return self.n - - def __setitem__(self, i, v): - offset = i * self.bpp - for i in range(self.bpp): - self.buf[offset + self.ORDER[i]] = v[i] - - def __getitem__(self, i): - offset = i * self.bpp - return tuple(self.buf[offset + self.ORDER[i]] for i in range(self.bpp)) - - def fill(self, v): - b = self.buf - l = len(self.buf) - bpp = self.bpp - for i in range(bpp): - c = v[i] - j = self.ORDER[i] - while j < l: - b[j] = c - j += bpp - - def write(self): - # BITSTREAM_TYPE_HIGH_LOW = 0 - bitstream(self.pin, 0, self.timing, self.buf) diff --git a/drivers/nrf24l01/manifest.py b/drivers/nrf24l01/manifest.py deleted file mode 100644 index babdb7a52a95..000000000000 --- a/drivers/nrf24l01/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("nrf24l01.py", opt=3) diff --git a/drivers/nrf24l01/nrf24l01.py b/drivers/nrf24l01/nrf24l01.py deleted file mode 100644 index 76d55312f856..000000000000 --- a/drivers/nrf24l01/nrf24l01.py +++ /dev/null @@ -1,252 +0,0 @@ -"""NRF24L01 driver for MicroPython -""" - -from micropython import const -import utime - -# nRF24L01+ registers -CONFIG = const(0x00) -EN_RXADDR = const(0x02) -SETUP_AW = const(0x03) -SETUP_RETR = const(0x04) -RF_CH = const(0x05) -RF_SETUP = const(0x06) -STATUS = const(0x07) -RX_ADDR_P0 = const(0x0A) -TX_ADDR = const(0x10) -RX_PW_P0 = const(0x11) -FIFO_STATUS = const(0x17) -DYNPD = const(0x1C) - -# CONFIG register -EN_CRC = const(0x08) # enable CRC -CRCO = const(0x04) # CRC encoding scheme; 0=1 byte, 1=2 bytes -PWR_UP = const(0x02) # 1=power up, 0=power down -PRIM_RX = const(0x01) # RX/TX control; 0=PTX, 1=PRX - -# RF_SETUP register -POWER_0 = const(0x00) # -18 dBm -POWER_1 = const(0x02) # -12 dBm -POWER_2 = const(0x04) # -6 dBm -POWER_3 = const(0x06) # 0 dBm -SPEED_1M = const(0x00) -SPEED_2M = const(0x08) -SPEED_250K = const(0x20) - -# STATUS register -RX_DR = const(0x40) # RX data ready; write 1 to clear -TX_DS = const(0x20) # TX data sent; write 1 to clear -MAX_RT = const(0x10) # max retransmits reached; write 1 to clear - -# FIFO_STATUS register -RX_EMPTY = const(0x01) # 1 if RX FIFO is empty - -# constants for instructions -R_RX_PL_WID = const(0x60) # read RX payload width -R_RX_PAYLOAD = const(0x61) # read RX payload -W_TX_PAYLOAD = const(0xA0) # write TX payload -FLUSH_TX = const(0xE1) # flush TX FIFO -FLUSH_RX = const(0xE2) # flush RX FIFO -NOP = const(0xFF) # use to read STATUS register - - -class NRF24L01: - def __init__(self, spi, cs, ce, channel=46, payload_size=16): - assert payload_size <= 32 - - self.buf = bytearray(1) - - # store the pins - self.spi = spi - self.cs = cs - self.ce = ce - - # init the SPI bus and pins - self.init_spi(4000000) - - # reset everything - ce.init(ce.OUT, value=0) - cs.init(cs.OUT, value=1) - - self.payload_size = payload_size - self.pipe0_read_addr = None - utime.sleep_ms(5) - - # set address width to 5 bytes and check for device present - self.reg_write(SETUP_AW, 0b11) - if self.reg_read(SETUP_AW) != 0b11: - raise OSError("nRF24L01+ Hardware not responding") - - # disable dynamic payloads - self.reg_write(DYNPD, 0) - - # auto retransmit delay: 1750us - # auto retransmit count: 8 - self.reg_write(SETUP_RETR, (6 << 4) | 8) - - # set rf power and speed - self.set_power_speed(POWER_3, SPEED_250K) # Best for point to point links - - # init CRC - self.set_crc(2) - - # clear status flags - self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) - - # set channel - self.set_channel(channel) - - # flush buffers - self.flush_rx() - self.flush_tx() - - def init_spi(self, baudrate): - try: - master = self.spi.MASTER - except AttributeError: - self.spi.init(baudrate=baudrate, polarity=0, phase=0) - else: - self.spi.init(master, baudrate=baudrate, polarity=0, phase=0) - - def reg_read(self, reg): - self.cs(0) - self.spi.readinto(self.buf, reg) - self.spi.readinto(self.buf) - self.cs(1) - return self.buf[0] - - def reg_write_bytes(self, reg, buf): - self.cs(0) - self.spi.readinto(self.buf, 0x20 | reg) - self.spi.write(buf) - self.cs(1) - return self.buf[0] - - def reg_write(self, reg, value): - self.cs(0) - self.spi.readinto(self.buf, 0x20 | reg) - ret = self.buf[0] - self.spi.readinto(self.buf, value) - self.cs(1) - return ret - - def flush_rx(self): - self.cs(0) - self.spi.readinto(self.buf, FLUSH_RX) - self.cs(1) - - def flush_tx(self): - self.cs(0) - self.spi.readinto(self.buf, FLUSH_TX) - self.cs(1) - - # power is one of POWER_x defines; speed is one of SPEED_x defines - def set_power_speed(self, power, speed): - setup = self.reg_read(RF_SETUP) & 0b11010001 - self.reg_write(RF_SETUP, setup | power | speed) - - # length in bytes: 0, 1 or 2 - def set_crc(self, length): - config = self.reg_read(CONFIG) & ~(CRCO | EN_CRC) - if length == 0: - pass - elif length == 1: - config |= EN_CRC - else: - config |= EN_CRC | CRCO - self.reg_write(CONFIG, config) - - def set_channel(self, channel): - self.reg_write(RF_CH, min(channel, 125)) - - # address should be a bytes object 5 bytes long - def open_tx_pipe(self, address): - assert len(address) == 5 - self.reg_write_bytes(RX_ADDR_P0, address) - self.reg_write_bytes(TX_ADDR, address) - self.reg_write(RX_PW_P0, self.payload_size) - - # address should be a bytes object 5 bytes long - # pipe 0 and 1 have 5 byte address - # pipes 2-5 use same 4 most-significant bytes as pipe 1, plus 1 extra byte - def open_rx_pipe(self, pipe_id, address): - assert len(address) == 5 - assert 0 <= pipe_id <= 5 - if pipe_id == 0: - self.pipe0_read_addr = address - if pipe_id < 2: - self.reg_write_bytes(RX_ADDR_P0 + pipe_id, address) - else: - self.reg_write(RX_ADDR_P0 + pipe_id, address[0]) - self.reg_write(RX_PW_P0 + pipe_id, self.payload_size) - self.reg_write(EN_RXADDR, self.reg_read(EN_RXADDR) | (1 << pipe_id)) - - def start_listening(self): - self.reg_write(CONFIG, self.reg_read(CONFIG) | PWR_UP | PRIM_RX) - self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) - - if self.pipe0_read_addr is not None: - self.reg_write_bytes(RX_ADDR_P0, self.pipe0_read_addr) - - self.flush_rx() - self.flush_tx() - self.ce(1) - utime.sleep_us(130) - - def stop_listening(self): - self.ce(0) - self.flush_tx() - self.flush_rx() - - # returns True if any data available to recv - def any(self): - return not bool(self.reg_read(FIFO_STATUS) & RX_EMPTY) - - def recv(self): - # get the data - self.cs(0) - self.spi.readinto(self.buf, R_RX_PAYLOAD) - buf = self.spi.read(self.payload_size) - self.cs(1) - # clear RX ready flag - self.reg_write(STATUS, RX_DR) - - return buf - - # blocking wait for tx complete - def send(self, buf, timeout=500): - self.send_start(buf) - start = utime.ticks_ms() - result = None - while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout: - result = self.send_done() # 1 == success, 2 == fail - if result == 2: - raise OSError("send failed") - - # non-blocking tx - def send_start(self, buf): - # power up - self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX) - utime.sleep_us(150) - # send the data - self.cs(0) - self.spi.readinto(self.buf, W_TX_PAYLOAD) - self.spi.write(buf) - if len(buf) < self.payload_size: - self.spi.write(b"\x00" * (self.payload_size - len(buf))) # pad out data - self.cs(1) - - # enable the chip so it can send the data - self.ce(1) - utime.sleep_us(15) # needs to be >10us - self.ce(0) - - # returns None if send still in progress, 1 for success, 2 for fail - def send_done(self): - if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)): - return None # tx not finished - - # either finished or failed: get and clear status flags, power down - status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) - self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP) - return 1 if status & TX_DS else 2 diff --git a/drivers/nrf24l01/nrf24l01test.py b/drivers/nrf24l01/nrf24l01test.py deleted file mode 100644 index 56bdb6e26eb9..000000000000 --- a/drivers/nrf24l01/nrf24l01test.py +++ /dev/null @@ -1,150 +0,0 @@ -"""Test for nrf24l01 module. Portable between MicroPython targets.""" - -import usys -import ustruct as struct -import utime -from machine import Pin, SPI -from nrf24l01 import NRF24L01 -from micropython import const - -# Slave pause between receiving data and checking for further packets. -_RX_POLL_DELAY = const(15) -# Slave pauses an additional _SLAVE_SEND_DELAY ms after receiving data and before -# transmitting to allow the (remote) master time to get into receive mode. The -# master may be a slow device. Value tested with Pyboard, ESP32 and ESP8266. -_SLAVE_SEND_DELAY = const(10) - -if usys.platform == "pyboard": - cfg = {"spi": 2, "miso": "Y7", "mosi": "Y8", "sck": "Y6", "csn": "Y5", "ce": "Y4"} -elif usys.platform == "esp8266": # Hardware SPI - cfg = {"spi": 1, "miso": 12, "mosi": 13, "sck": 14, "csn": 4, "ce": 5} -elif usys.platform == "esp32": # Software SPI - cfg = {"spi": -1, "miso": 32, "mosi": 33, "sck": 25, "csn": 26, "ce": 27} -else: - raise ValueError("Unsupported platform {}".format(usys.platform)) - -# Addresses are in little-endian format. They correspond to big-endian -# 0xf0f0f0f0e1, 0xf0f0f0f0d2 -pipes = (b"\xe1\xf0\xf0\xf0\xf0", b"\xd2\xf0\xf0\xf0\xf0") - - -def master(): - csn = Pin(cfg["csn"], mode=Pin.OUT, value=1) - ce = Pin(cfg["ce"], mode=Pin.OUT, value=0) - if cfg["spi"] == -1: - spi = SPI(-1, sck=Pin(cfg["sck"]), mosi=Pin(cfg["mosi"]), miso=Pin(cfg["miso"])) - nrf = NRF24L01(spi, csn, ce, payload_size=8) - else: - nrf = NRF24L01(SPI(cfg["spi"]), csn, ce, payload_size=8) - - nrf.open_tx_pipe(pipes[0]) - nrf.open_rx_pipe(1, pipes[1]) - nrf.start_listening() - - num_needed = 16 - num_successes = 0 - num_failures = 0 - led_state = 0 - - print("NRF24L01 master mode, sending %d packets..." % num_needed) - - while num_successes < num_needed and num_failures < num_needed: - # stop listening and send packet - nrf.stop_listening() - millis = utime.ticks_ms() - led_state = max(1, (led_state << 1) & 0x0F) - print("sending:", millis, led_state) - try: - nrf.send(struct.pack("ii", millis, led_state)) - except OSError: - pass - - # start listening again - nrf.start_listening() - - # wait for response, with 250ms timeout - start_time = utime.ticks_ms() - timeout = False - while not nrf.any() and not timeout: - if utime.ticks_diff(utime.ticks_ms(), start_time) > 250: - timeout = True - - if timeout: - print("failed, response timed out") - num_failures += 1 - - else: - # recv packet - (got_millis,) = struct.unpack("i", nrf.recv()) - - # print response and round-trip delay - print( - "got response:", - got_millis, - "(delay", - utime.ticks_diff(utime.ticks_ms(), got_millis), - "ms)", - ) - num_successes += 1 - - # delay then loop - utime.sleep_ms(250) - - print("master finished sending; successes=%d, failures=%d" % (num_successes, num_failures)) - - -def slave(): - csn = Pin(cfg["csn"], mode=Pin.OUT, value=1) - ce = Pin(cfg["ce"], mode=Pin.OUT, value=0) - if cfg["spi"] == -1: - spi = SPI(-1, sck=Pin(cfg["sck"]), mosi=Pin(cfg["mosi"]), miso=Pin(cfg["miso"])) - nrf = NRF24L01(spi, csn, ce, payload_size=8) - else: - nrf = NRF24L01(SPI(cfg["spi"]), csn, ce, payload_size=8) - - nrf.open_tx_pipe(pipes[1]) - nrf.open_rx_pipe(1, pipes[0]) - nrf.start_listening() - - print("NRF24L01 slave mode, waiting for packets... (ctrl-C to stop)") - - while True: - if nrf.any(): - while nrf.any(): - buf = nrf.recv() - millis, led_state = struct.unpack("ii", buf) - print("received:", millis, led_state) - for led in leds: - if led_state & 1: - led.on() - else: - led.off() - led_state >>= 1 - utime.sleep_ms(_RX_POLL_DELAY) - - # Give master time to get into receive mode. - utime.sleep_ms(_SLAVE_SEND_DELAY) - nrf.stop_listening() - try: - nrf.send(struct.pack("i", millis)) - except OSError: - pass - print("sent response") - nrf.start_listening() - - -try: - import pyb - - leds = [pyb.LED(i + 1) for i in range(4)] -except: - leds = [] - -print("NRF24L01 test module loaded") -print("NRF24L01 pinout for test:") -print(" CE on", cfg["ce"]) -print(" CSN on", cfg["csn"]) -print(" SCK on", cfg["sck"]) -print(" MISO on", cfg["miso"]) -print(" MOSI on", cfg["mosi"]) -print("run nrf24l01test.slave() on slave, then nrf24l01test.master() on master") diff --git a/drivers/onewire/ds18x20.py b/drivers/onewire/ds18x20.py deleted file mode 100644 index ad2d9f52cdd0..000000000000 --- a/drivers/onewire/ds18x20.py +++ /dev/null @@ -1,52 +0,0 @@ -# DS18x20 temperature sensor driver for MicroPython. -# MIT license; Copyright (c) 2016 Damien P. George - -from micropython import const - -_CONVERT = const(0x44) -_RD_SCRATCH = const(0xBE) -_WR_SCRATCH = const(0x4E) - - -class DS18X20: - def __init__(self, onewire): - self.ow = onewire - self.buf = bytearray(9) - - def scan(self): - return [rom for rom in self.ow.scan() if rom[0] in (0x10, 0x22, 0x28)] - - def convert_temp(self): - self.ow.reset(True) - self.ow.writebyte(self.ow.SKIP_ROM) - self.ow.writebyte(_CONVERT) - - def read_scratch(self, rom): - self.ow.reset(True) - self.ow.select_rom(rom) - self.ow.writebyte(_RD_SCRATCH) - self.ow.readinto(self.buf) - if self.ow.crc8(self.buf): - raise Exception("CRC error") - return self.buf - - def write_scratch(self, rom, buf): - self.ow.reset(True) - self.ow.select_rom(rom) - self.ow.writebyte(_WR_SCRATCH) - self.ow.write(buf) - - def read_temp(self, rom): - buf = self.read_scratch(rom) - if rom[0] == 0x10: - if buf[1]: - t = buf[0] >> 1 | 0x80 - t = -((~t + 1) & 0xFF) - else: - t = buf[0] >> 1 - return t - 0.25 + (buf[7] - buf[6]) / buf[7] - else: - t = buf[1] << 8 | buf[0] - if t & 0x8000: # sign bit set - t = -((t ^ 0xFFFF) + 1) - return t / 16 diff --git a/drivers/onewire/manifest.py b/drivers/onewire/manifest.py deleted file mode 100644 index f500a65d780b..000000000000 --- a/drivers/onewire/manifest.py +++ /dev/null @@ -1,6 +0,0 @@ -options.defaults(ds18x20=False) - -module("onewire.py", opt=3) - -if options.ds18x20: - module("ds18x20.py", opt=3) diff --git a/drivers/onewire/onewire.py b/drivers/onewire/onewire.py deleted file mode 100644 index 4c6da741c74c..000000000000 --- a/drivers/onewire/onewire.py +++ /dev/null @@ -1,92 +0,0 @@ -# 1-Wire driver for MicroPython -# MIT license; Copyright (c) 2016 Damien P. George - -import _onewire as _ow - - -class OneWireError(Exception): - pass - - -class OneWire: - SEARCH_ROM = 0xF0 - MATCH_ROM = 0x55 - SKIP_ROM = 0xCC - - def __init__(self, pin): - self.pin = pin - self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP) - - def reset(self, required=False): - reset = _ow.reset(self.pin) - if required and not reset: - raise OneWireError - return reset - - def readbit(self): - return _ow.readbit(self.pin) - - def readbyte(self): - return _ow.readbyte(self.pin) - - def readinto(self, buf): - for i in range(len(buf)): - buf[i] = _ow.readbyte(self.pin) - - def writebit(self, value): - return _ow.writebit(self.pin, value) - - def writebyte(self, value): - return _ow.writebyte(self.pin, value) - - def write(self, buf): - for b in buf: - _ow.writebyte(self.pin, b) - - def select_rom(self, rom): - self.reset() - self.writebyte(self.MATCH_ROM) - self.write(rom) - - def scan(self): - devices = [] - diff = 65 - rom = False - for i in range(0xFF): - rom, diff = self._search_rom(rom, diff) - if rom: - devices += [rom] - if diff == 0: - break - return devices - - def _search_rom(self, l_rom, diff): - if not self.reset(): - return None, 0 - self.writebyte(self.SEARCH_ROM) - if not l_rom: - l_rom = bytearray(8) - rom = bytearray(8) - next_diff = 0 - i = 64 - for byte in range(8): - r_b = 0 - for bit in range(8): - b = self.readbit() - if self.readbit(): - if b: # there are no devices or there is an error on the bus - return None, 0 - else: - if not b: # collision, two devices with different bit meaning - if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i): - b = 1 - next_diff = i - self.writebit(b) - if b: - r_b |= 1 << bit - i -= 1 - rom[byte] = r_b - return rom, next_diff - - def crc8(self, data): - return _ow.crc8(data) diff --git a/drivers/sdcard/manifest.py b/drivers/sdcard/manifest.py deleted file mode 100644 index e584b97d9ca6..000000000000 --- a/drivers/sdcard/manifest.py +++ /dev/null @@ -1 +0,0 @@ -module("sdcard.py", opt=3) diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py deleted file mode 100644 index df28bd953448..000000000000 --- a/drivers/sdcard/sdcard.py +++ /dev/null @@ -1,299 +0,0 @@ -""" -MicroPython driver for SD cards using SPI bus. - -Requires an SPI bus and a CS pin. Provides readblocks and writeblocks -methods so the device can be mounted as a filesystem. - -Example usage on pyboard: - - import pyb, sdcard, os - sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X5) - pyb.mount(sd, '/sd2') - os.listdir('/') - -Example usage on ESP8266: - - import machine, sdcard, os - sd = sdcard.SDCard(machine.SPI(1), machine.Pin(15)) - os.mount(sd, '/sd') - os.listdir('/') - -""" - -from micropython import const -import time - - -_CMD_TIMEOUT = const(100) - -_R1_IDLE_STATE = const(1 << 0) -# R1_ERASE_RESET = const(1 << 1) -_R1_ILLEGAL_COMMAND = const(1 << 2) -# R1_COM_CRC_ERROR = const(1 << 3) -# R1_ERASE_SEQUENCE_ERROR = const(1 << 4) -# R1_ADDRESS_ERROR = const(1 << 5) -# R1_PARAMETER_ERROR = const(1 << 6) -_TOKEN_CMD25 = const(0xFC) -_TOKEN_STOP_TRAN = const(0xFD) -_TOKEN_DATA = const(0xFE) - - -class SDCard: - def __init__(self, spi, cs, baudrate=1320000): - self.spi = spi - self.cs = cs - - self.cmdbuf = bytearray(6) - self.dummybuf = bytearray(512) - self.tokenbuf = bytearray(1) - for i in range(512): - self.dummybuf[i] = 0xFF - self.dummybuf_memoryview = memoryview(self.dummybuf) - - # initialise the card - self.init_card(baudrate) - - def init_spi(self, baudrate): - try: - master = self.spi.MASTER - except AttributeError: - # on ESP8266 - self.spi.init(baudrate=baudrate, phase=0, polarity=0) - else: - # on pyboard - self.spi.init(master, baudrate=baudrate, phase=0, polarity=0) - - def init_card(self, baudrate): - - # init CS pin - self.cs.init(self.cs.OUT, value=1) - - # init SPI bus; use low data rate for initialisation - self.init_spi(100000) - - # clock card at least 100 cycles with cs high - for i in range(16): - self.spi.write(b"\xff") - - # CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts) - for _ in range(5): - if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE: - break - else: - raise OSError("no SD card") - - # CMD8: determine card version - r = self.cmd(8, 0x01AA, 0x87, 4) - if r == _R1_IDLE_STATE: - self.init_card_v2() - elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND): - self.init_card_v1() - else: - raise OSError("couldn't determine SD card version") - - # get the number of sectors - # CMD9: response R2 (R1 byte + 16-byte block read) - if self.cmd(9, 0, 0, 0, False) != 0: - raise OSError("no response from SD card") - csd = bytearray(16) - self.readinto(csd) - if csd[0] & 0xC0 == 0x40: # CSD version 2.0 - self.sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024 - elif csd[0] & 0xC0 == 0x00: # CSD version 1.0 (old, <=2GB) - c_size = (csd[6] & 0b11) << 10 | csd[7] << 2 | csd[8] >> 6 - c_size_mult = (csd[9] & 0b11) << 1 | csd[10] >> 7 - read_bl_len = csd[5] & 0b1111 - capacity = (c_size + 1) * (2 ** (c_size_mult + 2)) * (2**read_bl_len) - self.sectors = capacity // 512 - else: - raise OSError("SD card CSD format not supported") - # print('sectors', self.sectors) - - # CMD16: set block length to 512 bytes - if self.cmd(16, 512, 0) != 0: - raise OSError("can't set 512 block size") - - # set to high data rate now that it's initialised - self.init_spi(baudrate) - - def init_card_v1(self): - for i in range(_CMD_TIMEOUT): - time.sleep_ms(50) - self.cmd(55, 0, 0) - if self.cmd(41, 0, 0) == 0: - # SDSC card, uses byte addressing in read/write/erase commands - self.cdv = 512 - # print("[SDCard] v1 card") - return - raise OSError("timeout waiting for v1 card") - - def init_card_v2(self): - for i in range(_CMD_TIMEOUT): - time.sleep_ms(50) - self.cmd(58, 0, 0, 4) - self.cmd(55, 0, 0) - if self.cmd(41, 0x40000000, 0) == 0: - self.cmd(58, 0, 0, -4) # 4-byte response, negative means keep the first byte - ocr = self.tokenbuf[0] # get first byte of response, which is OCR - if not ocr & 0x40: - # SDSC card, uses byte addressing in read/write/erase commands - self.cdv = 512 - else: - # SDHC/SDXC card, uses block addressing in read/write/erase commands - self.cdv = 1 - # print("[SDCard] v2 card") - return - raise OSError("timeout waiting for v2 card") - - def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False): - self.cs(0) - - # create and send the command - buf = self.cmdbuf - buf[0] = 0x40 | cmd - buf[1] = arg >> 24 - buf[2] = arg >> 16 - buf[3] = arg >> 8 - buf[4] = arg - buf[5] = crc - self.spi.write(buf) - - if skip1: - self.spi.readinto(self.tokenbuf, 0xFF) - - # wait for the response (response[7] == 0) - for i in range(_CMD_TIMEOUT): - self.spi.readinto(self.tokenbuf, 0xFF) - response = self.tokenbuf[0] - if not (response & 0x80): - # this could be a big-endian integer that we are getting here - # if final<0 then store the first byte to tokenbuf and discard the rest - if final < 0: - self.spi.readinto(self.tokenbuf, 0xFF) - final = -1 - final - for j in range(final): - self.spi.write(b"\xff") - if release: - self.cs(1) - self.spi.write(b"\xff") - return response - - # timeout - self.cs(1) - self.spi.write(b"\xff") - return -1 - - def readinto(self, buf): - self.cs(0) - - # read until start byte (0xff) - for i in range(_CMD_TIMEOUT): - self.spi.readinto(self.tokenbuf, 0xFF) - if self.tokenbuf[0] == _TOKEN_DATA: - break - time.sleep_ms(1) - else: - self.cs(1) - raise OSError("timeout waiting for response") - - # read data - mv = self.dummybuf_memoryview - if len(buf) != len(mv): - mv = mv[: len(buf)] - self.spi.write_readinto(mv, buf) - - # read checksum - self.spi.write(b"\xff") - self.spi.write(b"\xff") - - self.cs(1) - self.spi.write(b"\xff") - - def write(self, token, buf): - self.cs(0) - - # send: start of block, data, checksum - self.spi.read(1, token) - self.spi.write(buf) - self.spi.write(b"\xff") - self.spi.write(b"\xff") - - # check the response - if (self.spi.read(1, 0xFF)[0] & 0x1F) != 0x05: - self.cs(1) - self.spi.write(b"\xff") - return - - # wait for write to finish - while self.spi.read(1, 0xFF)[0] == 0: - pass - - self.cs(1) - self.spi.write(b"\xff") - - def write_token(self, token): - self.cs(0) - self.spi.read(1, token) - self.spi.write(b"\xff") - # wait for write to finish - while self.spi.read(1, 0xFF)[0] == 0x00: - pass - - self.cs(1) - self.spi.write(b"\xff") - - def readblocks(self, block_num, buf): - nblocks = len(buf) // 512 - assert nblocks and not len(buf) % 512, "Buffer length is invalid" - if nblocks == 1: - # CMD17: set read address for single block - if self.cmd(17, block_num * self.cdv, 0, release=False) != 0: - # release the card - self.cs(1) - raise OSError(5) # EIO - # receive the data and release card - self.readinto(buf) - else: - # CMD18: set read address for multiple blocks - if self.cmd(18, block_num * self.cdv, 0, release=False) != 0: - # release the card - self.cs(1) - raise OSError(5) # EIO - offset = 0 - mv = memoryview(buf) - while nblocks: - # receive the data and release card - self.readinto(mv[offset : offset + 512]) - offset += 512 - nblocks -= 1 - if self.cmd(12, 0, 0xFF, skip1=True): - raise OSError(5) # EIO - - def writeblocks(self, block_num, buf): - nblocks, err = divmod(len(buf), 512) - assert nblocks and not err, "Buffer length is invalid" - if nblocks == 1: - # CMD24: set write address for single block - if self.cmd(24, block_num * self.cdv, 0) != 0: - raise OSError(5) # EIO - - # send the data - self.write(_TOKEN_DATA, buf) - else: - # CMD25: set write address for first block - if self.cmd(25, block_num * self.cdv, 0) != 0: - raise OSError(5) # EIO - # send the data - offset = 0 - mv = memoryview(buf) - while nblocks: - self.write(_TOKEN_CMD25, mv[offset : offset + 512]) - offset += 512 - nblocks -= 1 - self.write_token(_TOKEN_STOP_TRAN) - - def ioctl(self, op, arg): - if op == 4: # get number of blocks - return self.sectors - if op == 5: # get block size in bytes - return 512 diff --git a/drivers/sdcard/sdtest.py b/drivers/sdcard/sdtest.py deleted file mode 100644 index 018ef7c64aa1..000000000000 --- a/drivers/sdcard/sdtest.py +++ /dev/null @@ -1,61 +0,0 @@ -# Test for sdcard block protocol -# Peter hinch 30th Jan 2016 -import os, sdcard, machine - - -def sdtest(): - spi = machine.SPI(1) - spi.init() # Ensure right baudrate - sd = sdcard.SDCard(spi, machine.Pin.board.X21) # Compatible with PCB - vfs = os.VfsFat(sd) - os.mount(vfs, "/fc") - print("Filesystem check") - print(os.listdir("/fc")) - - line = "abcdefghijklmnopqrstuvwxyz\n" - lines = line * 200 # 5400 chars - short = "1234567890\n" - - fn = "/fc/rats.txt" - print() - print("Multiple block read/write") - with open(fn, "w") as f: - n = f.write(lines) - print(n, "bytes written") - n = f.write(short) - print(n, "bytes written") - n = f.write(lines) - print(n, "bytes written") - - with open(fn, "r") as f: - result1 = f.read() - print(len(result1), "bytes read") - - fn = "/fc/rats1.txt" - print() - print("Single block read/write") - with open(fn, "w") as f: - n = f.write(short) # one block - print(n, "bytes written") - - with open(fn, "r") as f: - result2 = f.read() - print(len(result2), "bytes read") - - os.umount("/fc") - - print() - print("Verifying data read back") - success = True - if result1 == "".join((lines, short, lines)): - print("Large file Pass") - else: - print("Large file Fail") - success = False - if result2 == short: - print("Small file Pass") - else: - print("Small file Fail") - success = False - print() - print("Tests", "passed" if success else "failed") diff --git a/extmod/ntptime.py b/extmod/ntptime.py deleted file mode 100644 index 05d7e9717d82..000000000000 --- a/extmod/ntptime.py +++ /dev/null @@ -1,48 +0,0 @@ -import utime - -try: - import usocket as socket -except: - import socket -try: - import ustruct as struct -except: - import struct - -# The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org' -host = "pool.ntp.org" - - -def time(): - NTP_QUERY = bytearray(48) - NTP_QUERY[0] = 0x1B - addr = socket.getaddrinfo(host, 123)[0][-1] - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - try: - s.settimeout(1) - res = s.sendto(NTP_QUERY, addr) - msg = s.recv(48) - finally: - s.close() - val = struct.unpack("!I", msg[40:44])[0] - - EPOCH_YEAR = utime.gmtime(0)[0] - if EPOCH_YEAR == 2000: - # (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60 - NTP_DELTA = 3155673600 - elif EPOCH_YEAR == 1970: - # (date(1970, 1, 1) - date(1900, 1, 1)).days * 24*60*60 - NTP_DELTA = 2208988800 - else: - raise Exception("Unsupported epoch: {}".format(EPOCH_YEAR)) - - return val - NTP_DELTA - - -# There's currently no timezone support in MicroPython, and the RTC is set in UTC time. -def settime(): - t = time() - import machine - - tm = utime.gmtime(t) - machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0)) diff --git a/extmod/webrepl/manifest.py b/extmod/webrepl/manifest.py deleted file mode 100644 index 6d1a314219ca..000000000000 --- a/extmod/webrepl/manifest.py +++ /dev/null @@ -1,2 +0,0 @@ -module("webrepl.py", opt=3) -module("webrepl_setup.py", opt=3) diff --git a/extmod/webrepl/webrepl.py b/extmod/webrepl/webrepl.py deleted file mode 100644 index 56767d8b71f7..000000000000 --- a/extmod/webrepl/webrepl.py +++ /dev/null @@ -1,177 +0,0 @@ -# This module should be imported from REPL, not run from command line. -import binascii -import hashlib -import network -import os -import socket -import sys -import websocket -import _webrepl - -listen_s = None -client_s = None - -DEBUG = 0 - -_DEFAULT_STATIC_HOST = const("https://micropython.org/webrepl/") -static_host = _DEFAULT_STATIC_HOST - - -def server_handshake(cl): - req = cl.makefile("rwb", 0) - # Skip HTTP GET line. - l = req.readline() - if DEBUG: - sys.stdout.write(repr(l)) - - webkey = None - upgrade = False - websocket = False - - while True: - l = req.readline() - if not l: - # EOF in headers. - return False - if l == b"\r\n": - break - if DEBUG: - sys.stdout.write(l) - h, v = [x.strip() for x in l.split(b":", 1)] - if DEBUG: - print((h, v)) - if h == b"Sec-WebSocket-Key": - webkey = v - elif h == b"Connection" and b"Upgrade" in v: - upgrade = True - elif h == b"Upgrade" and v == b"websocket": - websocket = True - - if not (upgrade and websocket and webkey): - return False - - if DEBUG: - print("Sec-WebSocket-Key:", webkey, len(webkey)) - - d = hashlib.sha1(webkey) - d.update(b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11") - respkey = d.digest() - respkey = binascii.b2a_base64(respkey)[:-1] - if DEBUG: - print("respkey:", respkey) - - cl.send( - b"""\ -HTTP/1.1 101 Switching Protocols\r -Upgrade: websocket\r -Connection: Upgrade\r -Sec-WebSocket-Accept: """ - ) - cl.send(respkey) - cl.send("\r\n\r\n") - - return True - - -def send_html(cl): - cl.send( - b"""\ -HTTP/1.0 200 OK\r -\r -\r -\r -""" - ) - cl.close() - - -def setup_conn(port, accept_handler): - global listen_s - listen_s = socket.socket() - listen_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - ai = socket.getaddrinfo("0.0.0.0", port) - addr = ai[0][4] - - listen_s.bind(addr) - listen_s.listen(1) - if accept_handler: - listen_s.setsockopt(socket.SOL_SOCKET, 20, accept_handler) - for i in (network.AP_IF, network.STA_IF): - iface = network.WLAN(i) - if iface.active(): - print("WebREPL server started on http://%s:%d/" % (iface.ifconfig()[0], port)) - return listen_s - - -def accept_conn(listen_sock): - global client_s - cl, remote_addr = listen_sock.accept() - - if not server_handshake(cl): - send_html(cl) - return False - - prev = os.dupterm(None) - os.dupterm(prev) - if prev: - print("\nConcurrent WebREPL connection from", remote_addr, "rejected") - cl.close() - return False - print("\nWebREPL connection from:", remote_addr) - client_s = cl - - ws = websocket.websocket(cl, True) - ws = _webrepl._webrepl(ws) - cl.setblocking(False) - # notify REPL on socket incoming data (ESP32/ESP8266-only) - if hasattr(os, "dupterm_notify"): - cl.setsockopt(socket.SOL_SOCKET, 20, os.dupterm_notify) - os.dupterm(ws) - - return True - - -def stop(): - global listen_s, client_s - os.dupterm(None) - if client_s: - client_s.close() - if listen_s: - listen_s.close() - - -def start(port=8266, password=None, accept_handler=accept_conn): - global static_host - stop() - webrepl_pass = password - if webrepl_pass is None: - try: - import webrepl_cfg - - webrepl_pass = webrepl_cfg.PASS - if hasattr(webrepl_cfg, "BASE"): - static_host = webrepl_cfg.BASE - except: - print("WebREPL is not configured, run 'import webrepl_setup'") - - _webrepl.password(webrepl_pass) - s = setup_conn(port, accept_handler) - - if accept_handler is None: - print("Starting webrepl in foreground mode") - # Run accept_conn to serve HTML until we get a websocket connection. - while not accept_conn(s): - pass - elif password is None: - print("Started webrepl in normal mode") - else: - print("Started webrepl in manual override mode") - - -def start_foreground(port=8266, password=None): - start(port, password, None) diff --git a/extmod/webrepl/webrepl_setup.py b/extmod/webrepl/webrepl_setup.py deleted file mode 100644 index 16e5f76e655e..000000000000 --- a/extmod/webrepl/webrepl_setup.py +++ /dev/null @@ -1,107 +0,0 @@ -import sys - -import os -import machine - -RC = "./boot.py" -CONFIG = "./webrepl_cfg.py" - - -def input_choice(prompt, choices): - while 1: - resp = input(prompt) - if resp in choices: - return resp - - -def getpass(prompt): - return input(prompt) - - -def input_pass(): - while 1: - passwd1 = getpass("New password (4-9 chars): ") - if len(passwd1) < 4 or len(passwd1) > 9: - print("Invalid password length") - continue - passwd2 = getpass("Confirm password: ") - if passwd1 == passwd2: - return passwd1 - print("Passwords do not match") - - -def exists(fname): - try: - with open(fname): - pass - return True - except OSError: - return False - - -def get_daemon_status(): - with open(RC) as f: - for l in f: - if "webrepl" in l: - if l.startswith("#"): - return False - return True - return None - - -def change_daemon(action): - LINES = ("import webrepl", "webrepl.start()") - with open(RC) as old_f, open(RC + ".tmp", "w") as new_f: - found = False - for l in old_f: - for patt in LINES: - if patt in l: - found = True - if action and l.startswith("#"): - l = l[1:] - elif not action and not l.startswith("#"): - l = "#" + l - new_f.write(l) - if not found: - new_f.write("import webrepl\nwebrepl.start()\n") - # FatFs rename() is not POSIX compliant, will raise OSError if - # dest file exists. - os.remove(RC) - os.rename(RC + ".tmp", RC) - - -def main(): - status = get_daemon_status() - - print("WebREPL daemon auto-start status:", "enabled" if status else "disabled") - print("\nWould you like to (E)nable or (D)isable it running on boot?") - print("(Empty line to quit)") - resp = input("> ").upper() - - if resp == "E": - if exists(CONFIG): - resp2 = input_choice( - "Would you like to change WebREPL password? (y/n) ", ("y", "n", "") - ) - else: - print("To enable WebREPL, you must set password for it") - resp2 = "y" - - if resp2 == "y": - passwd = input_pass() - with open(CONFIG, "w") as f: - f.write("PASS = %r\n" % passwd) - - if resp not in ("D", "E") or (resp == "D" and not status) or (resp == "E" and status): - print("No further action required") - sys.exit() - - change_daemon(resp == "E") - - print("Changes will be activated after reboot") - resp = input_choice("Would you like to reboot now? (y/n) ", ("y", "n", "")) - if resp == "y": - machine.reset() - - -main() From 6aa3c946347281875165392c09753547d8c77fc3 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 5 Sep 2022 11:20:10 +0100 Subject: [PATCH 1705/4290] rp2/rp2_flash: Add start/len support to rp2.Flash() constructor. This allows support for partitioned flash on rp2 boards. See issue #9208. Signed-off-by: Phil Howard --- ports/rp2/rp2_flash.c | 45 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c index db6b9f3bfe75..47c95ea5c822 100644 --- a/ports/rp2/rp2_flash.c +++ b/ports/rp2/rp2_flash.c @@ -70,16 +70,45 @@ bi_decl(bi_block_device( BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN)); STATIC mp_obj_t rp2_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - // Check args. - mp_arg_check_num(n_args, n_kw, 0, 0, false); + // Parse arguments + enum { ARG_start, ARG_len }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (args[ARG_start].u_int == -1 && args[ARG_len].u_int == -1) { + #ifndef NDEBUG + extern char __flash_binary_end; + assert((uintptr_t)&__flash_binary_end - XIP_BASE <= MICROPY_HW_FLASH_STORAGE_BASE); + #endif + + // Default singleton object that accesses entire flash + return MP_OBJ_FROM_PTR(&rp2_flash_obj); + } + + rp2_flash_obj_t *self = mp_obj_malloc(rp2_flash_obj_t, &rp2_flash_type); + + mp_int_t start = args[ARG_start].u_int; + if (start == -1) { + start = 0; + } else if (!(0 <= start && start < MICROPY_HW_FLASH_STORAGE_BYTES && start % BLOCK_SIZE_BYTES == 0)) { + mp_raise_ValueError(NULL); + } + + mp_int_t len = args[ARG_len].u_int; + if (len == -1) { + len = MICROPY_HW_FLASH_STORAGE_BYTES - start; + } else if (!(0 < len && start + len <= MICROPY_HW_FLASH_STORAGE_BYTES && len % BLOCK_SIZE_BYTES == 0)) { + mp_raise_ValueError(NULL); + } - #ifndef NDEBUG - extern char __flash_binary_end; - assert((uintptr_t)&__flash_binary_end - XIP_BASE <= MICROPY_HW_FLASH_STORAGE_BASE); - #endif + self->flash_base = MICROPY_HW_FLASH_STORAGE_BASE + start; + self->flash_size = len; - // Return singleton object. - return MP_OBJ_FROM_PTR(&rp2_flash_obj); + return MP_OBJ_FROM_PTR(self); } STATIC mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) { From c364301817d828eeb6df74095b3ea8083e8fbef6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 23:32:11 +1000 Subject: [PATCH 1706/4290] rp2/boards: Set PICO_BOARD correctly for each board. In most cases, it's calculated automatically from the board name, and so doesn't need to be set at all. Signed-off-by: Jim Mussared --- .../rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake | 2 -- ports/rp2/boards/PICO_W/mpconfigboard.cmake | 2 -- ports/rp2/boards/W5100S_EVB_PICO/mpconfigboard.cmake | 2 +- ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake index 311e114b2914..11fcb3d087ec 100644 --- a/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake +++ b/ports/rp2/boards/GARATRONIC_PYBSTICK26_RP2040/mpconfigboard.cmake @@ -1,3 +1 @@ # cmake file - -set(PICO_BOARD garatronic_pybstick26_rp2040) diff --git a/ports/rp2/boards/PICO_W/mpconfigboard.cmake b/ports/rp2/boards/PICO_W/mpconfigboard.cmake index d3fbce699327..681e0dec44ff 100644 --- a/ports/rp2/boards/PICO_W/mpconfigboard.cmake +++ b/ports/rp2/boards/PICO_W/mpconfigboard.cmake @@ -1,6 +1,4 @@ # cmake file for Raspberry Pi Pico W -set(MICROPY_BOARD PICO_W) - set(MICROPY_PY_LWIP ON) set(MICROPY_PY_NETWORK_CYW43 ON) diff --git a/ports/rp2/boards/W5100S_EVB_PICO/mpconfigboard.cmake b/ports/rp2/boards/W5100S_EVB_PICO/mpconfigboard.cmake index bc5d1ea65e8b..4746c6e267a1 100644 --- a/ports/rp2/boards/W5100S_EVB_PICO/mpconfigboard.cmake +++ b/ports/rp2/boards/W5100S_EVB_PICO/mpconfigboard.cmake @@ -1,4 +1,4 @@ # cmake file for Wiznet W5100S-EVB-Pico. -set(PICO_BOARD pico) +set(PICO_BOARD wiznet_w5100s_evb_pico) set(MICROPY_PY_NETWORK_WIZNET5K W5100S) set(MICROPY_PY_LWIP 1) diff --git a/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake b/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake index 875b89f2befe..f7f2650bfa0e 100644 --- a/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake +++ b/ports/rp2/boards/W5500_EVB_PICO/mpconfigboard.cmake @@ -1,4 +1,4 @@ # cmake file for Wiznet W5500-EVB-Pico. -set(PICO_BOARD pico) +set(PICO_BOARD wiznet_w5100s_evb_pico) set(MICROPY_PY_NETWORK_WIZNET5K W5500) set(MICROPY_PY_LWIP 1) From 29437205f29976db71dc12d61ce756732e6f813a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 22:54:40 +1000 Subject: [PATCH 1707/4290] rp2/machine_spi: Use pico-sdk's default pins for SPI. Rather than hardcoding the defaults, use pico-sdk's board definition. Signed-off-by: Jim Mussared --- ports/rp2/machine_spi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ports/rp2/machine_spi.c b/ports/rp2/machine_spi.c index 42998664a76d..104bd1fd5338 100644 --- a/ports/rp2/machine_spi.c +++ b/ports/rp2/machine_spi.c @@ -40,20 +40,36 @@ #define DEFAULT_SPI_FIRSTBIT (SPI_MSB_FIRST) #ifndef MICROPY_HW_SPI0_SCK +#if PICO_DEFAULT_SPI == 0 +#define MICROPY_HW_SPI0_SCK (PICO_DEFAULT_SPI_SCK_PIN) +#define MICROPY_HW_SPI0_MOSI (PICO_DEFAULT_SPI_TX_PIN) +#define MICROPY_HW_SPI0_MISO (PICO_DEFAULT_SPI_RX_PIN) +#else #define MICROPY_HW_SPI0_SCK (6) #define MICROPY_HW_SPI0_MOSI (7) #define MICROPY_HW_SPI0_MISO (4) #endif +#endif #ifndef MICROPY_HW_SPI1_SCK +#if PICO_DEFAULT_SPI == 1 +#define MICROPY_HW_SPI1_SCK (PICO_DEFAULT_SPI_SCK_PIN) +#define MICROPY_HW_SPI1_MOSI (PICO_DEFAULT_SPI_TX_PIN) +#define MICROPY_HW_SPI1_MISO (PICO_DEFAULT_SPI_RX_PIN) +#else #define MICROPY_HW_SPI1_SCK (10) #define MICROPY_HW_SPI1_MOSI (11) #define MICROPY_HW_SPI1_MISO (8) #endif +#endif +// SPI0 can be GP{0..7,16..23}, SPI1 can be GP{8..15,24..29}. #define IS_VALID_PERIPH(spi, pin) ((((pin) & 8) >> 3) == (spi)) +// GP{2,6,10,14,...} #define IS_VALID_SCK(spi, pin) (((pin) & 3) == 2 && IS_VALID_PERIPH(spi, pin)) +// GP{3,7,11,15,...} #define IS_VALID_MOSI(spi, pin) (((pin) & 3) == 3 && IS_VALID_PERIPH(spi, pin)) +// GP{0,4,8,10,...} #define IS_VALID_MISO(spi, pin) (((pin) & 3) == 0 && IS_VALID_PERIPH(spi, pin)) typedef struct _machine_spi_obj_t { From 315e74236fb7be7c72f708832038596d668979b7 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 23:28:50 +1000 Subject: [PATCH 1708/4290] rp2/machine_i2c: Use pico-sdk's default pins for I2C. Inherits the default values for whichever instance is PICO_DEFAULT_I2C. Signed-off-by: Jim Mussared --- ports/rp2/machine_i2c.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ports/rp2/machine_i2c.c b/ports/rp2/machine_i2c.c index f785ad7dedf3..3390cc42101d 100644 --- a/ports/rp2/machine_i2c.c +++ b/ports/rp2/machine_i2c.c @@ -35,14 +35,24 @@ #define DEFAULT_I2C_FREQ (400000) #ifndef MICROPY_HW_I2C0_SCL +#if PICO_DEFAULT_I2C == 0 +#define MICROPY_HW_I2C0_SCL (PICO_DEFAULT_I2C_SCL_PIN) +#define MICROPY_HW_I2C0_SDA (PICO_DEFAULT_I2C_SDA_PIN) +#else #define MICROPY_HW_I2C0_SCL (9) #define MICROPY_HW_I2C0_SDA (8) #endif +#endif #ifndef MICROPY_HW_I2C1_SCL +#if PICO_DEFAULT_I2C == 1 +#define MICROPY_HW_I2C1_SCL (PICO_DEFAULT_I2C_SCL_PIN) +#define MICROPY_HW_I2C1_SDA (PICO_DEFAULT_I2C_SDA_PIN) +#else #define MICROPY_HW_I2C1_SCL (7) #define MICROPY_HW_I2C1_SDA (6) #endif +#endif // SDA/SCL on even/odd pins, I2C0/I2C1 on even/odd pairs of pins. #define IS_VALID_SCL(i2c, pin) (((pin) & 1) == 1 && (((pin) & 2) >> 1) == (i2c)) From dec0ff7a10efee286037812287d5bfcad611f64f Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 6 Sep 2022 23:32:34 +1000 Subject: [PATCH 1709/4290] rp2/boards: Remove all I2C,SPI pin defs that already match pico-sdk. I.e. for whichever SPI/I2C instance is PICO_DEFAULT_I2C, there's no need to set MICROPY_HW_SPIn_SCK. The only ones remaining are for the non-default instance. Signed-off-by: Jim Mussared --- .../rp2/boards/ADAFRUIT_FEATHER_RP2040/mpconfigboard.h | 8 -------- .../boards/ADAFRUIT_ITSYBITSY_RP2040/mpconfigboard.h | 7 ------- ports/rp2/boards/ADAFRUIT_QTPY_RP2040/mpconfigboard.h | 9 +-------- .../boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h | 8 ++------ .../rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h | 8 -------- ports/rp2/boards/PIMORONI_PICOLIPO_4MB/mpconfigboard.h | 8 -------- ports/rp2/boards/PIMORONI_TINY2040/mpconfigboard.h | 1 + ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h | 8 -------- ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h | 10 +--------- 9 files changed, 5 insertions(+), 62 deletions(-) diff --git a/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/mpconfigboard.h b/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/mpconfigboard.h index 84d2bf20dbc6..f9cd030d46ce 100644 --- a/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/mpconfigboard.h +++ b/ports/rp2/boards/ADAFRUIT_FEATHER_RP2040/mpconfigboard.h @@ -7,14 +7,6 @@ #define MICROPY_HW_USB_VID (0x239A) #define MICROPY_HW_USB_PID (0x80F2) -// STEMMA QT / Qwiic on I2C1 -#define MICROPY_HW_I2C1_SCL (3) -#define MICROPY_HW_I2C1_SDA (2) - -#define MICROPY_HW_SPI0_SCK (18) -#define MICROPY_HW_SPI0_MOSI (19) -#define MICROPY_HW_SPI0_MISO (20) - // NeoPixel GPIO16, power not toggleable // Red user LED GPIO13 diff --git a/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/mpconfigboard.h b/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/mpconfigboard.h index 8f5551172bf9..be950f4f99d4 100644 --- a/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/mpconfigboard.h +++ b/ports/rp2/boards/ADAFRUIT_ITSYBITSY_RP2040/mpconfigboard.h @@ -7,13 +7,6 @@ #define MICROPY_HW_USB_VID (0x239A) #define MICROPY_HW_USB_PID (0x80FE) -#define MICROPY_HW_I2C0_SCL (3) -#define MICROPY_HW_I2C0_SDA (2) - -#define MICROPY_HW_SPI0_SCK (18) -#define MICROPY_HW_SPI0_MOSI (19) -#define MICROPY_HW_SPI0_MISO (20) - // NeoPixel data GPIO17, power GPIO16 // Red user LED GPIO11 diff --git a/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/mpconfigboard.h b/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/mpconfigboard.h index ca341cedd8d2..6d834fd4f5d6 100644 --- a/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/mpconfigboard.h +++ b/ports/rp2/boards/ADAFRUIT_QTPY_RP2040/mpconfigboard.h @@ -12,17 +12,10 @@ #define MICROPY_HW_UART1_CTS (10) #define MICROPY_HW_UART1_RTS (7) -#define MICROPY_HW_I2C0_SCL (25) -#define MICROPY_HW_I2C0_SDA (24) - -// STEMMA QT / Qwiic on I2C1 +// STEMMA QT / Qwiic on (non-default) I2C1 #define MICROPY_HW_I2C1_SCL (23) #define MICROPY_HW_I2C1_SDA (22) -#define MICROPY_HW_SPI0_SCK (6) -#define MICROPY_HW_SPI0_MOSI (3) -#define MICROPY_HW_SPI0_MISO (4) - // NeoPixel data GPIO12, power GPIO11 // Boot button GPIO21 diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h index 87b9187659a4..5ea9b8cdb850 100644 --- a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h @@ -22,16 +22,12 @@ #define MICROPY_HW_UART1_CTS (10) #define MICROPY_HW_UART1_RTS (11) -// SPI 1 config. +// SPI 1 config (non-default). #define MICROPY_HW_SPI1_SCK (14) #define MICROPY_HW_SPI1_MOSI (11) #define MICROPY_HW_SPI1_MISO (8) -// I2C0 config. -#define MICROPY_HW_I2C0_SCL (13) -#define MICROPY_HW_I2C0_SDA (12) - -// I2C1 config. +// I2C1 config (non-default). #define MICROPY_HW_I2C1_SCL (27) #define MICROPY_HW_I2C1_SDA (26) diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h index 134c2ff78495..a90ef6783d66 100644 --- a/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_16MB/mpconfigboard.h @@ -11,14 +11,6 @@ #define MICROPY_HW_UART1_CTS (10) #define MICROPY_HW_UART1_RTS (11) -// Qwiic on I2C0 -#define MICROPY_HW_I2C0_SCL (4) -#define MICROPY_HW_I2C0_SDA (5) - -#define MICROPY_HW_SPI0_SCK (18) -#define MICROPY_HW_SPI0_MOSI (19) -#define MICROPY_HW_SPI0_MISO (16) - // User LED GPIO25 // VBUS_SENSE GPIO24 diff --git a/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/mpconfigboard.h b/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/mpconfigboard.h index fd45547e1b28..53ade7291532 100644 --- a/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/mpconfigboard.h +++ b/ports/rp2/boards/PIMORONI_PICOLIPO_4MB/mpconfigboard.h @@ -11,14 +11,6 @@ #define MICROPY_HW_UART1_CTS (10) #define MICROPY_HW_UART1_RTS (11) -// Qwiic on I2C0 -#define MICROPY_HW_I2C0_SCL (4) -#define MICROPY_HW_I2C0_SDA (5) - -#define MICROPY_HW_SPI0_SCK (18) -#define MICROPY_HW_SPI0_MOSI (19) -#define MICROPY_HW_SPI0_MISO (16) - // User LED GPIO25 // VBUS_SENSE GPIO24 diff --git a/ports/rp2/boards/PIMORONI_TINY2040/mpconfigboard.h b/ports/rp2/boards/PIMORONI_TINY2040/mpconfigboard.h index 50cb2bd59936..ea40a8071b77 100644 --- a/ports/rp2/boards/PIMORONI_TINY2040/mpconfigboard.h +++ b/ports/rp2/boards/PIMORONI_TINY2040/mpconfigboard.h @@ -6,6 +6,7 @@ #define MICROPY_HW_USB_VID (0x16D0) #define MICROPY_HW_USB_PID (0x08C7) +// I2C0 (non-default) #define MICROPY_HW_I2C0_SCL (4) #define MICROPY_HW_I2C0_SDA (5) diff --git a/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h b/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h index 65b29eecd151..72a9aeb373e4 100644 --- a/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h +++ b/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h @@ -11,12 +11,4 @@ #define MICROPY_HW_UART1_CTS (10) #define MICROPY_HW_UART1_RTS (11) -// Qwiic on I2C0 -#define MICROPY_HW_I2C0_SCL (17) -#define MICROPY_HW_I2C0_SDA (16) - -#define MICROPY_HW_SPI0_SCK (22) -#define MICROPY_HW_SPI0_MOSI (23) -#define MICROPY_HW_SPI0_MISO (20) - // NeoPixel data GPIO25, power not toggleable diff --git a/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h b/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h index f88ba5dd63c8..c2ca90b96835 100644 --- a/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h +++ b/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h @@ -9,15 +9,7 @@ #define MICROPY_HW_I2C0_SCL (17) #define MICROPY_HW_I2C0_SDA (16) -// Qwiic on I2C1 -#define MICROPY_HW_I2C1_SCL (7) -#define MICROPY_HW_I2C1_SDA (6) - -#define MICROPY_HW_SPI0_SCK (2) -#define MICROPY_HW_SPI0_MOSI (3) -#define MICROPY_HW_SPI0_MISO (4) - -// MicroSD on SPI1 +// MicroSD on SPI1 (non-default) #define MICROPY_HW_SPI1_SCK (14) #define MICROPY_HW_SPI1_MOSI (15) #define MICROPY_HW_SPI1_MISO (12) From 9070a2494022383586e1f86745ae4c9af52389f6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 8 Sep 2022 13:55:50 +1000 Subject: [PATCH 1710/4290] tools/autobuild: Use distinct directory for building stm32 variants. Previous the build directory just used the board name, now make it use the variant name too. This shouldn't have any change because the existing directory should not exist (all builds run by these scripts remove their build directory after completion), but it makes debugging easier. Signed-off-by: Jim Mussared --- tools/autobuild/build-stm32-extra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/autobuild/build-stm32-extra.sh b/tools/autobuild/build-stm32-extra.sh index feb269e35604..887e3cd24694 100755 --- a/tools/autobuild/build-stm32-extra.sh +++ b/tools/autobuild/build-stm32-extra.sh @@ -10,7 +10,7 @@ function do_build() { for variant in `$MICROPY_AUTOBUILD_MAKE BOARD=$board query-variants | grep VARIANTS: | cut -d' ' -f2-`; do target=$descr-$variant echo "building $target $board" - build_dir=/tmp/stm-build-$board + build_dir=/tmp/stm-build-$board-$variant $MICROPY_AUTOBUILD_MAKE $@ BOARD=$board BOARD_VARIANT=$variant BUILD=$build_dir || exit 1 mv $build_dir/firmware.dfu $dest_dir/$target$fw_tag.dfu mv $build_dir/firmware.hex $dest_dir/$target$fw_tag.hex From 6e75d177e778caebe791add7eb4cc9eff3a33b6a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 8 Sep 2022 13:58:03 +1000 Subject: [PATCH 1711/4290] stm32/boards/PYB: Fix handling of BOARD_VARIANT selection. The matches should not have been quoted. Signed-off-by: Jim Mussared --- ports/stm32/boards/PYBLITEV10/mpconfigboard.mk | 8 ++++---- ports/stm32/boards/PYBV10/mpconfigboard.mk | 8 ++++---- ports/stm32/boards/PYBV11/mpconfigboard.mk | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk index 74698664760f..461886b63cab 100644 --- a/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBLITEV10/mpconfigboard.mk @@ -8,20 +8,20 @@ TEXT1_ADDR = 0x08020000 # Provide different variants for the downloads page. BOARD_VARIANTS += "dp thread dp-thread network" -ifeq ($(BOARD_VARIANT),"dp") +ifeq ($(BOARD_VARIANT),dp) MICROPY_FLOAT_IMPL=double endif -ifeq ($(BOARD_VARIANT),"thread") +ifeq ($(BOARD_VARIANT),thread) CFLAGS += -DMICROPY_PY_THREAD=1 endif -ifeq ($(BOARD_VARIANT),"dp-thread") +ifeq ($(BOARD_VARIANT),dp-thread) MICROPY_FLOAT_IMPL=double CFLAGS += -DMICROPY_PY_THREAD=1 endif -ifeq ($(BOARD_VARIANT),"network") +ifeq ($(BOARD_VARIANT),network) MICROPY_PY_NETWORK_WIZNET5K=5200 endif diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.mk b/ports/stm32/boards/PYBV10/mpconfigboard.mk index af2878267803..363f6b480616 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV10/mpconfigboard.mk @@ -18,20 +18,20 @@ MICROPY_VFS_LFS2 = 1 # Provide different variants for the downloads page. BOARD_VARIANTS += "dp thread dp-thread network" -ifeq ($(BOARD_VARIANT),"dp") +ifeq ($(BOARD_VARIANT),dp) MICROPY_FLOAT_IMPL=double endif -ifeq ($(BOARD_VARIANT),"thread") +ifeq ($(BOARD_VARIANT),thread) CFLAGS += -DMICROPY_PY_THREAD=1 endif -ifeq ($(BOARD_VARIANT),"dp-thread") +ifeq ($(BOARD_VARIANT),dp-thread) MICROPY_FLOAT_IMPL=double CFLAGS += -DMICROPY_PY_THREAD=1 endif -ifeq ($(BOARD_VARIANT),"network") +ifeq ($(BOARD_VARIANT),network) MICROPY_PY_NETWORK_WIZNET5K=5200 endif diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.mk b/ports/stm32/boards/PYBV11/mpconfigboard.mk index cf7884cfc67a..857049f21596 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.mk +++ b/ports/stm32/boards/PYBV11/mpconfigboard.mk @@ -18,20 +18,20 @@ MICROPY_VFS_LFS2 = 1 # Provide different variants for the downloads page. BOARD_VARIANTS += "dp thread dp-thread network" -ifeq ($(BOARD_VARIANT),"dp") +ifeq ($(BOARD_VARIANT),dp) MICROPY_FLOAT_IMPL=double endif -ifeq ($(BOARD_VARIANT),"thread") +ifeq ($(BOARD_VARIANT),thread) CFLAGS += -DMICROPY_PY_THREAD=1 endif -ifeq ($(BOARD_VARIANT),"dp-thread") +ifeq ($(BOARD_VARIANT),dp-thread) MICROPY_FLOAT_IMPL=double CFLAGS += -DMICROPY_PY_THREAD=1 endif -ifeq ($(BOARD_VARIANT),"network") +ifeq ($(BOARD_VARIANT),network) MICROPY_PY_NETWORK_WIZNET5K=5200 endif From 82fc16f2982b38f6dfd0145b8012b34308d13605 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 9 Aug 2022 16:48:04 +1000 Subject: [PATCH 1712/4290] extmod/modbluetooth: Fix descriptor registration with empty tuple. Incorrect use of "continue" when the tuple was length zero meant it broke the rest of the argument handling. Signed-off-by: Jim Mussared --- extmod/modbluetooth.c | 62 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 4645ae6c9869..c2cbf0e70ad5 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -529,43 +529,41 @@ STATIC int bluetooth_gatts_register_service(mp_obj_t uuid_in, mp_obj_t character // Optional third element, iterable of descriptors. if (characteristic_len >= 3) { - mp_obj_t descriptors_len_in = mp_obj_len(characteristic_items[2]); - num_descriptors[characteristic_index] = mp_obj_get_int(descriptors_len_in); + mp_int_t n = mp_obj_get_int(mp_obj_len(characteristic_items[2])); + if (n) { + num_descriptors[characteristic_index] = n; + + // Grow the flattened uuids and flags arrays with this many more descriptors. + descriptor_uuids = m_renew(mp_obj_bluetooth_uuid_t *, descriptor_uuids, descriptor_index, descriptor_index + num_descriptors[characteristic_index]); + descriptor_flags = m_renew(uint16_t, descriptor_flags, descriptor_index, descriptor_index + num_descriptors[characteristic_index]); + + // Also grow the handles array. + *handles = m_renew(uint16_t, *handles, *num_handles, *num_handles + num_descriptors[characteristic_index]); + + mp_obj_iter_buf_t iter_buf_desc; + mp_obj_t iterable_desc = mp_getiter(characteristic_items[2], &iter_buf_desc); + mp_obj_t descriptor_obj; + + // Extract out descriptors for this characteristic. + while ((descriptor_obj = mp_iternext(iterable_desc)) != MP_OBJ_STOP_ITERATION) { + // (uuid, flags,) + mp_obj_t *descriptor_items; + mp_obj_get_array_fixed_n(descriptor_obj, 2, &descriptor_items); + mp_obj_t desc_uuid_obj = descriptor_items[0]; + if (!mp_obj_is_type(desc_uuid_obj, &mp_type_bluetooth_uuid)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid descriptor UUID")); + } - if (num_descriptors[characteristic_index] == 0) { - continue; - } + descriptor_uuids[descriptor_index] = MP_OBJ_TO_PTR(desc_uuid_obj); + descriptor_flags[descriptor_index] = mp_obj_get_int(descriptor_items[1]); + ++descriptor_index; - // Grow the flattened uuids and flags arrays with this many more descriptors. - descriptor_uuids = m_renew(mp_obj_bluetooth_uuid_t *, descriptor_uuids, descriptor_index, descriptor_index + num_descriptors[characteristic_index]); - descriptor_flags = m_renew(uint16_t, descriptor_flags, descriptor_index, descriptor_index + num_descriptors[characteristic_index]); - - // Also grow the handles array. - *handles = m_renew(uint16_t, *handles, *num_handles, *num_handles + num_descriptors[characteristic_index]); - - mp_obj_iter_buf_t iter_buf_desc; - mp_obj_t iterable_desc = mp_getiter(characteristic_items[2], &iter_buf_desc); - mp_obj_t descriptor_obj; - - // Extract out descriptors for this characteristic. - while ((descriptor_obj = mp_iternext(iterable_desc)) != MP_OBJ_STOP_ITERATION) { - // (uuid, flags,) - mp_obj_t *descriptor_items; - mp_obj_get_array_fixed_n(descriptor_obj, 2, &descriptor_items); - mp_obj_t desc_uuid_obj = descriptor_items[0]; - if (!mp_obj_is_type(desc_uuid_obj, &mp_type_bluetooth_uuid)) { - mp_raise_ValueError(MP_ERROR_TEXT("invalid descriptor UUID")); + (*handles)[handle_index++] = 0xffff; } - descriptor_uuids[descriptor_index] = MP_OBJ_TO_PTR(desc_uuid_obj); - descriptor_flags[descriptor_index] = mp_obj_get_int(descriptor_items[1]); - ++descriptor_index; - - (*handles)[handle_index++] = 0xffff; + // Reflect that we've grown the handles array. + *num_handles += num_descriptors[characteristic_index]; } - - // Reflect that we've grown the handles array. - *num_handles += num_descriptors[characteristic_index]; } characteristic_uuids[characteristic_index] = MP_OBJ_TO_PTR(uuid_obj); From cacc96d98c2a70dc7e5194331ea70746c39746ec Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 9 Aug 2022 16:50:58 +1000 Subject: [PATCH 1713/4290] extmod/modbluetooth: Replace def_handle with end_handle in char IRQ. This is technically a breaking change, but: a) We need the end handle to do descriptor discovery properly. b) We have no possible use for the existing definition handle in the characteristic result IRQ. None of the methods can use it, and therefore no existing code should be using it in a way that changing it to a different integer value should break. Unfortunately NimBLE doesn't make it easy to get the end handle, so also implement a mechanism to use the following characteristic to calculate the previous characteristic's end handle. Signed-off-by: Jim Mussared --- docs/library/bluetooth.rst | 2 +- extmod/btstack/modbluetooth_btstack.c | 2 +- extmod/modbluetooth.c | 12 +++-- extmod/modbluetooth.h | 2 +- extmod/nimble/modbluetooth_nimble.c | 70 +++++++++++++++++++++++---- extmod/nimble/modbluetooth_nimble.h | 15 ++++++ 6 files changed, 86 insertions(+), 17 deletions(-) diff --git a/docs/library/bluetooth.rst b/docs/library/bluetooth.rst index 052f7a5c7803..8f7041e8d3fb 100644 --- a/docs/library/bluetooth.rst +++ b/docs/library/bluetooth.rst @@ -166,7 +166,7 @@ Event Handling conn_handle, status = data elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT: # Called for each characteristic found by gattc_discover_services(). - conn_handle, def_handle, value_handle, properties, uuid = data + conn_handle, end_handle, value_handle, properties, uuid = data elif event == _IRQ_GATTC_CHARACTERISTIC_DONE: # Called once service discovery is complete. # Note: Status will be zero on success, implementation-specific value otherwise. diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index d41c671d68a3..b58be78a9942 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -450,7 +450,7 @@ STATIC void btstack_packet_handler(uint8_t packet_type, uint8_t *packet, uint8_t gatt_client_characteristic_t characteristic; gatt_event_characteristic_query_result_get_characteristic(packet, &characteristic); mp_obj_bluetooth_uuid_t characteristic_uuid = create_mp_uuid(characteristic.uuid16, characteristic.uuid128); - mp_bluetooth_gattc_on_characteristic_result(conn_handle, characteristic.start_handle, characteristic.value_handle, characteristic.properties, &characteristic_uuid); + mp_bluetooth_gattc_on_characteristic_result(conn_handle, characteristic.value_handle, characteristic.end_handle, characteristic.properties, &characteristic_uuid); } else if (event_type == GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT) { DEBUG_printf(" --> gatt descriptor query result\n"); uint16_t conn_handle = gatt_event_all_characteristic_descriptors_query_result_get_handle(packet); diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index c2cbf0e70ad5..bd4d9b71790c 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -1101,7 +1101,7 @@ STATIC mp_obj_t bluetooth_ble_invoke_irq(mp_obj_t none_in) { // conn_handle, start_handle, end_handle, uuid ringbuf_extract(&o->ringbuf, data_tuple, 3, 0, NULL, 0, &o->irq_data_uuid, NULL); } else if (event == MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_RESULT) { - // conn_handle, def_handle, value_handle, properties, uuid + // conn_handle, end_handle, value_handle, properties, uuid ringbuf_extract(&o->ringbuf, data_tuple, 3, 1, NULL, 0, &o->irq_data_uuid, NULL); } else if (event == MP_BLUETOOTH_IRQ_GATTC_DESCRIPTOR_RESULT) { // conn_handle, handle, uuid @@ -1375,8 +1375,9 @@ void mp_bluetooth_gattc_on_primary_service_result(uint16_t conn_handle, uint16_t invoke_irq_handler(MP_BLUETOOTH_IRQ_GATTC_SERVICE_RESULT, args, 3, 0, NULL_ADDR, service_uuid, NULL_DATA, NULL_DATA_LEN, 0); } -void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t def_handle, uint16_t value_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid) { - mp_int_t args[] = {conn_handle, def_handle, value_handle, properties}; +void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t value_handle, uint16_t end_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid) { + // Note: "end_handle" replaces "def_handle" from the original version of this event. + mp_int_t args[] = {conn_handle, end_handle, value_handle, properties}; invoke_irq_handler(MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_RESULT, args, 4, 0, NULL_ADDR, characteristic_uuid, NULL_DATA, NULL_DATA_LEN, 0); } @@ -1588,12 +1589,13 @@ void mp_bluetooth_gattc_on_primary_service_result(uint16_t conn_handle, uint16_t schedule_ringbuf(atomic_state); } -void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t def_handle, uint16_t value_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid) { +void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t value_handle, uint16_t end_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid) { MICROPY_PY_BLUETOOTH_ENTER mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth)); if (enqueue_irq(o, 2 + 2 + 2 + 1 + characteristic_uuid->type, MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_RESULT)) { ringbuf_put16(&o->ringbuf, conn_handle); - ringbuf_put16(&o->ringbuf, def_handle); + // Note: "end_handle" replaces "def_handle" from the original version of this event. + ringbuf_put16(&o->ringbuf, end_handle); ringbuf_put16(&o->ringbuf, value_handle); ringbuf_put(&o->ringbuf, properties); ringbuf_put_uuid(&o->ringbuf, characteristic_uuid); diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index 52053045f852..d49034627820 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -459,7 +459,7 @@ void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uin void mp_bluetooth_gattc_on_primary_service_result(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, mp_obj_bluetooth_uuid_t *service_uuid); // Notify modbluetooth that a characteristic was found (either by discover-all-on-service, or discover-by-uuid-on-service). -void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t def_handle, uint16_t value_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid); +void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t value_handle, uint16_t end_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid); // Notify modbluetooth that a descriptor was found. void mp_bluetooth_gattc_on_descriptor_result(uint16_t conn_handle, uint16_t handle, mp_obj_bluetooth_uuid_t *descriptor_uuid); diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index c26c09e61a2c..b0194446bd4b 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -1310,15 +1310,51 @@ int mp_bluetooth_gattc_discover_primary_services(uint16_t conn_handle, const mp_ return ble_hs_err_to_errno(err); } +STATIC bool match_char_uuid(const mp_obj_bluetooth_uuid_t *filter_uuid, const ble_uuid_any_t *result_uuid) { + if (!filter_uuid) { + return true; + } + ble_uuid_any_t filter_uuid_nimble; + create_nimble_uuid(filter_uuid, &filter_uuid_nimble); + return ble_uuid_cmp(&result_uuid->u, &filter_uuid_nimble.u) == 0; +} + STATIC int ble_gattc_characteristic_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *characteristic, void *arg) { DEBUG_printf("ble_gattc_characteristic_cb: conn_handle=%d status=%d def_handle=%d val_handle=%d\n", conn_handle, error->status, characteristic ? characteristic->def_handle : -1, characteristic ? characteristic->val_handle : -1); if (!mp_bluetooth_is_active()) { return 0; } + + mp_bluetooth_nimble_pending_characteristic_t *pending = &MP_STATE_PORT(bluetooth_nimble_root_pointers)->pending_char_result; + if (pending->ready) { + // If there's a pending characteristic, we now know what it's end handle is, report it up to modbluetooth. + pending->ready = 0; + + // The end handle will either be the end of the query range (there are + // no more results), or one before the current result's definition + // handle. + uint16_t end_handle = MP_STATE_PORT(bluetooth_nimble_root_pointers)->char_disc_end_handle; + if (error->status == 0) { + end_handle = characteristic->def_handle - 1; + } + + // Assume same conn_handle because we're limiting to a single active discovery. + mp_bluetooth_gattc_on_characteristic_result(conn_handle, pending->value_handle, end_handle, pending->properties, &pending->uuid); + } + if (error->status == 0) { - mp_obj_bluetooth_uuid_t characteristic_uuid = create_mp_uuid(&characteristic->uuid); - mp_bluetooth_gattc_on_characteristic_result(conn_handle, characteristic->def_handle, characteristic->val_handle, characteristic->properties, &characteristic_uuid); + // If there's no filter, or the filter matches, then save this result. + if (match_char_uuid(MP_STATE_PORT(bluetooth_nimble_root_pointers)->char_filter_uuid, &characteristic->uuid)) { + pending->value_handle = characteristic->val_handle; + pending->properties = characteristic->properties; + pending->uuid = create_mp_uuid(&characteristic->uuid); + pending->ready = 1; + } } else { + // Finished (or failed). Allow another characteristic discovery to start. + MP_STATE_PORT(bluetooth_nimble_root_pointers)->char_disc_end_handle = 0; + + // Report completion. mp_bluetooth_gattc_on_discover_complete(MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_DONE, conn_handle, error->status == BLE_HS_EDONE ? 0 : error->status); } return 0; @@ -1328,13 +1364,29 @@ int mp_bluetooth_gattc_discover_characteristics(uint16_t conn_handle, uint16_t s if (!mp_bluetooth_is_active()) { return ERRNO_BLUETOOTH_NOT_ACTIVE; } - int err; - if (uuid) { - ble_uuid_any_t nimble_uuid; - create_nimble_uuid(uuid, &nimble_uuid); - err = ble_gattc_disc_chrs_by_uuid(conn_handle, start_handle, end_handle, &nimble_uuid.u, &ble_gattc_characteristic_cb, NULL); - } else { - err = ble_gattc_disc_all_chrs(conn_handle, start_handle, end_handle, &ble_gattc_characteristic_cb, NULL); + + // The implementation of characteristic discovery queries for all + // characteristics, and then UUID filtering is applied by NimBLE on each + // characteristic. Unfortunately, each characteristic result does not + // include its end handle, so you need to know the next characteristic + // before you can raise the previous one to modbluetooth. But if we let + // NimBLE do the filtering, then we don't necessarily see the next one. + // So we make NimBLE return all results and do the filtering here instead. + + if (MP_STATE_PORT(bluetooth_nimble_root_pointers)->char_disc_end_handle) { + // Only allow a single discovery (otherwise we'd need to track a + // pending characteristic per conn handle). + return MP_EBUSY; + } + + // Set the uuid filter (if any). This needs to be a root pointer, + // otherwise we'd use ble_gattc_disc_all_chrs's arg param. + MP_STATE_PORT(bluetooth_nimble_root_pointers)->char_filter_uuid = uuid; + + int err = ble_gattc_disc_all_chrs(conn_handle, start_handle, end_handle, &ble_gattc_characteristic_cb, NULL); + if (!err) { + // Lock out concurrent characteristic discovery. + MP_STATE_PORT(bluetooth_nimble_root_pointers)->char_disc_end_handle = end_handle; } return ble_hs_err_to_errno(err); } diff --git a/extmod/nimble/modbluetooth_nimble.h b/extmod/nimble/modbluetooth_nimble.h index 15648a9959a6..d9bef649201c 100644 --- a/extmod/nimble/modbluetooth_nimble.h +++ b/extmod/nimble/modbluetooth_nimble.h @@ -31,6 +31,13 @@ #define MP_BLUETOOTH_NIMBLE_MAX_SERVICES (8) +typedef struct _mp_bluetooth_nimble_pending_characteristic_t { + uint16_t value_handle; + uint8_t properties; + mp_obj_bluetooth_uuid_t uuid; + uint8_t ready; +} mp_bluetooth_nimble_pending_characteristic_t; + typedef struct _mp_bluetooth_nimble_root_pointers_t { // Characteristic (and descriptor) value storage. mp_gatts_db_t gatts_db; @@ -44,6 +51,14 @@ typedef struct _mp_bluetooth_nimble_root_pointers_t { struct _mp_bluetooth_nimble_l2cap_channel_t *l2cap_chan; bool l2cap_listening; #endif + + #if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT + // Workaround to allow us to get the end_handle of each characteristic + // during discovery. See mp_bluetooth_gattc_discover_characteristics(). + uint16_t char_disc_end_handle; + const mp_obj_bluetooth_uuid_t *char_filter_uuid; + mp_bluetooth_nimble_pending_characteristic_t pending_char_result; + #endif } mp_bluetooth_nimble_root_pointers_t; enum { From 1d4228ccc1f4b6760007a8370d75a3ae3339c801 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Sep 2022 14:14:31 +1000 Subject: [PATCH 1714/4290] zephyr/boards: Add config for bbc_microbit_v2. This enables the bluetooth module. GAP scanning and advertising works. Signed-off-by: Damien George --- ports/zephyr/boards/bbc_microbit_v2.conf | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 ports/zephyr/boards/bbc_microbit_v2.conf diff --git a/ports/zephyr/boards/bbc_microbit_v2.conf b/ports/zephyr/boards/bbc_microbit_v2.conf new file mode 100644 index 000000000000..31872244ca71 --- /dev/null +++ b/ports/zephyr/boards/bbc_microbit_v2.conf @@ -0,0 +1,8 @@ +CONFIG_CONSOLE_SUBSYS=n +CONFIG_NETWORKING=n +CONFIG_BT=y +CONFIG_BT_DEVICE_NAME_DYNAMIC=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y + +CONFIG_MICROPY_HEAP_SIZE=98304 From 4903e48e340bd9741577f30cacb31605cc70cf20 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 9 Sep 2022 18:12:55 +1000 Subject: [PATCH 1715/4290] tools/makemanifest.py: Force the repo version of the mpy_cross package. In case the version from pypi is installed or some other version is available in sys.path, prepend `$(TOP)/mpy-cross` to sys.path instead. Signed-off-by: Jim Mussared --- tools/makemanifest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/makemanifest.py b/tools/makemanifest.py index d059d4a2660f..9dd8815aac5f 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -29,7 +29,8 @@ import os import subprocess -sys.path.append(os.path.join(os.path.dirname(__file__), "../mpy-cross")) +# Always use the mpy-cross from this repo. +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../mpy-cross")) import mpy_cross import manifestfile From 582b3e4e7864809e30eac694251600f61db52a3c Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 9 Sep 2022 09:48:01 +1000 Subject: [PATCH 1716/4290] py/objpolyiter: Add a new polyiter type with finaliser support. --- py/obj.h | 3 +++ py/objpolyiter.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/py/obj.h b/py/obj.h index e048cf0c286a..894983028225 100644 --- a/py/obj.h +++ b/py/obj.h @@ -677,6 +677,9 @@ extern const mp_obj_type_t mp_type_stringio; extern const mp_obj_type_t mp_type_bytesio; extern const mp_obj_type_t mp_type_reversed; extern const mp_obj_type_t mp_type_polymorph_iter; +#if MICROPY_ENABLE_FINALISER +extern const mp_obj_type_t mp_type_polymorph_iter_with_finaliser; +#endif // Exceptions extern const mp_obj_type_t mp_type_BaseException; diff --git a/py/objpolyiter.c b/py/objpolyiter.c index 01880bff9c1b..16fd1f486c15 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -51,3 +51,37 @@ const mp_obj_type_t mp_type_polymorph_iter = { .getiter = mp_identity_getiter, .iternext = polymorph_it_iternext, }; + +#if MICROPY_ENABLE_FINALISER +// mp_type_polymorph_iter_with_finaliser is a variant of the universal iterator +// above which has a finaliser function attached. This function will be run when +// the GC collects the iter object and can be used to close file handles etc. + +// Any instance should have these 3 fields at the beginning +typedef struct _mp_obj_polymorph_iter_with_finaliser_t { + mp_obj_base_t base; + mp_fun_1_t iternext; + mp_fun_1_t finaliser; +} mp_obj_polymorph_with_finaliser_iter_t; + +STATIC mp_obj_t mp_obj_polymorph_iter_del(mp_obj_t self_in) { + mp_obj_polymorph_with_finaliser_iter_t *self = MP_OBJ_TO_PTR(self_in); + // Redirect call to object instance's iternext method + return self->finaliser(self_in); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_polymorph_iter_del_obj, mp_obj_polymorph_iter_del); + +STATIC const mp_rom_map_elem_t mp_obj_polymorph_iter_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_obj_polymorph_iter_del_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_obj_polymorph_iter_locals_dict, mp_obj_polymorph_iter_locals_dict_table); + +const mp_obj_type_t mp_type_polymorph_iter_with_finaliser = { + { &mp_type_type }, + .name = MP_QSTR_iterator, + .getiter = mp_identity_getiter, + .iternext = polymorph_it_iternext, + .locals_dict = (mp_obj_dict_t *)&mp_obj_polymorph_iter_locals_dict, +}; + +#endif From 4e0964b59f44b25ebaa5239f9ea4273b804ebe64 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 9 Sep 2022 09:48:01 +1000 Subject: [PATCH 1717/4290] extmod/vfs: Add finaliser to ilistdir to close directory handle. When iterating over filesystem/folders with os.iterdir(), an open file (directory) handle is used internally. Currently this file handle is only closed once the iterator is completely drained, eg. once all entries have been looped over / converted into list etc. If a program opens an iterdir but does not loop over it, or starts to loop over the iterator but breaks out of the loop, then the handle never gets closed. In this state, when the iter object is cleaned up by the garbage collector this open handle can cause corruption of the filesystem. Fixes issues #6568 and #8506. --- extmod/vfs_fat.c | 16 ++++- extmod/vfs_lfsx.c | 25 +++++++- extmod/vfs_posix.c | 19 +++++- tests/extmod/vfs_fat_ilistdir_del.py | 75 ++++++++++++++++++++++ tests/extmod/vfs_fat_ilistdir_del.py.exp | 30 +++++++++ tests/extmod/vfs_lfs_ilistdir_del.py | 75 ++++++++++++++++++++++ tests/extmod/vfs_lfs_ilistdir_del.py.exp | 30 +++++++++ tests/extmod/vfs_posix_ilistdir_del.py | 70 ++++++++++++++++++++ tests/extmod/vfs_posix_ilistdir_del.py.exp | 30 +++++++++ tools/ci.sh | 4 +- 10 files changed, 368 insertions(+), 6 deletions(-) create mode 100644 tests/extmod/vfs_fat_ilistdir_del.py create mode 100644 tests/extmod/vfs_fat_ilistdir_del.py.exp create mode 100644 tests/extmod/vfs_lfs_ilistdir_del.py create mode 100644 tests/extmod/vfs_lfs_ilistdir_del.py.exp create mode 100644 tests/extmod/vfs_posix_ilistdir_del.py create mode 100644 tests/extmod/vfs_posix_ilistdir_del.py.exp diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 27681ca77012..7d8b51efeb61 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -28,6 +28,10 @@ #include "py/mpconfig.h" #if MICROPY_VFS_FAT +#if !MICROPY_ENABLE_FINALISER +#error "MICROPY_VFS_FAT requires MICROPY_ENABLE_FINALISER" +#endif + #if !MICROPY_VFS #error "with MICROPY_VFS_FAT enabled, must also enable MICROPY_VFS" #endif @@ -118,6 +122,7 @@ STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(fat_vfs_mkfs_obj, MP_ROM_PTR(&fat_vfs_mk typedef struct _mp_vfs_fat_ilistdir_it_t { mp_obj_base_t base; mp_fun_1_t iternext; + mp_fun_1_t finaliser; bool is_str; FF_DIR dir; } mp_vfs_fat_ilistdir_it_t; @@ -162,6 +167,13 @@ STATIC mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) { return MP_OBJ_STOP_ITERATION; } +STATIC mp_obj_t mp_vfs_fat_ilistdir_it_del(mp_obj_t self_in) { + mp_vfs_fat_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); + // ignore result / error because we may be closing a second time. + f_closedir(&self->dir); + return mp_const_none; +} + STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(args[0]); bool is_str_type = true; @@ -176,8 +188,10 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) { } // Create a new iterator object to list the dir - mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter); + mp_vfs_fat_ilistdir_it_t *iter = m_new_obj_with_finaliser(mp_vfs_fat_ilistdir_it_t); + iter->base.type = &mp_type_polymorph_iter_with_finaliser; iter->iternext = mp_vfs_fat_ilistdir_it_iternext; + iter->finaliser = mp_vfs_fat_ilistdir_it_del; iter->is_str = is_str_type; FRESULT res = f_opendir(&self->fatfs, &iter->dir, path); if (res != FR_OK) { diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index dbd32338cfd9..fbfeaa5ccf1a 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -36,6 +36,10 @@ #include "extmod/vfs.h" #include "shared/timeutils/timeutils.h" +#if !MICROPY_ENABLE_FINALISER +#error "MICROPY_VFS_LFS requires MICROPY_ENABLE_FINALISER" +#endif + STATIC int MP_VFS_LFSx(dev_ioctl)(const struct LFSx_API (config) * c, int cmd, int arg, bool must_return_int) { mp_obj_t ret = mp_vfs_blockdev_ioctl(c->context, cmd, arg); int ret_i = 0; @@ -155,6 +159,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(MP_VFS_LFSx(open_obj), MP_VFS_LFSx(file_open)); typedef struct MP_VFS_LFSx (_ilistdir_it_t) { mp_obj_base_t base; mp_fun_1_t iternext; + mp_fun_1_t finaliser; bool is_str; MP_OBJ_VFS_LFSx *vfs; LFSx_API(dir_t) dir; @@ -163,11 +168,16 @@ typedef struct MP_VFS_LFSx (_ilistdir_it_t) { STATIC mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) { MP_VFS_LFSx(ilistdir_it_t) * self = MP_OBJ_TO_PTR(self_in); + if (self->vfs == NULL) { + return MP_OBJ_STOP_ITERATION; + } + struct LFSx_API (info) info; for (;;) { int ret = LFSx_API(dir_read)(&self->vfs->lfs, &self->dir, &info); if (ret == 0) { LFSx_API(dir_close)(&self->vfs->lfs, &self->dir); + self->vfs = NULL; return MP_OBJ_STOP_ITERATION; } if (!(info.name[0] == '.' && (info.name[1] == '\0' @@ -190,6 +200,14 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) { return MP_OBJ_FROM_PTR(t); } +STATIC mp_obj_t MP_VFS_LFSx(ilistdir_it_del)(mp_obj_t self_in) { + MP_VFS_LFSx(ilistdir_it_t) * self = MP_OBJ_TO_PTR(self_in); + if (self->vfs != NULL) { + LFSx_API(dir_close)(&self->vfs->lfs, &self->dir); + } + return mp_const_none; +} + STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args) { MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(args[0]); bool is_str_type = true; @@ -203,14 +221,17 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args) path = vstr_null_terminated_str(&self->cur_dir); } - MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter); + MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj_with_finaliser(MP_VFS_LFSx(ilistdir_it_t)); + iter->base.type = &mp_type_polymorph_iter_with_finaliser; + iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext); + iter->finaliser = MP_VFS_LFSx(ilistdir_it_del); iter->is_str = is_str_type; - iter->vfs = self; int ret = LFSx_API(dir_open)(&self->lfs, &iter->dir, path); if (ret < 0) { mp_raise_OSError(-ret); } + iter->vfs = self; return MP_OBJ_FROM_PTR(iter); } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(MP_VFS_LFSx(ilistdir_obj), 1, 2, MP_VFS_LFSx(ilistdir_func)); diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 9b00365817a1..36b211b84d6b 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -33,6 +33,10 @@ #if MICROPY_VFS_POSIX +#if !MICROPY_ENABLE_FINALISER +#error "MICROPY_VFS_POSIX requires MICROPY_ENABLE_FINALISER" +#endif + #include #include #include @@ -162,6 +166,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd); typedef struct _vfs_posix_ilistdir_it_t { mp_obj_base_t base; mp_fun_1_t iternext; + mp_fun_1_t finaliser; bool is_str; DIR *dir; } vfs_posix_ilistdir_it_t; @@ -226,10 +231,22 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) { } } +STATIC mp_obj_t vfs_posix_ilistdir_it_del(mp_obj_t self_in) { + vfs_posix_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); + if (self->dir != NULL) { + MP_THREAD_GIL_EXIT(); + closedir(self->dir); + MP_THREAD_GIL_ENTER(); + } + return mp_const_none; +} + STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); - vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter); + vfs_posix_ilistdir_it_t *iter = m_new_obj_with_finaliser(vfs_posix_ilistdir_it_t); + iter->base.type = &mp_type_polymorph_iter_with_finaliser; iter->iternext = vfs_posix_ilistdir_it_iternext; + iter->finaliser = vfs_posix_ilistdir_it_del; iter->is_str = mp_obj_get_type(path_in) == &mp_type_str; const char *path = vfs_posix_get_path_str(self, path_in); if (path[0] == '\0') { diff --git a/tests/extmod/vfs_fat_ilistdir_del.py b/tests/extmod/vfs_fat_ilistdir_del.py new file mode 100644 index 000000000000..a833e9ac128c --- /dev/null +++ b/tests/extmod/vfs_fat_ilistdir_del.py @@ -0,0 +1,75 @@ +# Test ilistdir __del__ for VfsFat using a RAM device. +import gc + +try: + import uos + + uos.VfsFat +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 4096 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off=0): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off=0): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + def ioctl(self, op, arg): + if op == 4: # block count + return len(self.data) // self.ERASE_BLOCK_SIZE + if op == 5: # block size + return self.ERASE_BLOCK_SIZE + if op == 6: # erase block + return 0 + + +def test(bdev, vfs_class): + vfs_class.mkfs(bdev) + vfs = vfs_class(bdev) + vfs.mkdir("/test_d1") + vfs.mkdir("/test_d2") + vfs.mkdir("/test_d3") + + for i in range(10): + print(i) + + # We want to partially iterate the ilistdir iterator to leave it in an + # open state, which will then test the finaliser when it's garbage collected. + idir = vfs.ilistdir("/") + print(any(idir)) + + # Alternate way of partially iterating the ilistdir object, modifying the + # filesystem while it's open. + for dname, *_ in vfs.ilistdir("/"): + vfs.rmdir(dname) + break + vfs.mkdir(dname) + + # Also create a fully drained iterator and ensure trying to re-use it + # throws the correct exception. + idir_emptied = vfs.ilistdir("/") + l = list(idir_emptied) + print(len(l)) + try: + next(idir_emptied) + except StopIteration: + pass + + gc.collect() + vfs.open("/test", "w").close() + + +bdev = RAMBlockDevice(30) +test(bdev, uos.VfsFat) diff --git a/tests/extmod/vfs_fat_ilistdir_del.py.exp b/tests/extmod/vfs_fat_ilistdir_del.py.exp new file mode 100644 index 000000000000..0ab2b019f4b6 --- /dev/null +++ b/tests/extmod/vfs_fat_ilistdir_del.py.exp @@ -0,0 +1,30 @@ +0 +True +3 +1 +True +4 +2 +True +4 +3 +True +4 +4 +True +4 +5 +True +4 +6 +True +4 +7 +True +4 +8 +True +4 +9 +True +4 diff --git a/tests/extmod/vfs_lfs_ilistdir_del.py b/tests/extmod/vfs_lfs_ilistdir_del.py new file mode 100644 index 000000000000..073576986d3a --- /dev/null +++ b/tests/extmod/vfs_lfs_ilistdir_del.py @@ -0,0 +1,75 @@ +# Test ilistdir __del__ for VfsLittle using a RAM device. +import gc + +try: + import uos + + uos.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 1024 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + def ioctl(self, op, arg): + if op == 4: # block count + return len(self.data) // self.ERASE_BLOCK_SIZE + if op == 5: # block size + return self.ERASE_BLOCK_SIZE + if op == 6: # erase block + return 0 + + +def test(bdev, vfs_class): + vfs_class.mkfs(bdev) + vfs = vfs_class(bdev) + vfs.mkdir("/test_d1") + vfs.mkdir("/test_d2") + vfs.mkdir("/test_d3") + + for i in range(10): + print(i) + + # We want to partially iterate the ilistdir iterator to leave it in an + # open state, which will then test the finaliser when it's garbage collected. + idir = vfs.ilistdir("/") + print(any(idir)) + + # Alternate way of partially iterating the ilistdir object, modifying the + # filesystem while it's open. + for dname, *_ in vfs.ilistdir("/"): + vfs.rmdir(dname) + break + vfs.mkdir(dname) + + # Also create a fully drained iterator and ensure trying to re-use it + # throws the correct exception. + idir_emptied = vfs.ilistdir("/") + l = list(idir_emptied) + print(len(l)) + try: + next(idir_emptied) + except StopIteration: + pass + + gc.collect() + vfs.open("/test", "w").close() + + +bdev = RAMBlockDevice(30) +test(bdev, uos.VfsLfs2) diff --git a/tests/extmod/vfs_lfs_ilistdir_del.py.exp b/tests/extmod/vfs_lfs_ilistdir_del.py.exp new file mode 100644 index 000000000000..0ab2b019f4b6 --- /dev/null +++ b/tests/extmod/vfs_lfs_ilistdir_del.py.exp @@ -0,0 +1,30 @@ +0 +True +3 +1 +True +4 +2 +True +4 +3 +True +4 +4 +True +4 +5 +True +4 +6 +True +4 +7 +True +4 +8 +True +4 +9 +True +4 diff --git a/tests/extmod/vfs_posix_ilistdir_del.py b/tests/extmod/vfs_posix_ilistdir_del.py new file mode 100644 index 000000000000..edb50dfd6229 --- /dev/null +++ b/tests/extmod/vfs_posix_ilistdir_del.py @@ -0,0 +1,70 @@ +# Test ilistdir __del__ for VfsPosix. +import gc + +try: + import os + + os.VfsPosix +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + + +def test(testdir): + vfs = os.VfsPosix(testdir) + vfs.mkdir("/test_d1") + vfs.mkdir("/test_d2") + vfs.mkdir("/test_d3") + + for i in range(10): + print(i) + + # We want to partially iterate the ilistdir iterator to leave it in an + # open state, which will then test the finaliser when it's garbage collected. + idir = vfs.ilistdir("/") + print(any(idir)) + + # Alternate way of partially iterating the ilistdir object, modifying the + # filesystem while it's open. + for dname, *_ in vfs.ilistdir("/"): + vfs.rmdir(dname) + break + vfs.mkdir(dname) + + # Also create a fully drained iterator and ensure trying to re-use it + # throws the correct exception. + idir_emptied = vfs.ilistdir("/") + l = list(idir_emptied) + print(len(l)) + try: + next(idir_emptied) + except StopIteration: + pass + + gc.collect() + + # Create and delete a file, try to flush out any filesystem + # corruption that may be caused over the loops. + vfs.open("/test", "w").close() + vfs.remove("/test") + + +# We need an empty directory for testing. +# Skip the test if it already exists. +temp_dir = "vfs_posix_ilistdir_del_test_dir" +try: + os.stat(temp_dir) + print("SKIP") + raise SystemExit +except OSError: + pass + +os.mkdir(temp_dir) + +test(temp_dir) + +# Remove tempdir. +for td in os.listdir(temp_dir): + os.rmdir("/".join((temp_dir, td))) + +os.rmdir(temp_dir) diff --git a/tests/extmod/vfs_posix_ilistdir_del.py.exp b/tests/extmod/vfs_posix_ilistdir_del.py.exp new file mode 100644 index 000000000000..c30ba4132686 --- /dev/null +++ b/tests/extmod/vfs_posix_ilistdir_del.py.exp @@ -0,0 +1,30 @@ +0 +True +3 +1 +True +3 +2 +True +3 +3 +True +3 +4 +True +3 +5 +True +3 +6 +True +3 +7 +True +3 +8 +True +3 +9 +True +3 diff --git a/tools/ci.sh b/tools/ci.sh index b4cb7dc2e380..8f1d729a1326 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -632,7 +632,7 @@ function ci_unix_qemu_mips_run_tests { # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) # - ffi tests do not work file ./ports/unix/build-coverage/micropython - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.*\.py' --exclude 'ffi_(callback|float|float2).py') } function ci_unix_qemu_arm_setup { @@ -652,7 +652,7 @@ function ci_unix_qemu_arm_run_tests { # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi file ./ports/unix/build-coverage/micropython - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.*\.py') } ######################################################################################## From 86676a43aa9de47bfdf52c7a71751de1bb512c64 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Mon, 12 Sep 2022 08:41:39 +1000 Subject: [PATCH 1718/4290] unix/mpconfigport: Enable MICROPY_ENABLE_FINALISER when VFS is used. --- ports/unix/mpconfigport.h | 2 +- ports/unix/variants/minimal/mpconfigvariant.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index dd73f61e24ba..cb389d9a5362 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -45,7 +45,6 @@ #ifndef MICROPY_OPT_MAP_LOOKUP_CACHE #define MICROPY_OPT_MAP_LOOKUP_CACHE (1) #endif -#define MICROPY_ENABLE_FINALISER (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_KBD_EXCEPTION (1) #define MICROPY_HELPER_REPL (1) @@ -124,6 +123,7 @@ #ifndef MICROPY_GC_SPLIT_HEAP_N_HEAPS #define MICROPY_GC_SPLIT_HEAP_N_HEAPS (1) #endif +#define MICROPY_ENABLE_FINALISER (1) #define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) #define MICROPY_MEM_STATS (1) #define MICROPY_DEBUG_PRINTERS (1) diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 2e2c1de0cc87..d9d2a6c48e64 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -37,8 +37,8 @@ #define MICROPY_ALLOC_PARSE_CHUNK_INIT (64) #define MICROPY_ALLOC_PATH_MAX (PATH_MAX) #define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_FINALISER (1) #define MICROPY_GC_ALLOC_THRESHOLD (0) -#define MICROPY_ENABLE_FINALISER (0) #define MICROPY_STACK_CHECK (0) #define MICROPY_COMP_CONST (0) #define MICROPY_MEM_STATS (0) From afc7e1d298add00eacf38be0ae9455f0f09aed2e Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Mon, 12 Sep 2022 08:45:56 +1000 Subject: [PATCH 1719/4290] zephyr/mpconfigport: Enable MICROPY_ENABLE_FINALISER when VFS is used. --- ports/zephyr/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/zephyr/mpconfigport.h b/ports/zephyr/mpconfigport.h index 4c8096b44107..71836768a44c 100644 --- a/ports/zephyr/mpconfigport.h +++ b/ports/zephyr/mpconfigport.h @@ -39,6 +39,7 @@ #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_FINALISER (MICROPY_VFS) #define MICROPY_HELPER_REPL (1) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_KBD_EXCEPTION (1) From 2d4e7e99bfcfaaed252564f9498176ca3ad88fee Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Mon, 12 Sep 2022 08:47:02 +1000 Subject: [PATCH 1720/4290] samd/mpconfigport: Enable MICROPY_ENABLE_FINALISER when VFS is used. --- ports/samd/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 0b16b5e817af..2c6052149ba3 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -41,6 +41,7 @@ // Python internal features #define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_FINALISER (1) #define MICROPY_KBD_EXCEPTION (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) From 57fd66b80f8352e4859e6b71536b6083f9d7279c Mon Sep 17 00:00:00 2001 From: Wind-stormger Date: Tue, 30 Aug 2022 11:30:12 +0800 Subject: [PATCH 1721/4290] tools/pyboard.py: Support Windows pathname separators. Addresses issue #9132. --- tools/pyboard.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 436bc5ab1be5..60cc06508ebe 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -582,12 +582,12 @@ def fname_remote(src): return src def fname_cp_dest(src, dest): - src = src.rsplit("/", 1)[-1] + _, src = os.path.split(src) if dest is None or dest == "": dest = src elif dest == ".": - dest = "./" + src - elif dest.endswith("/"): + dest = os.path.join(".", src) + elif dest.endswith(os.path.sep): dest += src return dest From 89a0fefb6c5c730a7b740cf31e44a6c76c3993b1 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 13 Sep 2022 14:57:24 +1000 Subject: [PATCH 1722/4290] py/mpconfig: Add LFS1/LFS2 options to match FAT/posix. Also fixes the #ifndef for FAT & posix. Signed-off-by: Jim Mussared --- py/mpconfig.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index d478c654d021..b8cc61b2adb1 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -920,15 +920,25 @@ typedef double mp_float_t; #endif // Support for VFS POSIX component, to mount a POSIX filesystem within VFS -#ifndef MICROPY_VFS +#ifndef MICROPY_VFS_POSIX #define MICROPY_VFS_POSIX (0) #endif // Support for VFS FAT component, to mount a FAT filesystem within VFS -#ifndef MICROPY_VFS +#ifndef MICROPY_VFS_FAT #define MICROPY_VFS_FAT (0) #endif +// Support for VFS LittleFS v1 component, to mount a LFSv1 filesystem within VFS +#ifndef MICROPY_VFS_LFS1 +#define MICROPY_VFS_LFS1 (0) +#endif + +// Support for VFS LittleFS v2 component, to mount a LFSv2 filesystem within VFS +#ifndef MICROPY_VFS_LFS2 +#define MICROPY_VFS_LFS2 (0) +#endif + /*****************************************************************************/ /* Fine control over Python builtins, classes, modules, etc */ From 605266ee9a1258003032abb2fbfa58ef354ded25 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 16 Aug 2022 01:28:31 +1000 Subject: [PATCH 1723/4290] py/mpconfig: Make feature levels available to mpconfigport.h. Signed-off-by: Jim Mussared --- py/mpconfig.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index b8cc61b2adb1..5da7e453ecac 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -56,12 +56,6 @@ // release vs debug configs, etc. Note that if you switch from one config // to another, you must rebuild from scratch using "-B" switch to make. -#ifdef MP_CONFIGFILE -#include MP_CONFIGFILE -#else -#include -#endif - // Disable all optional features (i.e. minimal port). #define MICROPY_CONFIG_ROM_LEVEL_MINIMUM (0) // Only enable core features (constrained flash, e.g. STM32L072) @@ -75,6 +69,12 @@ // Enable everything (e.g. coverage) #define MICROPY_CONFIG_ROM_LEVEL_EVERYTHING (50) +#ifdef MP_CONFIGFILE +#include MP_CONFIGFILE +#else +#include +#endif + // Ports/boards should set this, but default to level=core. #ifndef MICROPY_CONFIG_ROM_LEVEL #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES) From f4fed02537e5b1b1a06912c8339c47ce500d18c6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 15 Aug 2022 11:56:03 +1000 Subject: [PATCH 1724/4290] unix/variants: Remove freedos and fast variants. The freedos variant is untested by CI and is difficult to maintain. The fast variant is not a good name for what it does. Signed-off-by: Jim Mussared --- ports/unix/variants/fast/mpconfigvariant.h | 34 ----------------- ports/unix/variants/fast/mpconfigvariant.mk | 5 --- ports/unix/variants/freedos/mpconfigvariant.h | 38 ------------------- .../unix/variants/freedos/mpconfigvariant.mk | 18 --------- 4 files changed, 95 deletions(-) delete mode 100644 ports/unix/variants/fast/mpconfigvariant.h delete mode 100644 ports/unix/variants/fast/mpconfigvariant.mk delete mode 100644 ports/unix/variants/freedos/mpconfigvariant.h delete mode 100644 ports/unix/variants/freedos/mpconfigvariant.mk diff --git a/ports/unix/variants/fast/mpconfigvariant.h b/ports/unix/variants/fast/mpconfigvariant.h deleted file mode 100644 index 8a531b056ab7..000000000000 --- a/ports/unix/variants/fast/mpconfigvariant.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This config file is intended to configure artificially fast uPy build for -// synthetic benchmarking, at the expense of features supported and memory -// usage. This config is not intended to be used in production. - -#define MICROPY_PY___FILE__ (0) -// 91 is a magic number proposed by @dpgeorge, which make pystone run ~ at tie -// with CPython 3.4. -#define MICROPY_MODULE_DICT_SIZE (91) diff --git a/ports/unix/variants/fast/mpconfigvariant.mk b/ports/unix/variants/fast/mpconfigvariant.mk deleted file mode 100644 index b8fe69e48731..000000000000 --- a/ports/unix/variants/fast/mpconfigvariant.mk +++ /dev/null @@ -1,5 +0,0 @@ -# build synthetically fast interpreter for benchmarking - -COPT += -fno-crossjumping -O2 - -FROZEN_MANIFEST = diff --git a/ports/unix/variants/freedos/mpconfigvariant.h b/ports/unix/variants/freedos/mpconfigvariant.h deleted file mode 100644 index 562c783ca35f..000000000000 --- a/ports/unix/variants/freedos/mpconfigvariant.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2015 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// options to control how MicroPython is built - -#define MICROPY_PY_USELECT_POSIX (0) - -#define MICROPY_STREAMS_NON_BLOCK (0) - -#define MICROPY_PY_SYS_PLATFORM "freedos" - -// djgpp dirent struct does not have d_ino field -#undef _DIRENT_HAVE_D_INO - -#define MICROPY_USE_INTERNAL_ERRNO (1) diff --git a/ports/unix/variants/freedos/mpconfigvariant.mk b/ports/unix/variants/freedos/mpconfigvariant.mk deleted file mode 100644 index 86ab6864f45c..000000000000 --- a/ports/unix/variants/freedos/mpconfigvariant.mk +++ /dev/null @@ -1,18 +0,0 @@ -CC = i586-pc-msdosdjgpp-gcc - -STRIP = i586-pc-msdosdjgpp-strip - -SIZE = i586-pc-msdosdjgpp-size - -CFLAGS += \ - -DMICROPY_NLR_SETJMP \ - -Dtgamma=gamma \ - -DMICROPY_EMIT_X86=0 \ - -DMICROPY_NO_ALLOCA=1 \ - -MICROPY_PY_SOCKET = 0 -MICROPY_PY_FFI = 0 -MICROPY_PY_JNI = 0 -MICROPY_PY_BTREE = 0 -MICROPY_PY_THREAD = 0 -MICROPY_PY_USSL = 0 From c1530a0ce8e83811f88fbd4558ea7aaf27919ed8 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 15 Aug 2022 13:58:34 +1000 Subject: [PATCH 1725/4290] unix: Refactor mpconfigport.h and mpconfigvariant.h. This is a no-op for coverage and minimal. The standard and dev variants have been merged and enable the same feature set as a typical bare-metal board. And remove the CI for the dev build. Signed-off-by: Jim Mussared --- .github/workflows/ports_unix.yml | 12 - ports/unix/main.c | 5 + ports/unix/mpconfigport.h | 283 ++++++------------ .../unix/variants/coverage/mpconfigvariant.h | 5 +- ports/unix/variants/dev/mpconfigvariant.h | 40 --- ports/unix/variants/dev/mpconfigvariant.mk | 8 - ports/unix/variants/minimal/mpconfigvariant.h | 135 ++------- ports/unix/variants/mpconfigvariant_common.h | 124 ++++++++ ports/unix/variants/nanbox/mpconfigvariant.h | 5 + .../variants/{dev => standard}/manifest.py | 0 .../unix/variants/standard/mpconfigvariant.h | 17 +- .../unix/variants/standard/mpconfigvariant.mk | 7 + tools/ci.sh | 10 - 13 files changed, 268 insertions(+), 383 deletions(-) delete mode 100644 ports/unix/variants/dev/mpconfigvariant.h delete mode 100644 ports/unix/variants/dev/mpconfigvariant.mk create mode 100644 ports/unix/variants/mpconfigvariant_common.h rename ports/unix/variants/{dev => standard}/manifest.py (100%) diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index 45cc87e72394..3b738634a67f 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -49,18 +49,6 @@ jobs: if: failure() run: tests/run-tests.py --print-failures - dev: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build - run: source tools/ci.sh && ci_unix_dev_build - - name: Run main test suite - run: source tools/ci.sh && ci_unix_dev_run_tests - - name: Print failures - if: failure() - run: tests/run-tests.py --print-failures - coverage: runs-on: ubuntu-latest steps: diff --git a/ports/unix/main.c b/ports/unix/main.c index c388106a645e..4f019b6c2c30 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -63,6 +63,11 @@ STATIC uint emit_opt = MP_EMIT_OPT_NONE; long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4); #endif +// Number of heaps to assign by default if MICROPY_GC_SPLIT_HEAP=1 +#ifndef MICROPY_GC_SPLIT_HEAP_N_HEAPS +#define MICROPY_GC_SPLIT_HEAP_N_HEAPS (1) +#endif + STATIC void stderr_print_strn(void *env, const char *str, size_t len) { (void)env; ssize_t ret; diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index cb389d9a5362..08ddd21f63ba 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -24,85 +24,36 @@ * THE SOFTWARE. */ -// Options to control how MicroPython is built for this port, -// overriding defaults in py/mpconfig.h. +// Options to control how MicroPython is built for this port, overriding +// defaults in py/mpconfig.h. This file is mostly about configuring the +// features to work on Unix-like systems, see mpconfigvariant.h (and +// mpconfigvariant_common.h) for feature enabling. + +// For size_t and ssize_t +#include // Variant-specific definitions. #include "mpconfigvariant.h" -// The minimal variant's config covers everything. -// If we're building the minimal variant, ignore the rest of this file. -#ifndef MICROPY_UNIX_MINIMAL - -// If the variant did not set a feature level then configure a set of features. #ifndef MICROPY_CONFIG_ROM_LEVEL -#define MICROPY_COMP_MODULE_CONST (1) -#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) -#define MICROPY_COMP_RETURN_IF_EXPR (1) -#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH -#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) -#endif -#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE -#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES) #endif -#define MICROPY_STACK_CHECK (1) -#define MICROPY_KBD_EXCEPTION (1) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_REPL_EMACS_KEYS (1) -#define MICROPY_REPL_AUTO_INDENT (1) -#define MICROPY_ENABLE_SOURCE_LINE (1) -#ifndef MICROPY_STREAMS_NON_BLOCK -#define MICROPY_STREAMS_NON_BLOCK (1) + +#ifndef MICROPY_PY_SYS_PLATFORM +#if defined(__APPLE__) && defined(__MACH__) + #define MICROPY_PY_SYS_PLATFORM "darwin" +#else + #define MICROPY_PY_SYS_PLATFORM "linux" #endif -#define MICROPY_MODULE_WEAK_LINKS (1) -#define MICROPY_CAN_OVERRIDE_BUILTINS (1) -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_DESCRIPTORS (1) -#define MICROPY_PY_DELATTR_SETATTR (1) -#define MICROPY_PY_FSTRINGS (1) -#define MICROPY_PY_BUILTINS_BYTES_HEX (1) -#define MICROPY_PY_BUILTINS_STR_UNICODE (1) -#define MICROPY_PY_BUILTINS_STR_CENTER (1) -#define MICROPY_PY_BUILTINS_STR_PARTITION (1) -#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) -#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) -#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) -#define MICROPY_PY_BUILTINS_SLICE_INDICES (1) -#define MICROPY_PY_BUILTINS_FROZENSET (1) -#define MICROPY_PY_BUILTINS_ROUND_INT (1) -#define MICROPY_PY_ALL_SPECIAL_METHODS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_BUILTINS_COMPILE (1) -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_BUILTINS_INPUT (1) -#define MICROPY_PY_BUILTINS_POW3 (1) -#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) -#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) -#define MICROPY_PY_COLLECTIONS_DEQUE (1) -#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) -#ifndef MICROPY_PY_MATH_SPECIAL_FUNCTIONS -#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) #endif -#define MICROPY_PY_MATH_ISCLOSE (MICROPY_PY_MATH_SPECIAL_FUNCTIONS) -#define MICROPY_PY_CMATH (1) -#define MICROPY_PY_IO_IOBASE (1) -#define MICROPY_PY_SYS_MAXSIZE (1) -#define MICROPY_PY_SYS_STDFILES (1) -#define MICROPY_PY_UERRNO (1) -#define MICROPY_PY_UCTYPES (1) -#define MICROPY_PY_UZLIB (1) -#define MICROPY_PY_UJSON (1) -#define MICROPY_PY_UOS (1) -#define MICROPY_PY_URE (1) -#define MICROPY_PY_UHEAPQ (1) -#define MICROPY_PY_UHASHLIB (1) -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UBINASCII_CRC32 (1) -#define MICROPY_PY_URANDOM (1) + +#ifndef MICROPY_PY_SYS_PATH_DEFAULT +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" #endif -#define MICROPY_ALLOC_PATH_MAX (PATH_MAX) -#define MICROPY_PERSISTENT_CODE_LOAD (1) +#define MP_STATE_PORT MP_STATE_VM + +// Configure which emitter to use for this target. #if !defined(MICROPY_EMIT_X64) && defined(__x86_64__) #define MICROPY_EMIT_X64 (1) #endif @@ -118,83 +69,75 @@ #if !defined(MICROPY_EMIT_ARM) && defined(__arm__) && !defined(__thumb2__) #define MICROPY_EMIT_ARM (1) #endif -#define MICROPY_ENABLE_GC (1) -// Number of heaps to assign if MICROPY_GC_SPLIT_HEAP=1 -#ifndef MICROPY_GC_SPLIT_HEAP_N_HEAPS -#define MICROPY_GC_SPLIT_HEAP_N_HEAPS (1) -#endif -#define MICROPY_ENABLE_FINALISER (1) -#define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) -#define MICROPY_MEM_STATS (1) -#define MICROPY_DEBUG_PRINTERS (1) -// Printing debug to stderr may give tests which -// check stdout a chance to pass, etc. -#define MICROPY_DEBUG_PRINTER (&mp_stderr_print) -#define MICROPY_READER_POSIX (1) -#define MICROPY_READER_VFS (1) -#define MICROPY_USE_READLINE_HISTORY (1) -#ifndef MICROPY_READLINE_HISTORY_SIZE -#define MICROPY_READLINE_HISTORY_SIZE 50 + +// Type definitions for the specific machine based on the word size. +#ifndef MICROPY_OBJ_REPR +#ifdef __LP64__ +typedef long mp_int_t; // must be pointer size +typedef unsigned long mp_uint_t; // must be pointer size +#else +// These are definitions for machines where sizeof(int) == sizeof(void*), +// regardless of actual size. +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size #endif -#define MICROPY_HELPER_LEXER_UNIX (1) -#ifndef MICROPY_FLOAT_IMPL -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) +#else +// Assume that if we already defined the obj repr then we also defined types. #endif -#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) -#define MICROPY_STREAMS_POSIX_API (1) -#define MICROPY_OPT_COMPUTED_GOTO (1) -#define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1) -#define MICROPY_VFS (1) -#define MICROPY_VFS_POSIX (1) -#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) -#define MICROPY_PY_SYS_EXIT (1) -#define MICROPY_PY_SYS_ATEXIT (1) -#if MICROPY_PY_SYS_SETTRACE -#define MICROPY_PERSISTENT_CODE_SAVE (1) -#define MICROPY_COMP_CONST (0) + +// Cannot include , as it may lead to symbol name clashes +#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__) +typedef long long mp_off_t; +#else +typedef long mp_off_t; #endif -#ifndef MICROPY_PY_SYS_PLATFORM -#if defined(__APPLE__) && defined(__MACH__) - #define MICROPY_PY_SYS_PLATFORM "darwin" + +// We need to provide a declaration/definition of alloca() +// unless support for it is disabled. +#if !defined(MICROPY_NO_ALLOCA) || MICROPY_NO_ALLOCA == 0 +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include #else - #define MICROPY_PY_SYS_PLATFORM "linux" +#include #endif #endif -#ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" + +// Always enable GC. +#define MICROPY_ENABLE_GC (1) + +#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) +// Fall back to setjmp() implementation for discovery of GC pointers in registers. +#define MICROPY_GCREGS_SETJMP (1) #endif -#define MICROPY_PY_SYS_EXC_INFO (1) -#define MICROPY_PY_GC_COLLECT_RETVAL (1) +// Enable the VFS, and enable the posix "filesystem". +#define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_VFS (1) +#define MICROPY_READER_VFS (1) +#define MICROPY_HELPER_LEXER_UNIX (1) +#define MICROPY_VFS_POSIX (1) +#define MICROPY_READER_POSIX (1) + +// VFS stat functions should return time values relative to 1970/1/1 +#define MICROPY_EPOCH_IS_1970 (1) + +// Assume that select() call, interrupted with a signal, and erroring +// with EINTR, updates remaining timeout value. +#define MICROPY_SELECT_REMAINING_TIME (1) + +// Disable stackless by default. #ifndef MICROPY_STACKLESS #define MICROPY_STACKLESS (0) #define MICROPY_STACKLESS_STRICT (0) #endif -#define MICROPY_PY_UOS_INCLUDEFILE "ports/unix/moduos.c" -#define MICROPY_PY_UOS_ERRNO (1) -#define MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV (1) -#define MICROPY_PY_UOS_SEP (1) -#define MICROPY_PY_UOS_SYSTEM (1) -#define MICROPY_PY_UOS_URANDOM (1) -#define MICROPY_PY_UTIME (1) -#define MICROPY_PY_UTIME_MP_HAL (1) -#define MICROPY_PY_UTIMEQ (1) -#define MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128) -#if MICROPY_PY_USSL -#define MICROPY_PY_UHASHLIB_MD5 (1) -#define MICROPY_PY_UHASHLIB_SHA1 (1) -#define MICROPY_PY_UCRYPTOLIB (1) -#endif -#ifndef MICROPY_PY_USELECT -#define MICROPY_PY_USELECT (0) -#endif -#ifndef MICROPY_PY_USELECT_POSIX -#define MICROPY_PY_USELECT_POSIX (!MICROPY_PY_USELECT) +// If settrace is enabled then we need code saving. +#if MICROPY_PY_SYS_SETTRACE +#define MICROPY_PERSISTENT_CODE_SAVE (1) +#define MICROPY_COMP_CONST (0) #endif -#define MICROPY_PY_UWEBSOCKET (1) -#define MICROPY_PY_MACHINE (1) -#define MICROPY_PY_MACHINE_PULSE (1) + +// Unix-specific configuration of machine.mem*. #define MICROPY_MACHINE_MEM_GET_READ_ADDR mod_machine_mem_get_addr #define MICROPY_MACHINE_MEM_GET_WRITE_ADDR mod_machine_mem_get_addr @@ -203,52 +146,23 @@ #define MICROPY_FATFS_MAX_SS (4096) #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ -// Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc. -// names in exception messages (may require more RAM). -#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED) -#define MICROPY_WARNINGS (1) -#define MICROPY_ERROR_PRINTER (&mp_stderr_print) -#define MICROPY_PY_STR_BYTES_CMP_WARN (1) - -// VFS stat functions should return time values relative to 1970/1/1 -#define MICROPY_EPOCH_IS_1970 (1) - -extern const struct _mp_print_t mp_stderr_print; - -#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) -// Fall back to setjmp() implementation for discovery of GC pointers in registers. -#define MICROPY_GCREGS_SETJMP (1) -#endif - -#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) -#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256) -#define MICROPY_ASYNC_KBD_INTR (1) +#define MICROPY_ALLOC_PATH_MAX (PATH_MAX) -// type definitions for the specific machine +// Ensure builtinimport.c works with -m. +#define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1) -// For size_t and ssize_t -#include +// Don't default sys.argv because we do that in main. +#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) -// assume that if we already defined the obj repr then we also defined types -#ifndef MICROPY_OBJ_REPR -#ifdef __LP64__ -typedef long mp_int_t; // must be pointer size -typedef unsigned long mp_uint_t; // must be pointer size -#else -// These are definitions for machines where sizeof(int) == sizeof(void*), -// regardless of actual size. -typedef int mp_int_t; // must be pointer size -typedef unsigned int mp_uint_t; // must be pointer size -#endif -#endif +#define MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128) -// Cannot include , as it may lead to symbol name clashes -#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__) -typedef long long mp_off_t; -#else -typedef long mp_off_t; -#endif +// Bare-metal ports don't have stderr. Printing debug to stderr may give tests +// which check stdout a chance to pass, etc. +extern const struct _mp_print_t mp_stderr_print; +#define MICROPY_DEBUG_PRINTER (&mp_stderr_print) +#define MICROPY_ERROR_PRINTER (&mp_stderr_print) +// For the native emitter configure how to mark a region as executable. void mp_unix_alloc_exec(size_t min_size, void **ptr, size_t *size); void mp_unix_free_exec(void *ptr, size_t size); void mp_unix_mark_exec(void); @@ -260,8 +174,8 @@ void mp_unix_mark_exec(void); #define MICROPY_FORCE_PLAT_ALLOC_EXEC (1) #endif +// If enabled, configure how to seed random on init. #ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC -// Support for seeding the random module on import. #include void mp_hal_get_random(size_t n, void *buf); static inline unsigned long mp_urandom_seed_init(void) { @@ -276,10 +190,6 @@ static inline unsigned long mp_urandom_seed_init(void) { #define MICROPY_PLAT_DEV_MEM (1) #endif -// Assume that select() call, interrupted with a signal, and erroring -// with EINTR, updates remaining timeout value. -#define MICROPY_SELECT_REMAINING_TIME (1) - #ifdef __ANDROID__ #include #if __ANDROID_API__ < 4 @@ -289,18 +199,6 @@ static inline unsigned long mp_urandom_seed_init(void) { #endif #endif -#define MP_STATE_PORT MP_STATE_VM - -// We need to provide a declaration/definition of alloca() -// unless support for it is disabled. -#if !defined(MICROPY_NO_ALLOCA) || MICROPY_NO_ALLOCA == 0 -#if defined(__FreeBSD__) || defined(__NetBSD__) -#include -#else -#include -#endif -#endif - // From "man readdir": "Under glibc, programs can check for the availability // of the fields [in struct dirent] not defined in POSIX.1 by testing whether // the macros [...], _DIRENT_HAVE_D_TYPE are defined." @@ -320,11 +218,13 @@ static inline unsigned long mp_urandom_seed_init(void) { #include #endif +// If threading is enabled, configure the atomic section. #if MICROPY_PY_THREAD #define MICROPY_BEGIN_ATOMIC_SECTION() (mp_thread_unix_begin_atomic_section(), 0xffffffff) #define MICROPY_END_ATOMIC_SECTION(x) (void)x; mp_thread_unix_end_atomic_section() #endif +// In lieu of a WFI(), slow down polling from being a tight loop. #ifndef MICROPY_EVENT_POLL_HOOK #define MICROPY_EVENT_POLL_HOOK \ do { \ @@ -334,7 +234,6 @@ static inline unsigned long mp_urandom_seed_init(void) { } while (0); #endif +// Configure the implementation of machine.idle(). #include #define MICROPY_UNIX_MACHINE_IDLE sched_yield(); - -#endif // MICROPY_UNIX_MINIMAL diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index fb70d791ac9b..9857c668748a 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -30,6 +30,9 @@ // Set base feature level. #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EVERYTHING) +// Enable extra Unix features. +#include "../mpconfigvariant_common.h" + // Enable additional features. #define MICROPY_DEBUG_PARSE_RULE_NAME (1) #define MICROPY_GC_SPLIT_HEAP (1) @@ -45,11 +48,9 @@ #define MICROPY_PY_BUILTINS_RANGE_BINOP (1) #define MICROPY_PY_SYS_GETSIZEOF (1) #define MICROPY_PY_IO_BUFFEREDWRITER (1) -#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (mp_urandom_seed_init()) #define MICROPY_PY_URE_DEBUG (1) #define MICROPY_PY_URE_MATCH_GROUPS (1) #define MICROPY_PY_URE_MATCH_SPAN_START_END (1) #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1) -#define MICROPY_PY_UCRYPTOLIB (1) #define MICROPY_PY_UCRYPTOLIB_CTR (1) #define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1) diff --git a/ports/unix/variants/dev/mpconfigvariant.h b/ports/unix/variants/dev/mpconfigvariant.h deleted file mode 100644 index 2522f1861fdc..000000000000 --- a/ports/unix/variants/dev/mpconfigvariant.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2019 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Set base feature level. -#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) - -// Enable some additional features. -#ifndef MICROPY_REPL_EMACS_WORDS_MOVE -#define MICROPY_REPL_EMACS_WORDS_MOVE (1) -#endif -#ifndef MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE -#define MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE (1) -#endif -#ifndef MICROPY_PY_SYS_SETTRACE -#define MICROPY_PY_SYS_SETTRACE (1) -#endif -#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (mp_urandom_seed_init()) diff --git a/ports/unix/variants/dev/mpconfigvariant.mk b/ports/unix/variants/dev/mpconfigvariant.mk deleted file mode 100644 index 058eda2f8d19..000000000000 --- a/ports/unix/variants/dev/mpconfigvariant.mk +++ /dev/null @@ -1,8 +0,0 @@ -FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py - -MICROPY_ROM_TEXT_COMPRESSION = 1 -MICROPY_VFS_FAT ?= 1 -MICROPY_VFS_LFS1 ?= 1 -MICROPY_VFS_LFS2 ?= 1 - -MICROPY_PY_BLUETOOTH ?= 1 diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index d9d2a6c48e64..6b107e77909c 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -26,117 +26,44 @@ // options to control how MicroPython is built -// Prevent the rest of the default mpconfigport.h being used. -#define MICROPY_UNIX_MINIMAL (1) +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM) +// Disable native emitters. +#define MICROPY_EMIT_X86 (0) +#define MICROPY_EMIT_X64 (0) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_ARM (0) + +// Tune the parser to use less RAM by default. #define MICROPY_ALLOC_QSTR_CHUNK_INIT (64) #define MICROPY_ALLOC_PARSE_RULE_INIT (8) #define MICROPY_ALLOC_PARSE_RULE_INC (8) #define MICROPY_ALLOC_PARSE_RESULT_INIT (8) #define MICROPY_ALLOC_PARSE_RESULT_INC (8) #define MICROPY_ALLOC_PARSE_CHUNK_INIT (64) -#define MICROPY_ALLOC_PATH_MAX (PATH_MAX) -#define MICROPY_ENABLE_GC (1) -#define MICROPY_ENABLE_FINALISER (1) -#define MICROPY_GC_ALLOC_THRESHOLD (0) -#define MICROPY_STACK_CHECK (0) -#define MICROPY_COMP_CONST (0) -#define MICROPY_MEM_STATS (0) -#define MICROPY_DEBUG_PRINTERS (0) -#define MICROPY_READER_POSIX (1) -#define MICROPY_READER_VFS (1) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_HELPER_LEXER_UNIX (1) -#define MICROPY_ENABLE_SOURCE_LINE (0) -#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) -#define MICROPY_WARNINGS (0) -#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0) -#define MICROPY_KBD_EXCEPTION (1) -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) -#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) -#define MICROPY_STREAMS_NON_BLOCK (0) -#define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (0) -#define MICROPY_OPT_MAP_LOOKUP_CACHE (0) -#define MICROPY_CAN_OVERRIDE_BUILTINS (0) -#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) -#define MICROPY_VFS (1) -#define MICROPY_VFS_POSIX (1) -#define MICROPY_CPYTHON_COMPAT (0) -#define MICROPY_PY_BUILTINS_BYTEARRAY (0) -#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) -#define MICROPY_PY_BUILTINS_COMPILE (0) -#define MICROPY_PY_BUILTINS_ENUMERATE (0) -#define MICROPY_PY_BUILTINS_FILTER (0) -#define MICROPY_PY_BUILTINS_FROZENSET (0) -#define MICROPY_PY_BUILTINS_REVERSED (0) -#define MICROPY_PY_BUILTINS_SET (0) -#define MICROPY_PY_BUILTINS_SLICE (0) -#define MICROPY_PY_BUILTINS_STR_COUNT (0) -#define MICROPY_PY_BUILTINS_STR_OP_MODULO (0) -#define MICROPY_PY_BUILTINS_STR_UNICODE (0) -#define MICROPY_PY_BUILTINS_PROPERTY (0) -#define MICROPY_PY_BUILTINS_MIN_MAX (0) -#define MICROPY_PY___FILE__ (0) -#define MICROPY_PY_MICROPYTHON_MEM_INFO (0) -#define MICROPY_PY_GC (0) -#define MICROPY_PY_GC_COLLECT_RETVAL (0) -#define MICROPY_PY_ARRAY (0) -#define MICROPY_PY_COLLECTIONS (0) -#define MICROPY_PY_MATH (0) -#define MICROPY_PY_CMATH (0) -#define MICROPY_PY_IO (0) -#define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_SYS (1) -#define MICROPY_PY_SYS_EXIT (0) -#define MICROPY_PY_SYS_PLATFORM "linux" -#ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" -#endif -#define MICROPY_PY_SYS_MAXSIZE (0) -#define MICROPY_PY_SYS_STDFILES (0) -#define MICROPY_PY_CMATH (0) -#define MICROPY_PY_UCTYPES (0) -#define MICROPY_PY_UTIME (0) -#define MICROPY_PY_UZLIB (0) -#define MICROPY_PY_UJSON (0) -#define MICROPY_PY_UOS (1) -#define MICROPY_PY_URE (0) -#define MICROPY_PY_UHEAPQ (0) -#define MICROPY_PY_UHASHLIB (0) -#define MICROPY_PY_UBINASCII (0) - -////////////////////////////////////////// -// Do not change anything beyond this line -////////////////////////////////////////// - -#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) -// Fall back to setjmp() implementation for discovery of GC pointers in registers. -#define MICROPY_GCREGS_SETJMP (1) -#endif - -// type definitions for the specific machine -#ifdef __LP64__ -typedef long mp_int_t; // must be pointer size -typedef unsigned long mp_uint_t; // must be pointer size -#else -// These are definitions for machines where sizeof(int) == sizeof(void*), -// regardless for actual size. -typedef int mp_int_t; // must be pointer size -typedef unsigned int mp_uint_t; // must be pointer size -#endif +// Enable features that are not enabled by default with the minimum config. +#define MICROPY_COMP_CONST_FOLDING (1) +#define MICROPY_COMP_CONST_LITERAL (1) +#define MICROPY_COMP_CONST_TUPLE (1) +#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1) +#define MICROPY_ENABLE_COMPILER (1) +#define MICROPY_ENABLE_EXTERNAL_IMPORT (1) +#define MICROPY_FULL_CHECKS (1) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_KBD_EXCEPTION (1) +#define MICROPY_MODULE_GETATTR (1) +#define MICROPY_MULTIPLE_INHERITANCE (1) +#define MICROPY_PY_ASSIGN_EXPR (1) +#define MICROPY_PY_ASYNC_AWAIT (1) +#define MICROPY_PY_ATTRTUPLE (1) +#define MICROPY_PY_BUILTINS_DICT_FROMKEYS (1) +#define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) +#define MICROPY_PY_GENERATOR_PEND_THROW (1) -// Cannot include , as it may lead to symbol name clashes -#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__) -typedef long long mp_off_t; -#else -typedef long mp_off_t; -#endif +// Enable just the sys and os built-in modules. +#define MICROPY_PY_SYS (1) +#define MICROPY_PY_UOS (1) -// We need to provide a declaration/definition of alloca() -#ifdef __FreeBSD__ -#include -#else -#include -#endif +// The minimum sets this to 1 to save flash. +#define MICROPY_QSTR_BYTES_IN_HASH (2) diff --git a/ports/unix/variants/mpconfigvariant_common.h b/ports/unix/variants/mpconfigvariant_common.h new file mode 100644 index 000000000000..1128f21d22ec --- /dev/null +++ b/ports/unix/variants/mpconfigvariant_common.h @@ -0,0 +1,124 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jim Mussared + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// This file enables and configures features common to all variants +// other than "minimal". + +// Send raise KeyboardInterrupt directly from the signal handler rather than +// scheduling it into the VM. +#define MICROPY_ASYNC_KBD_INTR (1) + +// Enable helpers for printing debugging information. +#ifndef MICROPY_DEBUG_PRINTERS +#define MICROPY_DEBUG_PRINTERS (1) +#endif + +// Enable floating point by default. +#ifndef MICROPY_FLOAT_IMPL +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) +#endif + +// Enable arbritrary precision long-int by default. +#ifndef MICROPY_LONGINT_IMPL +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) +#endif + +// Enable use of C libraries that need read/write/lseek/fsync, e.g. axtls. +#define MICROPY_STREAMS_POSIX_API (1) + +// REPL conveniences. +#define MICROPY_REPL_EMACS_WORDS_MOVE (1) +#define MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE (1) +#define MICROPY_USE_READLINE_HISTORY (1) +#ifndef MICROPY_READLINE_HISTORY_SIZE +#define MICROPY_READLINE_HISTORY_SIZE (50) +#endif + +// Seed random on import. +#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (mp_urandom_seed_init()) + +// Allow exception details in low-memory conditions. +#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) +#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256) + +// Allow loading of .mpy files. +#define MICROPY_PERSISTENT_CODE_LOAD (1) + +// Extra memory debugging. +#define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) +#define MICROPY_MEM_STATS (1) + +// Enable a small performance boost for the VM. +#define MICROPY_OPT_COMPUTED_GOTO (1) + +// Return number of collected objects from gc.collect(). +#define MICROPY_PY_GC_COLLECT_RETVAL (1) + +// Enable detailed error messages and warnings. +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED) +#define MICROPY_WARNINGS (1) +#define MICROPY_PY_STR_BYTES_CMP_WARN (1) + +// Configure the "sys" module with features not usually enabled on bare-metal. +#define MICROPY_PY_SYS_ATEXIT (1) +#define MICROPY_PY_SYS_EXC_INFO (1) + +// Configure the "os" module with extra unix features. +#define MICROPY_PY_UOS_INCLUDEFILE "ports/unix/moduos.c" +#define MICROPY_PY_UOS_ERRNO (1) +#define MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV (1) +#define MICROPY_PY_UOS_SEP (1) +#define MICROPY_PY_UOS_SYSTEM (1) +#define MICROPY_PY_UOS_URANDOM (1) + +// Enable the unix-specific "time" module. +#define MICROPY_PY_UTIME (1) +#define MICROPY_PY_UTIME_MP_HAL (1) + +// Enable the utimeq module used by the previous (v2) version of uasyncio. +#define MICROPY_PY_UTIMEQ (1) + +#if MICROPY_PY_USSL +#define MICROPY_PY_UHASHLIB_MD5 (1) +#define MICROPY_PY_UHASHLIB_SHA1 (1) +#define MICROPY_PY_UCRYPTOLIB (1) +#endif + +// Use the posix implementation of the "select" module (unless the variant +// specifically asks for the MicroPython version). +#ifndef MICROPY_PY_USELECT +#define MICROPY_PY_USELECT (0) +#endif +#ifndef MICROPY_PY_USELECT_POSIX +#define MICROPY_PY_USELECT_POSIX (!MICROPY_PY_USELECT) +#endif + +// Enable the "websocket" module. +#define MICROPY_PY_UWEBSOCKET (1) + +// Enable the "machine" module, mostly for machine.mem*. +#define MICROPY_PY_MACHINE (1) +#define MICROPY_PY_MACHINE_PULSE (1) diff --git a/ports/unix/variants/nanbox/mpconfigvariant.h b/ports/unix/variants/nanbox/mpconfigvariant.h index f827158fb712..7b13b7dc6ce4 100644 --- a/ports/unix/variants/nanbox/mpconfigvariant.h +++ b/ports/unix/variants/nanbox/mpconfigvariant.h @@ -28,6 +28,11 @@ // continues to build (i.e. catches usage of mp_obj_t that don't work with // this representation). +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) + +// Enable extra Unix features. +#include "../mpconfigvariant_common.h" + // select nan-boxing object model #define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_D) diff --git a/ports/unix/variants/dev/manifest.py b/ports/unix/variants/standard/manifest.py similarity index 100% rename from ports/unix/variants/dev/manifest.py rename to ports/unix/variants/standard/manifest.py diff --git a/ports/unix/variants/standard/mpconfigvariant.h b/ports/unix/variants/standard/mpconfigvariant.h index 31618652e961..75201e9abc8d 100644 --- a/ports/unix/variants/standard/mpconfigvariant.h +++ b/ports/unix/variants/standard/mpconfigvariant.h @@ -27,18 +27,5 @@ // Set base feature level. #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) -// Disable some features that come enabled by default with the feature level. -#define MICROPY_OPT_MPZ_BITWISE (0) -#define MICROPY_OPT_MATH_FACTORIAL (0) -#define MICROPY_MODULE_ATTR_DELEGATION (0) -#define MICROPY_MODULE_BUILTIN_INIT (0) -#define MICROPY_ENABLE_SCHEDULER (0) -#define MICROPY_PY_BUILTINS_EXECFILE (0) -#define MICROPY_PY_MATH_CONSTANTS (0) -#define MICROPY_PY_MATH_FACTORIAL (0) -#define MICROPY_PY_SYS_PS1_PS2 (0) -#define MICROPY_PY_SYS_STDIO_BUFFER (0) -#define MICROPY_PY_UASYNCIO (0) -#define MICROPY_PY_URE_SUB (0) -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) -#define MICROPY_PY_FRAMEBUF (0) +// Enable extra Unix features. +#include "../mpconfigvariant_common.h" diff --git a/ports/unix/variants/standard/mpconfigvariant.mk b/ports/unix/variants/standard/mpconfigvariant.mk index def7987d8dc8..929a1aec117d 100644 --- a/ports/unix/variants/standard/mpconfigvariant.mk +++ b/ports/unix/variants/standard/mpconfigvariant.mk @@ -1 +1,8 @@ # This is the default variant when you `make` the Unix port. + +FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py + +MICROPY_ROM_TEXT_COMPRESSION = 1 +MICROPY_VFS_FAT ?= 1 +MICROPY_VFS_LFS1 ?= 1 +MICROPY_VFS_LFS2 ?= 1 diff --git a/tools/ci.sh b/tools/ci.sh index 8f1d729a1326..9c670b7be5ea 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -454,14 +454,6 @@ function ci_unix_standard_run_tests { ci_unix_run_tests_full_helper standard } -function ci_unix_dev_build { - ci_unix_build_helper VARIANT=dev -} - -function ci_unix_dev_run_tests { - ci_unix_run_tests_helper VARIANT=dev -} - function ci_unix_coverage_setup { sudo pip3 install setuptools sudo pip3 install pyelftools @@ -602,8 +594,6 @@ function ci_unix_macos_build { #make ${MAKEOPTS} -C ports/unix deplibs make ${MAKEOPTS} -C ports/unix # check for additional compiler errors/warnings - make ${MAKEOPTS} -C ports/unix VARIANT=dev submodules - make ${MAKEOPTS} -C ports/unix VARIANT=dev make ${MAKEOPTS} -C ports/unix VARIANT=coverage submodules make ${MAKEOPTS} -C ports/unix VARIANT=coverage } From 3e5b1be8cad9cc38af9af30f5e7fa3582f65ffd9 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 16 Aug 2022 01:41:03 +1000 Subject: [PATCH 1726/4290] py/mpconfig: Add "everything" features from unix coverage. Signed-off-by: Jim Mussared --- .../unix/variants/coverage/mpconfigvariant.h | 20 +++---------- py/mpconfig.h | 28 +++++++++---------- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index 9857c668748a..6107a4a55625 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -33,24 +33,12 @@ // Enable extra Unix features. #include "../mpconfigvariant_common.h" -// Enable additional features. -#define MICROPY_DEBUG_PARSE_RULE_NAME (1) +// Enable testing of split heap. #define MICROPY_GC_SPLIT_HEAP (1) #define MICROPY_GC_SPLIT_HEAP_N_HEAPS (4) + +// Enable additional features. +#define MICROPY_DEBUG_PARSE_RULE_NAME (1) #define MICROPY_TRACKED_ALLOC (1) -#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1) -#define MICROPY_REPL_EMACS_WORDS_MOVE (1) -#define MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE (1) #define MICROPY_WARNINGS_CATEGORY (1) -#define MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS (1) -#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (1) -#define MICROPY_PY_BUILTINS_NEXT2 (1) -#define MICROPY_PY_BUILTINS_RANGE_BINOP (1) -#define MICROPY_PY_SYS_GETSIZEOF (1) -#define MICROPY_PY_IO_BUFFEREDWRITER (1) -#define MICROPY_PY_URE_DEBUG (1) -#define MICROPY_PY_URE_MATCH_GROUPS (1) -#define MICROPY_PY_URE_MATCH_SPAN_START_END (1) -#define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1) #define MICROPY_PY_UCRYPTOLIB_CTR (1) -#define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1) diff --git a/py/mpconfig.h b/py/mpconfig.h index 5da7e453ecac..698d264d2e80 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -683,7 +683,7 @@ // This adds Alt+F, Alt+B, Alt+D and Alt+Backspace for forward-word, backward-word, forward-kill-word // and backward-kill-word, respectively. #ifndef MICROPY_REPL_EMACS_WORDS_MOVE -#define MICROPY_REPL_EMACS_WORDS_MOVE (0) +#define MICROPY_REPL_EMACS_WORDS_MOVE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to include extra convenience keys for word movement/kill in readline REPL. @@ -691,7 +691,7 @@ // respectively. Ctrl+Delete is not implemented because it's a very different escape sequence. // Depends on MICROPY_REPL_EMACS_WORDS_MOVE. #ifndef MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE -#define MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE (0) +#define MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to implement auto-indent in REPL @@ -802,7 +802,7 @@ typedef double mp_float_t; // Whether to provide a high-quality hash for float and complex numbers. // Otherwise the default is a very simple but correct hashing function. #ifndef MICROPY_FLOAT_HIGH_QUALITY_HASH -#define MICROPY_FLOAT_HIGH_QUALITY_HASH (0) +#define MICROPY_FLOAT_HIGH_QUALITY_HASH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Enable features which improve CPython compatibility @@ -1054,7 +1054,7 @@ typedef double mp_float_t; // Whether to support memoryview.itemsize attribute #ifndef MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE -#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to support set object @@ -1099,12 +1099,12 @@ typedef double mp_float_t; // the same object will compare as not-equal. With it enabled the semantics // match CPython and ranges are equal if they yield the same sequence of items. #ifndef MICROPY_PY_BUILTINS_RANGE_BINOP -#define MICROPY_PY_BUILTINS_RANGE_BINOP (0) +#define MICROPY_PY_BUILTINS_RANGE_BINOP (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Support for callling next() with second argument #ifndef MICROPY_PY_BUILTINS_NEXT2 -#define MICROPY_PY_BUILTINS_NEXT2 (0) +#define MICROPY_PY_BUILTINS_NEXT2 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to support rounding of integers (incl bignum); eg round(123,-1)=120 @@ -1124,7 +1124,7 @@ typedef double mp_float_t; // Whether to support all inplace arithmetic operarion methods // (__imul__, etc.) #ifndef MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS -#define MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS (0) +#define MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to support reverse arithmetic operarion methods @@ -1219,7 +1219,7 @@ typedef double mp_float_t; // Whether to provide the "micropython.heap_locked" function #ifndef MICROPY_PY_MICROPYTHON_HEAP_LOCKED -#define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (0) +#define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to provide "array" module. Note that large chunk of the @@ -1258,7 +1258,7 @@ typedef double mp_float_t; // Whether to provide the _asdict function for namedtuple #ifndef MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT -#define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (0) +#define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to provide "math" module @@ -1338,7 +1338,7 @@ typedef double mp_float_t; // Whether to provide "io.BufferedWriter" class #ifndef MICROPY_PY_IO_BUFFEREDWRITER -#define MICROPY_PY_IO_BUFFEREDWRITER (0) +#define MICROPY_PY_IO_BUFFEREDWRITER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to provide "struct" module @@ -1394,7 +1394,7 @@ typedef double mp_float_t; // Whether to provide "sys.getsizeof" function #ifndef MICROPY_PY_SYS_GETSIZEOF -#define MICROPY_PY_SYS_GETSIZEOF (0) +#define MICROPY_PY_SYS_GETSIZEOF (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif // Whether to provide sys.{stdin,stdout,stderr} objects @@ -1516,15 +1516,15 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_URE_DEBUG -#define MICROPY_PY_URE_DEBUG (0) +#define MICROPY_PY_URE_DEBUG (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif #ifndef MICROPY_PY_URE_MATCH_GROUPS -#define MICROPY_PY_URE_MATCH_GROUPS (0) +#define MICROPY_PY_URE_MATCH_GROUPS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif #ifndef MICROPY_PY_URE_MATCH_SPAN_START_END -#define MICROPY_PY_URE_MATCH_SPAN_START_END (0) +#define MICROPY_PY_URE_MATCH_SPAN_START_END (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif #ifndef MICROPY_PY_URE_SUB From 51b054dd66fcd4f26f965910ea25de85a2ea01a3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 16 Aug 2022 01:56:25 +1000 Subject: [PATCH 1727/4290] unix: Refactor mpconfigvariant.mk. All variants (except minimal) enable text compression and fat/lfs, so move them to the common mpconfigport.mk. Signed-off-by: Jim Mussared --- ports/unix/mpconfigport.mk | 6 ++++++ ports/unix/variants/coverage/mpconfigvariant.mk | 5 ----- ports/unix/variants/minimal/mpconfigvariant.mk | 5 ++++- ports/unix/variants/standard/mpconfigvariant.mk | 5 ----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ports/unix/mpconfigport.mk b/ports/unix/mpconfigport.mk index fe9eec18dc33..ce6183c13397 100644 --- a/ports/unix/mpconfigport.mk +++ b/ports/unix/mpconfigport.mk @@ -38,3 +38,9 @@ MICROPY_PY_JNI = 0 # Avoid using system libraries, use copies bundled with MicroPython # as submodules (currently affects only libffi). MICROPY_STANDALONE = 0 + +MICROPY_ROM_TEXT_COMPRESSION = 1 + +MICROPY_VFS_FAT = 1 +MICROPY_VFS_LFS1 = 1 +MICROPY_VFS_LFS2 = 1 diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index bbbb0432b5b7..cc37ba158247 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -12,10 +12,5 @@ LDFLAGS += -fprofile-arcs -ftest-coverage FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py USER_C_MODULES = $(TOP)/examples/usercmodule -MICROPY_ROM_TEXT_COMPRESSION = 1 -MICROPY_VFS_FAT = 1 -MICROPY_VFS_LFS1 = 1 -MICROPY_VFS_LFS2 = 1 - SRC_C += coverage.c SRC_CXX += coveragecpp.cpp diff --git a/ports/unix/variants/minimal/mpconfigvariant.mk b/ports/unix/variants/minimal/mpconfigvariant.mk index 9d4ddab9563e..d5c2a52e9ae6 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.mk +++ b/ports/unix/variants/minimal/mpconfigvariant.mk @@ -2,7 +2,6 @@ FROZEN_MANIFEST = -MICROPY_ROM_TEXT_COMPRESSION = 1 MICROPY_PY_BTREE = 0 MICROPY_PY_FFI = 0 MICROPY_PY_SOCKET = 0 @@ -10,3 +9,7 @@ MICROPY_PY_THREAD = 0 MICROPY_PY_TERMIOS = 0 MICROPY_PY_USSL = 0 MICROPY_USE_READLINE = 0 + +MICROPY_VFS_FAT = 0 +MICROPY_VFS_LFS1 = 0 +MICROPY_VFS_LFS2 = 0 diff --git a/ports/unix/variants/standard/mpconfigvariant.mk b/ports/unix/variants/standard/mpconfigvariant.mk index 929a1aec117d..c91db1aa10ff 100644 --- a/ports/unix/variants/standard/mpconfigvariant.mk +++ b/ports/unix/variants/standard/mpconfigvariant.mk @@ -1,8 +1,3 @@ # This is the default variant when you `make` the Unix port. FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py - -MICROPY_ROM_TEXT_COMPRESSION = 1 -MICROPY_VFS_FAT ?= 1 -MICROPY_VFS_LFS1 ?= 1 -MICROPY_VFS_LFS2 ?= 1 From 6c376a93067230b3b9d7d4adc1b804df18b12dcd Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 13 Sep 2022 16:40:34 +1000 Subject: [PATCH 1728/4290] tests/extmod/uasyncio_heaplock.py: Force SKIP on stackless. This is a latent issue that wasn't caught by CI because there was no configuration that had both stackless+uasyncio. The previous check to skip with stackless builds only worked when the bytecode emitter was used by default. Force the check to use the bytecode emitter. Signed-off-by: Jim Mussared --- tests/extmod/uasyncio_heaplock.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/extmod/uasyncio_heaplock.py b/tests/extmod/uasyncio_heaplock.py index a6b4a0819c0e..9c9487357a2e 100644 --- a/tests/extmod/uasyncio_heaplock.py +++ b/tests/extmod/uasyncio_heaplock.py @@ -8,11 +8,19 @@ # strict stackless builds can't call functions without allocating a frame on the heap try: - f = lambda: 0 + # force bytecode (in case we're running with emit=native) and verify + # that bytecode-calling-bytecode doesn't allocate + @micropython.bytecode + def f(x): + x and f(x - 1) + micropython.heap_lock() - f() + f(1) micropython.heap_unlock() except RuntimeError: + # RuntimeError (max recursion depth) not MemoryError because effectively + # the recursion depth is at the limit while the heap is locked with + # stackless print("SKIP") raise SystemExit From 65ce7d7ade17f7f9ac2c5fbb75ad5d28078f8490 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 17 Jul 2022 08:43:02 +0200 Subject: [PATCH 1729/4290] mimxrt/machine_uart: Drop a few commented lines about TX ring buffer. --- ports/mimxrt/machine_uart.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index 302244f7221f..1b0c0633345a 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -244,12 +244,6 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args LPUART_EnableTx(self->lpuart, false); self->lpuart->STAT |= 1 << LPUART_STAT_BRK13_SHIFT; LPUART_EnableTx(self->lpuart, true); - - // Allocate the TX ring buffer. Not used yet, but maybe later. - - // ringbuf_alloc(&(self->write_buffer), txbuf_len + 1); - // MP_STATE_PORT(rp2_uart_tx_buffer[uart_id]) = self->write_buffer.buf; - } return MP_OBJ_FROM_PTR(self); From 8e542251405d780f7aa0d6c9abaa30282dd360d5 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 25 Apr 2022 13:56:45 +0200 Subject: [PATCH 1730/4290] mimxrt: Format the firmware image to match the new teensy loader. The new teensy loader keeps the file system under certain conditions: - The file size is properly set in the file header. - The header version is 4.3 These changes are implemented here, requiring a backport of fsl_flexspi_nor_boot.c. There is still a problem with the command line version of the teensy loader, which fails on the first attempt. At the second attempt it works. The GUI version of the teensy loader is fine. --- ports/mimxrt/Makefile | 2 +- ports/mimxrt/boards/common.ld | 7 +- ports/mimxrt/hal/fsl_flexspi_nor_boot.c | 53 +++++++++++ ports/mimxrt/hal/fsl_flexspi_nor_boot.h | 114 ++++++++++++++++++++++++ 4 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 ports/mimxrt/hal/fsl_flexspi_nor_boot.c create mode 100644 ports/mimxrt/hal/fsl_flexspi_nor_boot.h diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 6312ecdd8f3e..6a18879ac583 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -128,7 +128,7 @@ SRC_HAL_IMX_C += \ $(MCU_DIR)/drivers/fsl_trng.c \ $(MCU_DIR)/drivers/fsl_wdog.c \ $(MCU_DIR)/system_$(MCU_SERIES).c \ - $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + hal/fsl_flexspi_nor_boot.c \ ifeq ($(MICROPY_HW_SDRAM_AVAIL),1) SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_semc.c diff --git a/ports/mimxrt/boards/common.ld b/ports/mimxrt/boards/common.ld index fbc99da3ddb0..3aaa14c83bf2 100644 --- a/ports/mimxrt/boards/common.ld +++ b/ports/mimxrt/boards/common.ld @@ -207,7 +207,7 @@ SECTIONS __ram_function_end__ = .; } > m_itcm - __NDATA_ROM = __DATA_ROM + (__ram_function_end__ - __data_start__); + __NDATA_ROM = __RAM_FUNCTIONS_ROM + (__ram_function_end__ - __ram_function_start__); .ncache.init : AT(__NDATA_ROM) { __noncachedata_start__ = .; /* create a global symbol at ncache data start */ @@ -223,7 +223,8 @@ SECTIONS __noncachedata_end__ = .; /* define a global symbol at ncache data end */ } > m_dtcm - __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); + __DATA_END = __NDATA_ROM + (__noncachedata_end__ - __noncachedata_start__); + __FLASH_DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); text_end = ORIGIN(m_text) + LENGTH(m_text); ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") @@ -262,6 +263,8 @@ SECTIONS . += STACK_SIZE; } > m_dtcm + _flashimagelen = __FLASH_DATA_END - flash_start; + /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_dtcm) + LENGTH(m_dtcm); __StackLimit = __StackTop - STACK_SIZE; diff --git a/ports/mimxrt/hal/fsl_flexspi_nor_boot.c b/ports/mimxrt/hal/fsl_flexspi_nor_boot.c new file mode 100644 index 000000000000..5786f37e7ab8 --- /dev/null +++ b/ports/mimxrt/hal/fsl_flexspi_nor_boot.c @@ -0,0 +1,53 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_flexspi_nor_boot.h" +extern unsigned long _flashimagelen; +extern unsigned long __etext; + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_device" +#endif + +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.ivt"))) +#elif defined(__ICCARM__) +#pragma location=".boot_hdr.ivt" +#endif + + +/************************************* + * IVT Data + *************************************/ +const ivt image_vector_table = { + IVT_HEADER, /* IVT Header */ + IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ + IVT_RSVD, /* Reserved = 0 */ + (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ + (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ + (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ + (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ + IVT_RSVD /* Reserved = 0 */ +}; + +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.boot_data"))) +#elif defined(__ICCARM__) +#pragma location=".boot_hdr.boot_data" +#endif +/************************************* + * Boot Data + *************************************/ +const BOOT_DATA_T boot_data = { + FLASH_BASE, /* boot start location */ + (uint32_t)&_flashimagelen, /* Image size */ + PLUGIN_FLAG, /* Plugin flag*/ + 0xFFFFFFFF /* empty - extra data word */ +}; +#endif diff --git a/ports/mimxrt/hal/fsl_flexspi_nor_boot.h b/ports/mimxrt/hal/fsl_flexspi_nor_boot.h new file mode 100644 index 000000000000..fbb8a574f3ea --- /dev/null +++ b/ports/mimxrt/hal/fsl_flexspi_nor_boot.h @@ -0,0 +1,114 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __FLEXSPI_NOR_BOOT_H__ +#define __FLEXSPI_NOR_BOOT_H__ + +#include +#include "board.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_DEVICE driver version 2.0.0. */ +#define FSL_XIP_DEVICE_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/************************************* + * IVT Data + *************************************/ +typedef struct _ivt_ { + /** @ref hdr with tag #HAB_TAG_IVT, length and HAB version fields + * (see @ref data) + */ + uint32_t hdr; + /** Absolute address of the first instruction to execute from the + * image + */ + uint32_t entry; + /** Reserved in this version of HAB: should be NULL. */ + uint32_t reserved1; + /** Absolute address of the image DCD: may be NULL. */ + uint32_t dcd; + /** Absolute address of the Boot Data: may be NULL, but not interpreted + * any further by HAB + */ + uint32_t boot_data; + /** Absolute address of the IVT.*/ + uint32_t self; + /** Absolute address of the image CSF.*/ + uint32_t csf; + /** Reserved in this version of HAB: should be zero. */ + uint32_t reserved2; +} ivt; + +#define IVT_MAJOR_VERSION 0x4 +#define IVT_MAJOR_VERSION_SHIFT 0x4 +#define IVT_MAJOR_VERSION_MASK 0xF +#define IVT_MINOR_VERSION 0x3 +#define IVT_MINOR_VERSION_SHIFT 0x0 +#define IVT_MINOR_VERSION_MASK 0xF + +#define IVT_VERSION(major, minor) \ + ((((major) & IVT_MAJOR_VERSION_MASK) << IVT_MAJOR_VERSION_SHIFT) | \ + (((minor) & IVT_MINOR_VERSION_MASK) << IVT_MINOR_VERSION_SHIFT)) + +/* IVT header */ +#define IVT_TAG_HEADER 0xD1 /**< Image Vector Table */ +#define IVT_SIZE 0x2000 +#define IVT_PAR IVT_VERSION(IVT_MAJOR_VERSION, IVT_MINOR_VERSION) +#define IVT_HEADER (IVT_TAG_HEADER | (IVT_SIZE << 8) | (IVT_PAR << 24)) + +/* Set resume entry */ +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +extern uint32_t __Vectors[]; +extern uint32_t Image$$RW_m_config_text$$Base[]; +#define IMAGE_ENTRY_ADDRESS ((uint32_t)__Vectors) +#define FLASH_BASE ((uint32_t)Image$$RW_m_config_text$$Base) +#elif defined(__MCUXPRESSO) +extern uint32_t __Vectors[]; +extern uint32_t __boot_hdr_start__[]; +#define IMAGE_ENTRY_ADDRESS ((uint32_t)__Vectors) +#define FLASH_BASE ((uint32_t)__boot_hdr_start__) +#elif defined(__ICCARM__) +extern uint32_t __VECTOR_TABLE[]; +extern uint32_t m_boot_hdr_conf_start[]; +#define IMAGE_ENTRY_ADDRESS ((uint32_t)__VECTOR_TABLE) +#define FLASH_BASE ((uint32_t)m_boot_hdr_conf_start) +#elif defined(__GNUC__) +extern uint32_t __VECTOR_TABLE[]; +extern uint32_t __FLASH_BASE[]; +#define IMAGE_ENTRY_ADDRESS ((uint32_t)__VECTOR_TABLE) +#define FLASH_BASE ((uint32_t)__FLASH_BASE) +#endif + +#define DCD_ADDRESS dcd_data +#define BOOT_DATA_ADDRESS &boot_data +#define CSF_ADDRESS 0 +#define IVT_RSVD (uint32_t)(0x00000000) + +/************************************* + * Boot Data + *************************************/ +typedef struct _boot_data_ { + uint32_t start; /* boot start location */ + uint32_t size; /* size */ + uint32_t plugin; /* plugin flag - 1 if downloaded application is plugin */ + uint32_t placeholder; /* placehoder to make even 0x10 size */ +}BOOT_DATA_T; + +#if defined(BOARD_FLASH_SIZE) +#define FLASH_SIZE BOARD_FLASH_SIZE +#else +#error "Please define macro BOARD_FLASH_SIZE" +#endif +#define PLUGIN_FLAG (uint32_t)0 + +/* External Variables */ +const BOOT_DATA_T boot_data; +extern const uint8_t dcd_data[]; + +#endif /* __FLEXSPI_NOR_BOOT_H__ */ From 0f048a5a2a4cb239784cd152c9cd3fa0deb86db7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 31 Jul 2022 11:09:57 +0200 Subject: [PATCH 1731/4290] mimxrt/machine_spi: Allow a setting of -1 for cs in the constructor. In that case, no Pin will be configured for the CS signal, even if it is internally still generated. That setting allows to use any pin for CS, which then must be controlled by the Python script. Also make the default cs=-1 to match other ports (software CS). --- docs/mimxrt/pinout.rst | 3 ++- docs/mimxrt/quickref.rst | 8 +++++++- ports/mimxrt/machine_spi.c | 13 ++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/mimxrt/pinout.rst b/docs/mimxrt/pinout.rst index b82c153fc3ea..ef53fa63bff2 100644 --- a/docs/mimxrt/pinout.rst +++ b/docs/mimxrt/pinout.rst @@ -322,7 +322,8 @@ Olimex RT1010Py - CS0/-/SDO/SDI/SCK SDCARD wi Seeed ARCH MIX J4_12/-/J4_14/J4_13/J4_15 J3_09/J3_05/J3_08_J3_11 ================= ========================= ======================= =============== -Pins denoted with (*) are by default not wired at the board. +Pins denoted with (*) are by default not wired at the board. The CS0 and CS1 signals +are enabled with the keyword option cs=0 or cs=1 of the SPI object constructor. .. _mimxrt_i2c_pinout: diff --git a/docs/mimxrt/quickref.rst b/docs/mimxrt/quickref.rst index 0a14c632aafe..c75fe60c8d66 100644 --- a/docs/mimxrt/quickref.rst +++ b/docs/mimxrt/quickref.rst @@ -301,13 +301,19 @@ There are up to four hardware SPI channels that allow faster transmission rates (up to 30Mhz). Hardware SPI is accessed via the :ref:`machine.SPI ` class and has the same methods as software SPI above:: - from machine import SPI + from machine import SPI, Pin spi = SPI(0, 10000000) + cs_pin = Pin(6, Pin.OUT, value=1) + cs_pin(0) spi.write('Hello World') + cs_pin(1) For the assignment of Pins to SPI signals, refer to :ref:`Hardware SPI pinout `. +The keyword option cs=n can be used to enable the cs pin 0 or 1 for an automatic cs signal. The +default is cs=-1. Using cs=-1 the automatic cs signal is not created. +In that case, cs has to be set by the script. Clearing that assignment requires a power cycle. Notes: diff --git a/ports/mimxrt/machine_spi.c b/ports/mimxrt/machine_spi.c index 805ed9a0ac54..32bc77c34ddf 100644 --- a/ports/mimxrt/machine_spi.c +++ b/ports/mimxrt/machine_spi.c @@ -77,7 +77,7 @@ static const iomux_table_t iomux_table[] = { IOMUX_TABLE_SPI }; -bool lpspi_set_iomux(int8_t spi, uint8_t drive, uint8_t cs) { +bool lpspi_set_iomux(int8_t spi, uint8_t drive, int8_t cs) { int index = (spi - 1) * 5; if (SCK.muxRegister != 0) { @@ -93,7 +93,7 @@ bool lpspi_set_iomux(int8_t spi, uint8_t drive, uint8_t cs) { IOMUXC_SetPinMux(CS1.muxRegister, CS1.muxMode, CS1.inputRegister, CS1.inputDaisy, CS1.configRegister, 0U); IOMUXC_SetPinConfig(CS1.muxRegister, CS1.muxMode, CS1.inputRegister, CS1.inputDaisy, CS1.configRegister, pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, drive, CS1.configRegister)); - } else { + } else if (cs != -1) { mp_raise_ValueError(MP_ERROR_TEXT("The chosen CS is not available")); } @@ -131,7 +131,7 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_FIRSTBIT} }, { MP_QSTR_gap_ns, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_DRIVE} }, - { MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, }; // Parse the arguments. @@ -173,8 +173,11 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n } self->master_config->lastSckToPcsDelayInNanoSec = self->master_config->betweenTransferDelayInNanoSec; self->master_config->pcsToSckDelayInNanoSec = self->master_config->betweenTransferDelayInNanoSec; - uint8_t cs = args[ARG_cs].u_int; - if (cs <= 1) { + int8_t cs = args[ARG_cs].u_int; + // In the SPI master_config for automatic CS the value cs=0 is set already, + // so only cs=1 has to be addressed here. The case cs == -1 for manual CS is handled + // in the function spi_set_iomux() and the value in the master_config can stay at 0. + if (cs == 1) { self->master_config->whichPcs = cs; } LPSPI_MasterInit(self->spi_inst, self->master_config, BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT); From 443fbcf81c05de00f35b90d8a443837d62073a63 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 18 Aug 2022 11:36:08 +0200 Subject: [PATCH 1732/4290] mimxrt/machine_uart: Set the UART ioctl write poll flag properly. It was always set to True. The change adds a check to the tx status flag which is set when all data is transferred. --- ports/mimxrt/machine_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index 1b0c0633345a..ab1788692645 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -437,7 +437,7 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint ret |= MP_STREAM_POLL_RD; } } - if ((flags & MP_STREAM_POLL_WR)) { + if ((flags & MP_STREAM_POLL_WR) && (self->tx_status == kStatus_LPUART_TxIdle)) { ret |= MP_STREAM_POLL_WR; } } else if (request == MP_STREAM_FLUSH) { From 6472348c1b2559105e1b2f912a58566b9900e9c1 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 8 Sep 2022 14:24:32 +0200 Subject: [PATCH 1733/4290] mimxrt/machine_uart: Fix a bug in UART.write(). Causing an incomplete send if the data size was longer than the buffer size. --- ports/mimxrt/machine_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index ab1788692645..83382a6cf2bc 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -395,7 +395,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin // Wait at least the number of character times for this chunk. t = ticks_us64() + (uint64_t)xfer.dataSize * (13000000 / self->config.baudRate_Bps + 1000); - while (self->handle.txDataSize) { + while (self->tx_status != kStatus_LPUART_TxIdle) { // Wait for the first/next character to be sent. if (ticks_us64() > t) { // timed out if (self->handle.txDataSize >= size) { From 74805435f9459ceae4ea6044a767de4a5479e6c8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 13 Sep 2022 21:14:22 +1000 Subject: [PATCH 1734/4290] py/objpolyiter: Fix comment about finaliser method. Signed-off-by: Damien George --- py/objpolyiter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/objpolyiter.c b/py/objpolyiter.c index 16fd1f486c15..dac6a2545575 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -66,7 +66,7 @@ typedef struct _mp_obj_polymorph_iter_with_finaliser_t { STATIC mp_obj_t mp_obj_polymorph_iter_del(mp_obj_t self_in) { mp_obj_polymorph_with_finaliser_iter_t *self = MP_OBJ_TO_PTR(self_in); - // Redirect call to object instance's iternext method + // Redirect call to object instance's finaliser method return self->finaliser(self_in); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_polymorph_iter_del_obj, mp_obj_polymorph_iter_del); From 0e8c2204da377e95b5000a3c708891d98cdeb69c Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 14 Sep 2022 14:03:37 +1000 Subject: [PATCH 1735/4290] esp32/mphalport: Fix calculation of large sleep by using 64-bit arith. Fixes issue #9304. Signed-off-by: Damien George --- ports/esp32/mphalport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c index aab534937e13..2aaeb9755f97 100644 --- a/ports/esp32/mphalport.c +++ b/ports/esp32/mphalport.c @@ -130,7 +130,7 @@ uint32_t mp_hal_ticks_us(void) { } void mp_hal_delay_ms(uint32_t ms) { - uint64_t us = ms * 1000; + uint64_t us = (uint64_t)ms * 1000ULL; uint64_t dt; uint64_t t0 = esp_timer_get_time(); for (;;) { @@ -139,7 +139,7 @@ void mp_hal_delay_ms(uint32_t ms) { MP_THREAD_GIL_EXIT(); uint64_t t1 = esp_timer_get_time(); dt = t1 - t0; - if (dt + portTICK_PERIOD_MS * 1000 >= us) { + if (dt + portTICK_PERIOD_MS * 1000ULL >= us) { // doing a vTaskDelay would take us beyond requested delay time taskYIELD(); MP_THREAD_GIL_ENTER(); From 45972fa5481aeef38d074360b0f72b212968a305 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Sep 2022 09:57:47 +1000 Subject: [PATCH 1736/4290] py/mkrules.mk: Add link to build troubleshooting on failure. Also update the submodules help text to match. Signed-off-by: Jim Mussared --- py/mkrules.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/py/mkrules.mk b/py/mkrules.mk index 14f1b953cda4..a58bd2ee0e4d 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -4,6 +4,9 @@ THIS_MAKEFILE = $(lastword $(MAKEFILE_LIST)) include $(dir $(THIS_MAKEFILE))mkenv.mk endif +HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" +HELP_MPY_LIB_SUBMODULE ?= "\033[1;31mError: micropython-lib submodule is not initialized.\033[0m Run 'make submodules'" + # Extra deps that need to happen before object compilation. OBJ_EXTRA_ORDER_DEPS = @@ -53,7 +56,7 @@ $(BUILD)/%.o: %.s define compile_c $(ECHO) "CC $<" -$(Q)$(CC) $(CFLAGS) -c -MD -o $@ $< +$(Q)$(CC) $(CFLAGS) -c -MD -o $@ $< || (echo -e $(HELP_BUILD_ERROR); false) @# The following fixes the dependency file. @# See http://make.paulandlesley.org/autodep.html for details. @# Regex adjusted from the above to play better with Windows paths, etc. @@ -65,7 +68,7 @@ endef define compile_cxx $(ECHO) "CXX $<" -$(Q)$(CXX) $(CXXFLAGS) -c -MD -o $@ $< +$(Q)$(CXX) $(CXXFLAGS) -c -MD -o $@ $< || (echo -e $(HELP_BUILD_ERROR); false) @# The following fixes the dependency file. @# See http://make.paulandlesley.org/autodep.html for details. @# Regex adjusted from the above to play better with Windows paths, etc. @@ -182,7 +185,7 @@ endif # to build frozen_content.c from a manifest $(BUILD)/frozen_content.c: FORCE $(BUILD)/genhdr/qstrdefs.generated.h $(BUILD)/genhdr/root_pointers.h | $(MICROPY_MPYCROSS_DEPENDENCY) - $(Q)test -e "$(MPY_LIB_DIR)/README.md" || (echo "Error: micropython-lib not initialized. Run 'make submodules'"; false) + $(Q)test -e "$(MPY_LIB_DIR)/README.md" || (echo -e $(HELP_MPY_LIB_SUBMODULE); false) $(Q)$(MAKE_MANIFEST) -o $@ -v "MPY_DIR=$(TOP)" -v "MPY_LIB_DIR=$(MPY_LIB_DIR)" -v "PORT_DIR=$(shell pwd)" -v "BOARD_DIR=$(BOARD_DIR)" -b "$(BUILD)" $(if $(MPY_CROSS_FLAGS),-f"$(MPY_CROSS_FLAGS)",) --mpy-tool-flags="$(MPY_TOOL_FLAGS)" $(FROZEN_MANIFEST) endif From 18d0e6d0dbdb34c6cac5aeeb9c4424821cd9f16a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Sep 2022 10:08:48 +1000 Subject: [PATCH 1737/4290] esp32/Makefile: Add link to build troubleshooting on failure. Signed-off-by: Jim Mussared --- ports/esp32/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index b7d804d0730e..e43cad751b21 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -34,8 +34,10 @@ ifdef FROZEN_MANIFEST IDFPY_FLAGS += -D MICROPY_FROZEN_MANIFEST=$(FROZEN_MANIFEST) endif +HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" + all: - idf.py $(IDFPY_FLAGS) build + idf.py $(IDFPY_FLAGS) build || (echo -e $(HELP_BUILD_ERROR); false) @$(PYTHON) makeimg.py \ $(BUILD)/sdkconfig \ $(BUILD)/bootloader/bootloader.bin \ From ca51d63c37e6ca67bec0a645e2aeea71aba91058 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Sep 2022 10:08:59 +1000 Subject: [PATCH 1738/4290] rp2/Makefile: Add link to build troubleshooting on failure. Signed-off-by: Jim Mussared --- ports/rp2/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/rp2/Makefile b/ports/rp2/Makefile index 6d2fc009642d..c603f5403fca 100644 --- a/ports/rp2/Makefile +++ b/ports/rp2/Makefile @@ -22,9 +22,11 @@ ifeq ($(DEBUG),1) CMAKE_ARGS += -DCMAKE_BUILD_TYPE=Debug endif +HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" + all: [ -e $(BUILD)/Makefile ] || cmake -S . -B $(BUILD) -DPICO_BUILD_DOCS=0 ${CMAKE_ARGS} - $(MAKE) $(MAKESILENT) -C $(BUILD) + $(MAKE) $(MAKESILENT) -C $(BUILD) || (echo -e $(HELP_BUILD_ERROR); false) clean: $(RM) -rf $(BUILD) From fb2a57800acffd811d05373dcf63e95b4048d0c6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 15 Jul 2021 14:31:06 +1000 Subject: [PATCH 1739/4290] all: Simplify buffer protocol to just a "get buffer" callback. The buffer protocol type only has a single member, and this existing layout creates problems for the upcoming split/slot-index mp_obj_type_t layout optimisations. If we need to make the buffer protocol more sophisticated in the future either we can rely on the mp_obj_type_t optimisations to just add additional slots to mp_obj_type_t or re-visit the buffer protocol then. This change is a no-op in terms of generated code. Signed-off-by: Jim Mussared --- examples/natmod/framebuf/framebuf.c | 2 +- extmod/modbluetooth.c | 2 +- extmod/modframebuf.c | 2 +- extmod/moductypes.c | 2 +- ports/nrf/boards/microbit/modules/iters.c | 1 - ports/nrf/boards/microbit/modules/microbitdisplay.c | 1 - ports/nrf/boards/microbit/modules/microbitimage.c | 1 - ports/unix/modffi.c | 4 ++-- py/obj.c | 4 ++-- py/obj.h | 6 ++---- py/objarray.c | 6 +++--- py/objstr.c | 4 ++-- py/objstrunicode.c | 2 +- py/objtype.c | 6 +++--- 14 files changed, 19 insertions(+), 24 deletions(-) diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c index 53fb90c625ad..2eff61c817d2 100644 --- a/examples/natmod/framebuf/framebuf.c +++ b/examples/natmod/framebuf/framebuf.c @@ -21,7 +21,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a mp_type_framebuf.base.type = (void*)&mp_type_type; mp_type_framebuf.name = MP_QSTR_FrameBuffer; mp_type_framebuf.make_new = framebuf_make_new; - mp_type_framebuf.buffer_p.get_buffer = framebuf_get_buffer; + mp_type_framebuf.buffer = framebuf_get_buffer; framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index bd4d9b71790c..4cc57b3d55ab 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -248,7 +248,7 @@ const mp_obj_type_t mp_type_bluetooth_uuid = { .binary_op = bluetooth_uuid_binary_op, .locals_dict = NULL, .print = bluetooth_uuid_print, - .buffer_p = { .get_buffer = bluetooth_uuid_get_buffer }, + .buffer = bluetooth_uuid_get_buffer, }; // ---------------------------------------------------------------------------- diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index bb1f4f631077..9542d4303e09 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -833,7 +833,7 @@ STATIC const mp_obj_type_t mp_type_framebuf = { { &mp_type_type }, .name = MP_QSTR_FrameBuffer, .make_new = framebuf_make_new, - .buffer_p = { .get_buffer = framebuf_get_buffer }, + .buffer = framebuf_get_buffer, .locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict, }; #endif diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 547453c48e9f..25578dd6b071 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -642,7 +642,7 @@ STATIC const mp_obj_type_t uctypes_struct_type = { .attr = uctypes_struct_attr, .subscr = uctypes_struct_subscr, .unary_op = uctypes_struct_unary_op, - .buffer_p = { .get_buffer = uctypes_get_buffer }, + .buffer = uctypes_get_buffer, }; STATIC const mp_rom_map_elem_t mp_module_uctypes_globals_table[] = { diff --git a/ports/nrf/boards/microbit/modules/iters.c b/ports/nrf/boards/microbit/modules/iters.c index 8ae4b698fe92..e9c4ae3c72bc 100644 --- a/ports/nrf/boards/microbit/modules/iters.c +++ b/ports/nrf/boards/microbit/modules/iters.c @@ -55,7 +55,6 @@ const mp_obj_type_t microbit_repeat_iterator_type = { .subscr = NULL, .getiter = mp_identity_getiter, .iternext = microbit_repeat_iter_next, - .buffer_p = {NULL}, MP_OBJ_NULL }; diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c index b35703ad6f9a..04b8602879b8 100644 --- a/ports/nrf/boards/microbit/modules/microbitdisplay.c +++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c @@ -554,7 +554,6 @@ const mp_obj_type_t microbit_display_type = { .subscr = NULL, .getiter = NULL, .iternext = NULL, - .buffer_p = {NULL}, .locals_dict = (mp_obj_dict_t*)µbit_display_locals_dict, }; diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c index a028df8282a9..5d2896c38346 100644 --- a/ports/nrf/boards/microbit/modules/microbitimage.c +++ b/ports/nrf/boards/microbit/modules/microbitimage.c @@ -690,7 +690,6 @@ const mp_obj_type_t microbit_image_type = { .subscr = NULL, .getiter = NULL, .iternext = NULL, - .buffer_p = {NULL}, .locals_dict = (mp_obj_dict_t*)µbit_image_locals_dict, }; diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index d82d5270fa34..6417b5d3b395 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -505,10 +505,10 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const } else if (mp_obj_is_str(a)) { const char *s = mp_obj_str_get_str(a); values[i].ffi = (ffi_arg)(intptr_t)s; - } else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) { + } else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer != NULL) { mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a); mp_buffer_info_t bufinfo; - int ret = o->type->buffer_p.get_buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? + int ret = o->type->buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? if (ret != 0) { goto error; } diff --git a/py/obj.c b/py/obj.c index b461fe50aa25..eeadd3eeddda 100644 --- a/py/obj.c +++ b/py/obj.c @@ -579,10 +579,10 @@ mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) { bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { const mp_obj_type_t *type = mp_obj_get_type(obj); - if (type->buffer_p.get_buffer == NULL) { + if (type->buffer == NULL) { return false; } - int ret = type->buffer_p.get_buffer(obj, bufinfo, flags); + int ret = type->buffer(obj, bufinfo, flags); if (ret != 0) { return false; } diff --git a/py/obj.h b/py/obj.h index 894983028225..0bf5b58f8155 100644 --- a/py/obj.h +++ b/py/obj.h @@ -557,9 +557,7 @@ typedef struct _mp_buffer_info_t { #define MP_BUFFER_READ (1) #define MP_BUFFER_WRITE (2) #define MP_BUFFER_RW (MP_BUFFER_READ | MP_BUFFER_WRITE) -typedef struct _mp_buffer_p_t { - mp_int_t (*get_buffer)(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); -} mp_buffer_p_t; +typedef mp_int_t (*mp_buffer_fun_t)(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); @@ -618,7 +616,7 @@ struct _mp_obj_type_t { mp_fun_1_t iternext; // Implements the buffer protocol if supported by this type. - mp_buffer_p_t buffer_p; + mp_buffer_fun_t buffer; // One of disjoint protocols (interfaces), like mp_stream_p_t, etc. const void *protocol; diff --git a/py/objarray.c b/py/objarray.c index ecaffeb6a22e..dca41c2931d6 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -580,7 +580,7 @@ const mp_obj_type_t mp_type_array = { .unary_op = array_unary_op, .binary_op = array_binary_op, .subscr = array_subscr, - .buffer_p = { .get_buffer = array_get_buffer }, + .buffer_p = array_get_buffer, .locals_dict = (mp_obj_dict_t *)&mp_obj_array_locals_dict, }; #endif @@ -596,7 +596,7 @@ const mp_obj_type_t mp_type_bytearray = { .unary_op = array_unary_op, .binary_op = array_binary_op, .subscr = array_subscr, - .buffer_p = { .get_buffer = array_get_buffer }, + .buffer = array_get_buffer, .locals_dict = (mp_obj_dict_t *)&mp_obj_bytearray_locals_dict, }; #endif @@ -617,7 +617,7 @@ const mp_obj_type_t mp_type_memoryview = { .locals_dict = (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, #endif .subscr = array_subscr, - .buffer_p = { .get_buffer = array_get_buffer }, + .buffer = array_get_buffer, }; #endif diff --git a/py/objstr.c b/py/objstr.c index 683d035e4409..9dd7f65e66ca 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2151,7 +2151,7 @@ const mp_obj_type_t mp_type_str = { .binary_op = mp_obj_str_binary_op, .subscr = bytes_subscr, .getiter = mp_obj_new_str_iterator, - .buffer_p = { .get_buffer = mp_obj_str_get_buffer }, + .buffer = mp_obj_str_get_buffer, .locals_dict = (mp_obj_dict_t *)&mp_obj_str_locals_dict, }; #endif // !MICROPY_PY_BUILTINS_STR_UNICODE @@ -2165,7 +2165,7 @@ const mp_obj_type_t mp_type_bytes = { .binary_op = mp_obj_str_binary_op, .subscr = bytes_subscr, .getiter = mp_obj_new_bytes_iterator, - .buffer_p = { .get_buffer = mp_obj_str_get_buffer }, + .buffer = mp_obj_str_get_buffer, .locals_dict = (mp_obj_dict_t *)&mp_obj_bytes_locals_dict, }; diff --git a/py/objstrunicode.c b/py/objstrunicode.c index d36dd8b1375a..fef0353683c1 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -238,7 +238,7 @@ const mp_obj_type_t mp_type_str = { .binary_op = mp_obj_str_binary_op, .subscr = str_subscr, .getiter = mp_obj_new_str_iterator, - .buffer_p = { .get_buffer = mp_obj_str_get_buffer }, + .buffer = mp_obj_str_get_buffer, .locals_dict = (mp_obj_dict_t *)&mp_obj_str_locals_dict, }; diff --git a/py/objtype.c b/py/objtype.c index fe1918bd3731..c0f68578092d 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -913,14 +913,14 @@ STATIC mp_int_t instance_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, struct class_lookup_data lookup = { .obj = self, .attr = MP_QSTR_, // don't actually look for a method - .meth_offset = offsetof(mp_obj_type_t, buffer_p.get_buffer), + .meth_offset = offsetof(mp_obj_type_t, buffer), .dest = member, .is_type = false, }; mp_obj_class_lookup(&lookup, self->base.type); if (member[0] == MP_OBJ_SENTINEL) { const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]); - return type->buffer_p.get_buffer(self->subobj[0], bufinfo, flags); + return type->buffer(self->subobj[0], bufinfo, flags); } else { return 1; // object does not support buffer protocol } @@ -1160,7 +1160,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) o->subscr = instance_subscr; o->getiter = mp_obj_instance_getiter; // o->iternext = ; not implemented - o->buffer_p.get_buffer = instance_get_buffer; + o->buffer = instance_get_buffer; if (bases_len > 0) { // Inherit protocol from a base class. This allows to define an From 42587c78702e0a96ca025e66267201f27389bb17 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Jul 2021 14:06:29 +1000 Subject: [PATCH 1740/4290] all: Standardise mp_obj_type_t initialisation. Remove setting unused slots. Signed-off-by: Jim Mussared --- extmod/vfs_fat.c | 1 - ports/nrf/boards/microbit/modules/iters.c | 8 ---- .../boards/microbit/modules/microbitdisplay.c | 9 ---- .../boards/microbit/modules/microbitimage.c | 42 ------------------- 4 files changed, 60 deletions(-) diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 7d8b51efeb61..8d2f13be476d 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -437,7 +437,6 @@ const mp_obj_type_t mp_fat_vfs_type = { .make_new = fat_vfs_make_new, .protocol = &fat_vfs_proto, .locals_dict = (mp_obj_dict_t *)&fat_vfs_locals_dict, - }; #endif // MICROPY_VFS_FAT diff --git a/ports/nrf/boards/microbit/modules/iters.c b/ports/nrf/boards/microbit/modules/iters.c index e9c4ae3c72bc..66f9f6c7f3ea 100644 --- a/ports/nrf/boards/microbit/modules/iters.c +++ b/ports/nrf/boards/microbit/modules/iters.c @@ -46,16 +46,8 @@ static mp_obj_t microbit_repeat_iter_next(mp_obj_t iter_in) { const mp_obj_type_t microbit_repeat_iterator_type = { { &mp_type_type }, .name = MP_QSTR_iterator, - .print = NULL, - .make_new = NULL, - .call = NULL, - .unary_op = NULL, - .binary_op = NULL, - .attr = NULL, - .subscr = NULL, .getiter = mp_identity_getiter, .iternext = microbit_repeat_iter_next, - MP_OBJ_NULL }; mp_obj_t microbit_repeat_iterator(mp_obj_t iterable) { diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c index 04b8602879b8..93ba9772fe98 100644 --- a/ports/nrf/boards/microbit/modules/microbitdisplay.c +++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c @@ -545,15 +545,6 @@ STATIC MP_DEFINE_CONST_DICT(microbit_display_locals_dict, microbit_display_local const mp_obj_type_t microbit_display_type = { { &mp_type_type }, .name = MP_QSTR_MicroBitDisplay, - .print = NULL, - .make_new = NULL, - .call = NULL, - .unary_op = NULL, - .binary_op = NULL, - .attr = NULL, - .subscr = NULL, - .getiter = NULL, - .iternext = NULL, .locals_dict = (mp_obj_dict_t*)µbit_display_locals_dict, }; diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c index 5d2896c38346..eb44660b974c 100644 --- a/ports/nrf/boards/microbit/modules/microbitimage.c +++ b/ports/nrf/boards/microbit/modules/microbitimage.c @@ -683,13 +683,7 @@ const mp_obj_type_t microbit_image_type = { .name = MP_QSTR_MicroBitImage, .print = microbit_image_print, .make_new = microbit_image_make_new, - .call = NULL, - .unary_op = NULL, .binary_op = image_binary_op, - .attr = NULL, - .subscr = NULL, - .getiter = NULL, - .iternext = NULL, .locals_dict = (mp_obj_dict_t*)µbit_image_locals_dict, }; @@ -829,33 +823,14 @@ STATIC mp_obj_t microbit_scrolling_string_iter_next(mp_obj_t o_in) { const mp_obj_type_t microbit_scrolling_string_type = { { &mp_type_type }, .name = MP_QSTR_ScrollingString, - .print = NULL, - .make_new = NULL, - .call = NULL, - .unary_op = NULL, - .binary_op = NULL, - .attr = NULL, - .subscr = NULL, .getiter = get_microbit_scrolling_string_iter, - .iternext = NULL, - .buffer_p = {NULL}, - .locals_dict = NULL, }; const mp_obj_type_t microbit_scrolling_string_iterator_type = { { &mp_type_type }, .name = MP_QSTR_iterator, - .print = NULL, - .make_new = NULL, - .call = NULL, - .unary_op = NULL, - .binary_op = NULL, - .attr = NULL, - .subscr = NULL, .getiter = mp_identity_getiter, .iternext = microbit_scrolling_string_iter_next, - .buffer_p = {NULL}, - .locals_dict = NULL, }; /** Facade types to present a string as a sequence of images. @@ -897,17 +872,9 @@ static mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t const mp_obj_type_t string_image_facade_type = { { &mp_type_type }, .name = MP_QSTR_Facade, - .print = NULL, - .make_new = NULL, - .call = NULL, .unary_op = facade_unary_op, - .binary_op = NULL, - .attr = NULL, .subscr = string_image_facade_subscr, .getiter = microbit_facade_iterator, - .iternext = NULL, - .buffer_p = {NULL}, - NULL }; @@ -940,17 +907,8 @@ static mp_obj_t microbit_facade_iter_next(mp_obj_t iter_in) { const mp_obj_type_t microbit_facade_iterator_type = { { &mp_type_type }, .name = MP_QSTR_iterator, - .print = NULL, - .make_new = NULL, - .call = NULL, - .unary_op = NULL, - .binary_op = NULL, - .attr = NULL, - .subscr = NULL, .getiter = mp_identity_getiter, .iternext = microbit_facade_iter_next, - .buffer_p = {NULL}, - NULL }; mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf) { From cdb880789f61ee037cc7905ad75a7a9201d12ba5 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Jul 2021 13:38:27 +1000 Subject: [PATCH 1741/4290] py/obj: Add macro to declare ROM mp_obj_type_t instances. This will allow the structure of mp_obj_type_t to change while keeping the definition code the same. Signed-off-by: Jim Mussared --- py/obj.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/py/obj.h b/py/obj.h index 0bf5b58f8155..4ab7e0dc09c1 100644 --- a/py/obj.h +++ b/py/obj.h @@ -513,6 +513,7 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); // operator and not the __ne__ operator. If it's set then __ne__ may be implemented. // If MP_TYPE_FLAG_BINDS_SELF is set then the type as a method binds self as the first arg. // If MP_TYPE_FLAG_BUILTIN_FUN is set then the type is a built-in function type. +#define MP_TYPE_FLAG_NONE (0x0000) #define MP_TYPE_FLAG_IS_SUBCLASSED (0x0001) #define MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002) #define MP_TYPE_FLAG_EQ_NOT_REFLEXIVE (0x0004) @@ -631,6 +632,40 @@ struct _mp_obj_type_t { struct _mp_obj_dict_t *locals_dict; }; +#define MP_TYPE_NULL_MAKE_NEW (NULL) + +// Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments. +// Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE. +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0(_struct_type, _typename, _name, _flags, _make_new) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_1(_struct_type, _typename, _name, _flags, _make_new, f1, v1) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_2(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_3(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_4(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_5(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_6(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_8(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_9(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_10(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11 } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11, .f12 = v12 } + +// Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked +#define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x + +// This macro evaluates to MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N, where N is the value +// of the 30th argument (30 is 13*2 + 4). +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, N, ...) MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N + +// This macro is used to define a object type in ROM. +// Invoke as MP_DEFINE_CONST_OBJ_TYPE(_typename, _name, _flags, _make_new [, slot, func]*) +// It uses the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_* +// macro to use based on the number of arguments. It works by shifting the +// numeric values 12, 11, ... 0 by the number of arguments, such that the +// 30th argument ends up being the number to use. The _INV values are +// placeholders because the slot arguments come in pairs. +#define MP_DEFINE_CONST_OBJ_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_type_t, __VA_ARGS__)) + // Constant types, globally accessible extern const mp_obj_type_t mp_type_type; extern const mp_obj_type_t mp_type_object; From 662b9761b37b054f08fe2f7c00d0fce3a418d0b0 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Jul 2021 14:38:38 +1000 Subject: [PATCH 1742/4290] all: Make all mp_obj_type_t defs use MP_DEFINE_CONST_OBJ_TYPE. In preparation for upcoming rework of mp_obj_type_t layout. Signed-off-by: Jim Mussared --- extmod/machine_i2c.c | 17 +-- extmod/machine_mem.c | 14 ++- extmod/machine_pinbase.c | 13 +- extmod/machine_pwm.c | 15 +-- extmod/machine_signal.c | 17 +-- extmod/machine_spi.c | 17 +-- extmod/modbluetooth.c | 33 ++--- extmod/modbtree.c | 22 ++-- extmod/modframebuf.c | 15 +-- extmod/modlwip.c | 30 ++--- extmod/moduasyncio.c | 30 ++--- extmod/moducryptolib.c | 13 +- extmod/moductypes.c | 21 ++-- extmod/moduhashlib.c | 39 +++--- extmod/modure.c | 28 +++-- extmod/moduselect.c | 16 +-- extmod/modusocket.c | 17 +-- extmod/modussl_axtls.c | 20 ++-- extmod/modussl_mbedtls.c | 20 ++-- extmod/modutimeq.c | 15 +-- extmod/moduwebsocket.c | 15 +-- extmod/moduzlib.c | 15 +-- extmod/modwebrepl.c | 15 +-- extmod/network_cyw43.c | 15 +-- extmod/network_ninaw10.c | 15 ++- extmod/network_wiznet5k.c | 28 +++-- extmod/vfs_fat.c | 15 +-- extmod/vfs_fat_file.c | 40 ++++--- extmod/vfs_lfsx.c | 17 +-- extmod/vfs_lfsx_file.c | 40 ++++--- extmod/vfs_posix.c | 15 +-- extmod/vfs_posix_file.c | 40 ++++--- ports/cc3200/misc/mpirq.c | 14 ++- ports/cc3200/mods/modnetwork.c | 13 +- ports/cc3200/mods/moduhashlib.c | 28 +++-- ports/cc3200/mods/modusocket.c | 15 +-- ports/cc3200/mods/modussl.c | 18 +-- ports/cc3200/mods/modwlan.c | 15 ++- ports/cc3200/mods/pybadc.c | 31 ++--- ports/cc3200/mods/pybflash.c | 13 +- ports/cc3200/mods/pybi2c.c | 15 +-- ports/cc3200/mods/pybpin.c | 31 ++--- ports/cc3200/mods/pybrtc.c | 13 +- ports/cc3200/mods/pybsd.c | 13 +- ports/cc3200/mods/pybsleep.c | 10 +- ports/cc3200/mods/pybspi.c | 15 +-- ports/cc3200/mods/pybtimer.c | 29 +++-- ports/cc3200/mods/pybuart.c | 21 ++-- ports/cc3200/mods/pybwdt.c | 13 +- ports/esp32/esp32_nvs.c | 15 +-- ports/esp32/esp32_partition.c | 15 +-- ports/esp32/esp32_rmt.c | 15 +-- ports/esp32/esp32_ulp.c | 13 +- ports/esp32/machine_adc.c | 15 +-- ports/esp32/machine_adcblock.c | 15 +-- ports/esp32/machine_dac.c | 15 +-- ports/esp32/machine_hw_spi.c | 17 +-- ports/esp32/machine_i2c.c | 17 +-- ports/esp32/machine_i2s.c | 21 ++-- ports/esp32/machine_pin.c | 33 ++--- ports/esp32/machine_rtc.c | 13 +- ports/esp32/machine_sdcard.c | 13 +- ports/esp32/machine_timer.c | 15 +-- ports/esp32/machine_touchpad.c | 13 +- ports/esp32/machine_uart.c | 21 ++-- ports/esp32/machine_wdt.c | 13 +- ports/esp32/modsocket.c | 15 +-- ports/esp32/network_lan.c | 12 +- ports/esp32/network_ppp.c | 12 +- ports/esp32/network_wlan.c | 20 ++-- ports/esp8266/machine_adc.c | 15 +-- ports/esp8266/machine_hspi.c | 17 +-- ports/esp8266/machine_pin.c | 33 ++--- ports/esp8266/machine_rtc.c | 13 +- ports/esp8266/machine_uart.c | 21 ++-- ports/esp8266/machine_wdt.c | 13 +- ports/esp8266/modmachine.c | 15 +-- ports/esp8266/modnetwork.c | 12 +- ports/mimxrt/machine_adc.c | 15 +-- ports/mimxrt/machine_i2c.c | 17 +-- ports/mimxrt/machine_i2s.c | 21 ++-- ports/mimxrt/machine_led.c | 15 +-- ports/mimxrt/machine_pin.c | 61 +++++----- ports/mimxrt/machine_rtc.c | 13 +- ports/mimxrt/machine_sdcard.c | 13 +- ports/mimxrt/machine_spi.c | 17 +-- ports/mimxrt/machine_timer.c | 15 +-- ports/mimxrt/machine_uart.c | 21 ++-- ports/mimxrt/machine_wdt.c | 13 +- ports/mimxrt/mimxrt_flash.c | 13 +- ports/mimxrt/network_lan.c | 16 +-- ports/nrf/boards/microbit/modules/iters.c | 14 ++- .../boards/microbit/modules/microbitdisplay.c | 12 +- .../boards/microbit/modules/microbitimage.c | 73 ++++++----- ports/nrf/modules/board/led.c | 15 +-- ports/nrf/modules/machine/adc.c | 15 +-- ports/nrf/modules/machine/i2c.c | 17 +-- ports/nrf/modules/machine/pin.c | 31 ++--- ports/nrf/modules/machine/pwm.c | 15 +-- ports/nrf/modules/machine/rtcounter.c | 15 +-- ports/nrf/modules/machine/spi.c | 17 +-- ports/nrf/modules/machine/temp.c | 15 +-- ports/nrf/modules/machine/timer.c | 15 +-- ports/nrf/modules/machine/uart.c | 21 ++-- ports/nrf/modules/nrf/flashbdev.c | 15 +-- .../modules/ubluepy/ubluepy_characteristic.c | 15 +-- ports/nrf/modules/ubluepy/ubluepy_constants.c | 24 ++-- ports/nrf/modules/ubluepy/ubluepy_delegate.c | 15 +-- .../nrf/modules/ubluepy/ubluepy_descriptor.c | 15 +-- .../nrf/modules/ubluepy/ubluepy_peripheral.c | 15 +-- .../nrf/modules/ubluepy/ubluepy_scan_entry.c | 14 ++- ports/nrf/modules/ubluepy/ubluepy_scanner.c | 15 +-- ports/nrf/modules/ubluepy/ubluepy_service.c | 15 +-- ports/nrf/modules/ubluepy/ubluepy_uuid.c | 15 +-- ports/nrf/modules/uos/microbitfs.c | 28 +++-- ports/nrf/pin_named_pins.c | 28 +++-- ports/pic16bit/modpybled.c | 15 +-- ports/pic16bit/modpybswitch.c | 17 +-- ports/renesas-ra/extint.c | 15 +-- ports/renesas-ra/led.c | 15 +-- ports/renesas-ra/machine_adc.c | 15 +-- ports/renesas-ra/machine_i2c.c | 17 +-- ports/renesas-ra/machine_pin.c | 45 +++---- ports/renesas-ra/machine_rtc.c | 13 +- ports/renesas-ra/machine_spi.c | 17 +-- ports/renesas-ra/machine_timer.c | 15 +-- ports/renesas-ra/machine_uart.c | 21 ++-- ports/renesas-ra/storage.c | 15 +-- ports/renesas-ra/timer.c | 29 +++-- ports/renesas-ra/usrsw.c | 17 +-- ports/rp2/machine_adc.c | 15 +-- ports/rp2/machine_i2c.c | 17 +-- ports/rp2/machine_i2s.c | 21 ++-- ports/rp2/machine_pin.c | 19 +-- ports/rp2/machine_rtc.c | 13 +- ports/rp2/machine_spi.c | 17 +-- ports/rp2/machine_timer.c | 15 +-- ports/rp2/machine_uart.c | 21 ++-- ports/rp2/machine_wdt.c | 13 +- ports/rp2/rp2_flash.c | 13 +- ports/rp2/rp2_pio.c | 30 ++--- ports/samd/machine_led.c | 17 +-- ports/samd/machine_pin.c | 19 +-- ports/samd/samd_flash.c | 13 +- ports/stm32/accel.c | 13 +- ports/stm32/adc.c | 28 +++-- ports/stm32/dac.c | 15 +-- ports/stm32/extint.c | 15 +-- ports/stm32/lcd.c | 13 +- ports/stm32/led.c | 15 +-- ports/stm32/machine_adc.c | 15 +-- ports/stm32/machine_i2c.c | 17 +-- ports/stm32/machine_i2s.c | 21 ++-- ports/stm32/machine_spi.c | 17 +-- ports/stm32/machine_timer.c | 15 +-- ports/stm32/machine_uart.c | 21 ++-- ports/stm32/network_lan.c | 15 +-- ports/stm32/pin.c | 33 ++--- ports/stm32/pin_named_pins.c | 24 ++-- ports/stm32/pyb_can.c | 17 +-- ports/stm32/pyb_i2c.c | 15 +-- ports/stm32/pyb_spi.c | 17 +-- ports/stm32/rtc.c | 13 +- ports/stm32/sdcard.c | 26 ++-- ports/stm32/servo.c | 15 +-- ports/stm32/storage.c | 15 +-- ports/stm32/timer.c | 29 +++-- ports/stm32/usb.c | 36 +++--- ports/stm32/usrsw.c | 17 +-- ports/stm32/wdt.c | 13 +- ports/teensy/led.c | 15 +-- ports/teensy/timer.c | 29 +++-- ports/teensy/uart.c | 15 +-- ports/unix/coverage.c | 26 ++-- ports/unix/modffi.c | 69 ++++++----- ports/unix/modjni.c | 58 +++++---- ports/unix/moduselect.c | 16 +-- ports/unix/modusocket.c | 21 ++-- ports/zephyr/machine_i2c.c | 17 +-- ports/zephyr/machine_pin.c | 19 +-- ports/zephyr/machine_spi.c | 17 +-- ports/zephyr/machine_uart.c | 21 ++-- ports/zephyr/modusocket.c | 17 +-- ports/zephyr/modzsensor.c | 13 +- ports/zephyr/zephyr_storage.c | 30 ++--- py/builtinevex.c | 10 +- py/modio.c | 28 +++-- py/modthread.c | 12 +- py/objarray.c | 87 +++++++------- py/objattrtuple.c | 23 ++-- py/objbool.c | 19 +-- py/objboundmeth.c | 16 +-- py/objcell.c | 10 +- py/objclosure.c | 17 +-- py/objcomplex.c | 17 ++- py/objdeque.c | 15 +-- py/objdict.c | 78 ++++++------ py/objenumerate.c | 15 +-- py/objexcept.c | 15 +-- py/objfilter.c | 15 +-- py/objfloat.c | 15 +-- py/objfun.c | 113 ++++++++---------- py/objgenerator.c | 54 +++++---- py/objgetitemiter.c | 14 ++- py/objint.c | 19 +-- py/objlist.c | 24 ++-- py/objmap.c | 15 +-- py/objmodule.c | 14 ++- py/objnone.c | 14 ++- py/objobject.c | 13 +- py/objpolyiter.c | 31 ++--- py/objproperty.c | 13 +- py/objrange.c | 37 +++--- py/objreversed.c | 15 +-- py/objset.c | 43 +++---- py/objsingleton.c | 11 +- py/objslice.c | 16 +-- py/objstr.c | 48 ++++---- py/objstringio.c | 42 +++---- py/objstrunicode.c | 25 ++-- py/objtuple.c | 23 ++-- py/objtype.c | 58 ++++----- py/objzip.c | 15 +-- py/profile.c | 32 ++--- py/runtime.c | 13 +- shared/runtime/mpirq.c | 14 ++- shared/runtime/sys_stdio_mphal.c | 40 ++++--- 227 files changed, 2547 insertions(+), 2188 deletions(-) diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index ff597b58c5e5..7e597b791029 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -730,13 +730,14 @@ STATIC const mp_machine_i2c_p_t mp_machine_soft_i2c_p = { .transfer = mp_machine_soft_i2c_transfer, }; -const mp_obj_type_t mp_machine_soft_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_SoftI2C, - .print = mp_machine_soft_i2c_print, - .make_new = mp_machine_soft_i2c_make_new, - .protocol = &mp_machine_soft_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_machine_soft_i2c_type, + MP_QSTR_SoftI2C, + MP_TYPE_FLAG_NONE, + mp_machine_soft_i2c_make_new, + print, mp_machine_soft_i2c_print, + protocol, &mp_machine_soft_i2c_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + ); #endif // MICROPY_PY_MACHINE_SOFTI2C diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index 73e2f7fd1fcb..422e99d3ce42 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -101,12 +101,14 @@ STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t va } } -const mp_obj_type_t machine_mem_type = { - { &mp_type_type }, - .name = MP_QSTR_mem, - .print = machine_mem_print, - .subscr = machine_mem_subscr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_mem_type, + MP_QSTR_mem, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, machine_mem_print, + subscr, machine_mem_subscr + ); const machine_mem_obj_t machine_mem8_obj = {{&machine_mem_type}, 1}; const machine_mem_obj_t machine_mem16_obj = {{&machine_mem_type}, 2}; diff --git a/extmod/machine_pinbase.c b/extmod/machine_pinbase.c index 070c5cde9d3a..617dd1280c78 100644 --- a/extmod/machine_pinbase.c +++ b/extmod/machine_pinbase.c @@ -77,11 +77,12 @@ STATIC const mp_pin_p_t pinbase_pin_p = { .ioctl = pinbase_ioctl, }; -const mp_obj_type_t machine_pinbase_type = { - { &mp_type_type }, - .name = MP_QSTR_PinBase, - .make_new = pinbase_make_new, - .protocol = &pinbase_pin_p, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pinbase_type, + MP_QSTR_PinBase, + MP_TYPE_FLAG_NONE, + pinbase_make_new, + protocol, &pinbase_pin_p + ); #endif // MICROPY_PY_MACHINE diff --git a/extmod/machine_pwm.c b/extmod/machine_pwm.c index ddf49c1358a5..f12f70a2d14d 100644 --- a/extmod/machine_pwm.c +++ b/extmod/machine_pwm.c @@ -132,12 +132,13 @@ STATIC const mp_rom_map_elem_t machine_pwm_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_pwm_locals_dict, machine_pwm_locals_dict_table); -const mp_obj_type_t machine_pwm_type = { - { &mp_type_type }, - .name = MP_QSTR_PWM, - .print = mp_machine_pwm_print, - .make_new = mp_machine_pwm_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_pwm_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pwm_type, + MP_QSTR_PWM, + MP_TYPE_FLAG_NONE, + mp_machine_pwm_make_new, + print, mp_machine_pwm_print, + locals_dict, &machine_pwm_locals_dict + ); #endif // MICROPY_PY_MACHINE_PWM diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c index cf7550a2e084..818bc01c2711 100644 --- a/extmod/machine_signal.c +++ b/extmod/machine_signal.c @@ -172,13 +172,14 @@ STATIC const mp_pin_p_t signal_pin_p = { .ioctl = signal_ioctl, }; -const mp_obj_type_t machine_signal_type = { - { &mp_type_type }, - .name = MP_QSTR_Signal, - .make_new = signal_make_new, - .call = signal_call, - .protocol = &signal_pin_p, - .locals_dict = (void *)&signal_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_signal_type, + MP_QSTR_Signal, + MP_TYPE_FLAG_NONE, + signal_make_new, + call, signal_call, + protocol, &signal_pin_p, + locals_dict, (void *)&signal_locals_dict + ); #endif // MICROPY_PY_MACHINE diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index ba533b2a651a..43148c9c8d46 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -251,13 +251,14 @@ const mp_machine_spi_p_t mp_machine_soft_spi_p = { .transfer = mp_machine_soft_spi_transfer, }; -const mp_obj_type_t mp_machine_soft_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SoftSPI, - .print = mp_machine_soft_spi_print, - .make_new = mp_machine_soft_spi_make_new, - .protocol = &mp_machine_soft_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_machine_soft_spi_type, + MP_QSTR_SoftSPI, + MP_TYPE_FLAG_NONE, + mp_machine_soft_spi_make_new, + print, mp_machine_soft_spi_print, + protocol, &mp_machine_soft_spi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); #endif // MICROPY_PY_MACHINE_SOFTSPI diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 4cc57b3d55ab..2b7497e1b655 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -240,16 +240,16 @@ STATIC void ringbuf_get_uuid(ringbuf_t *ringbuf, mp_obj_bluetooth_uuid_t *uuid) #endif // !MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS -const mp_obj_type_t mp_type_bluetooth_uuid = { - { &mp_type_type }, - .name = MP_QSTR_UUID, - .make_new = bluetooth_uuid_make_new, - .unary_op = bluetooth_uuid_unary_op, - .binary_op = bluetooth_uuid_binary_op, - .locals_dict = NULL, - .print = bluetooth_uuid_print, - .buffer = bluetooth_uuid_get_buffer, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bluetooth_uuid, + MP_QSTR_UUID, + MP_TYPE_FLAG_NONE, + bluetooth_uuid_make_new, + unary_op, bluetooth_uuid_unary_op, + binary_op, bluetooth_uuid_binary_op, + print, bluetooth_uuid_print, + buffer, bluetooth_uuid_get_buffer + ); // ---------------------------------------------------------------------------- // Bluetooth object: General @@ -976,12 +976,13 @@ STATIC const mp_rom_map_elem_t bluetooth_ble_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(bluetooth_ble_locals_dict, bluetooth_ble_locals_dict_table); -STATIC const mp_obj_type_t mp_type_bluetooth_ble = { - { &mp_type_type }, - .name = MP_QSTR_BLE, - .make_new = bluetooth_ble_make_new, - .locals_dict = (void *)&bluetooth_ble_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bluetooth_ble, + MP_QSTR_BLE, + MP_TYPE_FLAG_NONE, + bluetooth_ble_make_new, + locals_dict, (void *)&bluetooth_ble_locals_dict + ); STATIC const mp_rom_map_elem_t mp_module_bluetooth_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluetooth) }, diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 7a1daacb4166..f115be44fec1 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -319,17 +319,19 @@ STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table); -STATIC const mp_obj_type_t btree_type = { - { &mp_type_type }, +STATIC MP_DEFINE_CONST_OBJ_TYPE( + btree_type, + MP_QSTR_btree, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module - .name = MP_QSTR_btree, - .print = btree_print, - .getiter = btree_getiter, - .iternext = btree_iternext, - .binary_op = btree_binary_op, - .subscr = btree_subscr, - .locals_dict = (void *)&btree_locals_dict, -}; + print, btree_print, + getiter, btree_getiter, + iternext, btree_iternext, + binary_op, btree_binary_op, + subscr, btree_subscr, + locals_dict, (void *)&btree_locals_dict + ); #endif STATIC const FILEVTABLE btree_stream_fvtable = { diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 9542d4303e09..1d44312cf304 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -829,13 +829,14 @@ STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); -STATIC const mp_obj_type_t mp_type_framebuf = { - { &mp_type_type }, - .name = MP_QSTR_FrameBuffer, - .make_new = framebuf_make_new, - .buffer = framebuf_get_buffer, - .locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_framebuf, + MP_QSTR_FrameBuffer, + MP_TYPE_FLAG_NONE, + framebuf_make_new, + buffer, framebuf_get_buffer, + locals_dict, (mp_obj_dict_t *)&framebuf_locals_dict + ); #endif // this factory function is provided for backwards compatibility with old FrameBuffer1 class diff --git a/extmod/modlwip.c b/extmod/modlwip.c index f9451a0ce439..f9d5b76b2c8b 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -177,12 +177,13 @@ STATIC const mp_rom_map_elem_t lwip_slip_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(lwip_slip_locals_dict, lwip_slip_locals_dict_table); -STATIC const mp_obj_type_t lwip_slip_type = { - { &mp_type_type }, - .name = MP_QSTR_slip, - .make_new = lwip_slip_make_new, - .locals_dict = (mp_obj_dict_t *)&lwip_slip_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + lwip_slip_type, + MP_QSTR_slip, + MP_TYPE_FLAG_NONE, + lwip_slip_make_new, + locals_dict, (mp_obj_dict_t *)&lwip_slip_locals_dict + ); #endif // MICROPY_PY_LWIP_SLIP @@ -1594,14 +1595,15 @@ STATIC const mp_stream_p_t lwip_socket_stream_p = { .ioctl = lwip_socket_ioctl, }; -STATIC const mp_obj_type_t lwip_socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .print = lwip_socket_print, - .make_new = lwip_socket_make_new, - .protocol = &lwip_socket_stream_p, - .locals_dict = (mp_obj_dict_t *)&lwip_socket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + lwip_socket_type, + MP_QSTR_socket, + MP_TYPE_FLAG_NONE, + lwip_socket_make_new, + print, lwip_socket_print, + protocol, &lwip_socket_stream_p, + locals_dict, (mp_obj_dict_t *)&lwip_socket_locals_dict + ); /******************************************************************************/ // Support functions for memory protection. lwIP has its own memory management diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c index 6e3603fa18a4..500d13c5b859 100644 --- a/extmod/moduasyncio.c +++ b/extmod/moduasyncio.c @@ -144,12 +144,13 @@ STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table); -STATIC const mp_obj_type_t task_queue_type = { - { &mp_type_type }, - .name = MP_QSTR_TaskQueue, - .make_new = task_queue_make_new, - .locals_dict = (mp_obj_dict_t *)&task_queue_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + task_queue_type, + MP_QSTR_TaskQueue, + MP_TYPE_FLAG_NONE, + task_queue_make_new, + locals_dict, (mp_obj_dict_t *)&task_queue_locals_dict + ); /******************************************************************************/ // Task class @@ -286,14 +287,15 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) { return mp_const_none; } -STATIC const mp_obj_type_t task_type = { - { &mp_type_type }, - .name = MP_QSTR_Task, - .make_new = task_make_new, - .attr = task_attr, - .getiter = task_getiter, - .iternext = task_iternext, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + task_type, + MP_QSTR_Task, + MP_TYPE_FLAG_NONE, + task_make_new, + attr, task_attr, + getiter, task_getiter, + iternext, task_iternext + ); /******************************************************************************/ // C-level uasyncio module diff --git a/extmod/moducryptolib.c b/extmod/moducryptolib.c index dc0ecb9b20f1..236b7edfd7aa 100644 --- a/extmod/moducryptolib.c +++ b/extmod/moducryptolib.c @@ -348,12 +348,13 @@ STATIC const mp_rom_map_elem_t ucryptolib_aes_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(ucryptolib_aes_locals_dict, ucryptolib_aes_locals_dict_table); -STATIC const mp_obj_type_t ucryptolib_aes_type = { - { &mp_type_type }, - .name = MP_QSTR_aes, - .make_new = ucryptolib_aes_make_new, - .locals_dict = (void *)&ucryptolib_aes_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ucryptolib_aes_type, + MP_QSTR_aes, + MP_TYPE_FLAG_NONE, + ucryptolib_aes_make_new, + locals_dict, (void *)&ucryptolib_aes_locals_dict + ); STATIC const mp_rom_map_elem_t mp_module_ucryptolib_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ucryptolib) }, diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 25578dd6b071..a9ad500c2d1a 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -634,16 +634,17 @@ STATIC mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) { } MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytes_at_obj, uctypes_struct_bytes_at); -STATIC const mp_obj_type_t uctypes_struct_type = { - { &mp_type_type }, - .name = MP_QSTR_struct, - .print = uctypes_struct_print, - .make_new = uctypes_struct_make_new, - .attr = uctypes_struct_attr, - .subscr = uctypes_struct_subscr, - .unary_op = uctypes_struct_unary_op, - .buffer = uctypes_get_buffer, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + uctypes_struct_type, + MP_QSTR_struct, + MP_TYPE_FLAG_NONE, + uctypes_struct_make_new, + print, uctypes_struct_print, + attr, uctypes_struct_attr, + subscr, uctypes_struct_subscr, + unary_op, uctypes_struct_unary_op, + buffer, uctypes_get_buffer + ); STATIC const mp_rom_map_elem_t mp_module_uctypes_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uctypes) }, diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 7eae06b77d34..44625ed6da2a 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -157,12 +157,13 @@ STATIC const mp_rom_map_elem_t uhashlib_sha256_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(uhashlib_sha256_locals_dict, uhashlib_sha256_locals_dict_table); -STATIC const mp_obj_type_t uhashlib_sha256_type = { - { &mp_type_type }, - .name = MP_QSTR_sha256, - .make_new = uhashlib_sha256_make_new, - .locals_dict = (void *)&uhashlib_sha256_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + uhashlib_sha256_type, + MP_QSTR_sha256, + MP_TYPE_FLAG_NONE, + uhashlib_sha256_make_new, + locals_dict, (void *)&uhashlib_sha256_locals_dict + ); #endif #if MICROPY_PY_UHASHLIB_SHA1 @@ -250,12 +251,13 @@ STATIC const mp_rom_map_elem_t uhashlib_sha1_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(uhashlib_sha1_locals_dict, uhashlib_sha1_locals_dict_table); -STATIC const mp_obj_type_t uhashlib_sha1_type = { - { &mp_type_type }, - .name = MP_QSTR_sha1, - .make_new = uhashlib_sha1_make_new, - .locals_dict = (void *)&uhashlib_sha1_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + uhashlib_sha1_type, + MP_QSTR_sha1, + MP_TYPE_FLAG_NONE, + uhashlib_sha1_make_new, + locals_dict, (void *)&uhashlib_sha1_locals_dict + ); #endif #if MICROPY_PY_UHASHLIB_MD5 @@ -343,12 +345,13 @@ STATIC const mp_rom_map_elem_t uhashlib_md5_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(uhashlib_md5_locals_dict, uhashlib_md5_locals_dict_table); -STATIC const mp_obj_type_t uhashlib_md5_type = { - { &mp_type_type }, - .name = MP_QSTR_md5, - .make_new = uhashlib_md5_make_new, - .locals_dict = (void *)&uhashlib_md5_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + uhashlib_md5_type, + MP_QSTR_md5, + MP_TYPE_FLAG_NONE, + uhashlib_md5_make_new, + locals_dict, (void *)&uhashlib_md5_locals_dict + ); #endif // MICROPY_PY_UHASHLIB_MD5 STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = { diff --git a/extmod/modure.c b/extmod/modure.c index a674d664999a..a27c7ff9fdc5 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -179,12 +179,14 @@ STATIC const mp_rom_map_elem_t match_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table); -STATIC const mp_obj_type_t match_type = { - { &mp_type_type }, - .name = MP_QSTR_match, - .print = match_print, - .locals_dict = (void *)&match_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + match_type, + MP_QSTR_match, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, match_print, + locals_dict, (void *)&match_locals_dict + ); #endif STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -411,12 +413,14 @@ STATIC const mp_rom_map_elem_t re_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table); -STATIC const mp_obj_type_t re_type = { - { &mp_type_type }, - .name = MP_QSTR_ure, - .print = re_print, - .locals_dict = (void *)&re_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + re_type, + MP_QSTR_ure, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, re_print, + locals_dict, (void *)&re_locals_dict + ); #endif STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { diff --git a/extmod/moduselect.c b/extmod/moduselect.c index 70a1de2e4099..1a11ee0eab50 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -336,13 +336,15 @@ STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table); -STATIC const mp_obj_type_t mp_type_poll = { - { &mp_type_type }, - .name = MP_QSTR_poll, - .getiter = mp_identity_getiter, - .iternext = poll_iternext, - .locals_dict = (void *)&poll_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_poll, + MP_QSTR_poll, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, poll_iternext, + locals_dict, (void *)&poll_locals_dict + ); // poll() STATIC mp_obj_t select_poll(void) { diff --git a/extmod/modusocket.c b/extmod/modusocket.c index 4d72531160e6..6008edb11c76 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -528,14 +528,15 @@ STATIC const mp_stream_p_t socket_stream_p = { .is_text = false, }; -STATIC const mp_obj_type_t socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .print = socket_print, - .make_new = socket_make_new, - .protocol = &socket_stream_p, - .locals_dict = (mp_obj_dict_t *)&socket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + socket_type, + MP_QSTR_socket, + MP_TYPE_FLAG_NONE, + socket_make_new, + protocol, &socket_stream_p, + locals_dict, (mp_obj_dict_t *)&socket_locals_dict, + print, socket_print + ); /******************************************************************************/ // usocket module diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c index 9ba613a3e89e..72eb0e214fe3 100644 --- a/extmod/modussl_axtls.c +++ b/extmod/modussl_axtls.c @@ -314,16 +314,18 @@ STATIC const mp_stream_p_t ussl_socket_stream_p = { .ioctl = ussl_socket_ioctl, }; -STATIC const mp_obj_type_t ussl_socket_type = { - { &mp_type_type }, +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ussl_socket_type, + MP_QSTR_ussl, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module - .name = MP_QSTR_ussl, - .print = ussl_socket_print, - .getiter = NULL, - .iternext = NULL, - .protocol = &ussl_socket_stream_p, - .locals_dict = (void *)&ussl_socket_locals_dict, -}; + print, ussl_socket_print, + getiter, NULL, + iternext, NULL, + protocol, &ussl_socket_stream_p, + locals_dict, (void *)&ussl_socket_locals_dict + ); STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // TODO: Implement more args diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index b14ed9ad0e3d..0fab915f3f06 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -392,16 +392,18 @@ STATIC const mp_stream_p_t ussl_socket_stream_p = { .ioctl = socket_ioctl, }; -STATIC const mp_obj_type_t ussl_socket_type = { - { &mp_type_type }, +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ussl_socket_type, + MP_QSTR_ussl, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module - .name = MP_QSTR_ussl, - .print = socket_print, - .getiter = NULL, - .iternext = NULL, - .protocol = &ussl_socket_stream_p, - .locals_dict = (void *)&ussl_socket_locals_dict, -}; + print, socket_print, + getiter, NULL, + iternext, NULL, + protocol, &ussl_socket_stream_p, + locals_dict, (void *)&ussl_socket_locals_dict + ); STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // TODO: Implement more args diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index 1dde90bd1b02..bf4e031895fa 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -209,13 +209,14 @@ STATIC const mp_rom_map_elem_t utimeq_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(utimeq_locals_dict, utimeq_locals_dict_table); -STATIC const mp_obj_type_t utimeq_type = { - { &mp_type_type }, - .name = MP_QSTR_utimeq, - .make_new = utimeq_make_new, - .unary_op = utimeq_unary_op, - .locals_dict = (void *)&utimeq_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + utimeq_type, + MP_QSTR_utimeq, + MP_TYPE_FLAG_NONE, + utimeq_make_new, + unary_op, utimeq_unary_op, + locals_dict, (void *)&utimeq_locals_dict + ); STATIC const mp_rom_map_elem_t mp_module_utimeq_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utimeq) }, diff --git a/extmod/moduwebsocket.c b/extmod/moduwebsocket.c index a9ad0c22e3a5..2895978f3d5d 100644 --- a/extmod/moduwebsocket.c +++ b/extmod/moduwebsocket.c @@ -290,13 +290,14 @@ STATIC const mp_stream_p_t websocket_stream_p = { .ioctl = websocket_ioctl, }; -STATIC const mp_obj_type_t websocket_type = { - { &mp_type_type }, - .name = MP_QSTR_websocket, - .make_new = websocket_make_new, - .protocol = &websocket_stream_p, - .locals_dict = (void *)&websocket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + websocket_type, + MP_QSTR_websocket, + MP_TYPE_FLAG_NONE, + websocket_make_new, + protocol, &websocket_stream_p, + locals_dict, (void *)&websocket_locals_dict + ); STATIC const mp_rom_map_elem_t uwebsocket_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uwebsocket) }, diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 0161b9f49cdd..93c939129eab 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -140,13 +140,14 @@ STATIC const mp_stream_p_t decompio_stream_p = { }; #if !MICROPY_ENABLE_DYNRUNTIME -STATIC const mp_obj_type_t decompio_type = { - { &mp_type_type }, - .name = MP_QSTR_DecompIO, - .make_new = decompio_make_new, - .protocol = &decompio_stream_p, - .locals_dict = (void *)&decompio_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + decompio_type, + MP_QSTR_DecompIO, + MP_TYPE_FLAG_NONE, + decompio_make_new, + protocol, &decompio_stream_p, + locals_dict, (void *)&decompio_locals_dict + ); #endif STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index 1a2a718acfab..cb893b38dcbe 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -342,13 +342,14 @@ STATIC const mp_stream_p_t webrepl_stream_p = { .ioctl = webrepl_ioctl, }; -STATIC const mp_obj_type_t webrepl_type = { - { &mp_type_type }, - .name = MP_QSTR__webrepl, - .make_new = webrepl_make_new, - .protocol = &webrepl_stream_p, - .locals_dict = (mp_obj_dict_t *)&webrepl_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + webrepl_type, + MP_QSTR__webrepl, + MP_TYPE_FLAG_NONE, + webrepl_make_new, + protocol, &webrepl_stream_p, + locals_dict, (mp_obj_dict_t *)&webrepl_locals_dict + ); STATIC const mp_rom_map_elem_t webrepl_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__webrepl) }, diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index 9df799119fe6..fbd0a750b8e6 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -496,12 +496,13 @@ STATIC const mp_rom_map_elem_t network_cyw43_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(network_cyw43_locals_dict, network_cyw43_locals_dict_table); -const mp_obj_type_t mp_network_cyw43_type = { - { &mp_type_type }, - .name = MP_QSTR_CYW43, - .print = network_cyw43_print, - .make_new = network_cyw43_make_new, - .locals_dict = (mp_obj_dict_t *)&network_cyw43_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_network_cyw43_type, + MP_QSTR_CYW43, + MP_TYPE_FLAG_NONE, + network_cyw43_make_new, + print, network_cyw43_print, + locals_dict, (mp_obj_dict_t *)&network_cyw43_locals_dict + ); #endif // MICROPY_PY_NETWORK_CYW43 diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c index 4014a71c1acf..0906176d20b0 100644 --- a/extmod/network_ninaw10.c +++ b/extmod/network_ninaw10.c @@ -774,13 +774,16 @@ static const mp_rom_map_elem_t nina_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(nina_locals_dict, nina_locals_dict_table); +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mod_network_nic_type_nina_base, + MP_QSTR_nina, + MP_TYPE_FLAG_NONE, + network_ninaw10_make_new, + locals_dict, &nina_locals_dict + ); + const mod_network_nic_type_t mod_network_nic_type_nina = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_nina, - .make_new = network_ninaw10_make_new, - .locals_dict = (mp_obj_t)&nina_locals_dict, - }, + .base = mod_network_nic_type_nina_base, .gethostbyname = network_ninaw10_gethostbyname, .socket = network_ninaw10_socket_socket, .close = network_ninaw10_socket_close, diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 95c852d7f729..951a2966c93f 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -1016,20 +1016,24 @@ STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); #if WIZNET5K_WITH_LWIP_STACK -const mp_obj_type_t mod_network_nic_type_wiznet5k = { - { &mp_type_type }, - .name = MP_QSTR_WIZNET5K, - .make_new = wiznet5k_make_new, - .locals_dict = (mp_obj_dict_t *)&wiznet5k_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mod_network_nic_type_wiznet5k, + MP_QSTR_WIZNET5K, + MP_TYPE_FLAG_NONE, + wiznet5k_make_new, + locals_dict, &wiznet5k_locals_dict + ); #else // WIZNET5K_PROVIDED_STACK +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mod_network_nic_type_wiznet5k_base, + MP_QSTR_WIZNET5K, + MP_TYPE_FLAG_NONE, + wiznet5k_make_new, + locals_dict, &wiznet5k_locals_dict + ); + const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_WIZNET5K, - .make_new = wiznet5k_make_new, - .locals_dict = (mp_obj_dict_t *)&wiznet5k_locals_dict, - }, + .base = mod_network_nic_type_wiznet5k_base, .gethostbyname = wiznet5k_gethostbyname, .socket = wiznet5k_socket_socket, .close = wiznet5k_socket_close, diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 8d2f13be476d..4a2ef883c26c 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -431,12 +431,13 @@ STATIC const mp_vfs_proto_t fat_vfs_proto = { .import_stat = fat_vfs_import_stat, }; -const mp_obj_type_t mp_fat_vfs_type = { - { &mp_type_type }, - .name = MP_QSTR_VfsFat, - .make_new = fat_vfs_make_new, - .protocol = &fat_vfs_proto, - .locals_dict = (mp_obj_dict_t *)&fat_vfs_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_fat_vfs_type, + MP_QSTR_VfsFat, + MP_TYPE_FLAG_NONE, + fat_vfs_make_new, + protocol, &fat_vfs_proto, + locals_dict, (mp_obj_dict_t *)&fat_vfs_locals_dict + ); #endif // MICROPY_VFS_FAT diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 874f10c50045..0d4af09b452c 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -176,15 +176,17 @@ STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = { .ioctl = file_obj_ioctl, }; -const mp_obj_type_t mp_type_vfs_fat_fileio = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .print = file_obj_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &vfs_fat_fileio_stream_p, - .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_fat_fileio, + MP_QSTR_FileIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, file_obj_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &vfs_fat_fileio_stream_p, + locals_dict, (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict + ); STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { .read = file_obj_read, @@ -193,15 +195,17 @@ STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { .is_text = true, }; -const mp_obj_type_t mp_type_vfs_fat_textio = { - { &mp_type_type }, - .name = MP_QSTR_TextIOWrapper, - .print = file_obj_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &vfs_fat_textio_stream_p, - .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_fat_textio, + MP_QSTR_TextIOWrapper, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, file_obj_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &vfs_fat_textio_stream_p, + locals_dict, (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict + ); // Factory function for I/O stream classes STATIC mp_obj_t fat_vfs_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in) { diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index fbfeaa5ccf1a..72c6696105d9 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -502,14 +502,15 @@ STATIC const mp_vfs_proto_t MP_VFS_LFSx(proto) = { .import_stat = MP_VFS_LFSx(import_stat), }; -const mp_obj_type_t MP_TYPE_VFS_LFSx = { - { &mp_type_type }, +MP_DEFINE_CONST_OBJ_TYPE( + MP_TYPE_VFS_LFSx, #if LFS_BUILD_VERSION == 1 - .name = MP_QSTR_VfsLfs1, + MP_QSTR_VfsLfs1, #else - .name = MP_QSTR_VfsLfs2, + MP_QSTR_VfsLfs2, #endif - .make_new = MP_VFS_LFSx(make_new), - .protocol = &MP_VFS_LFSx(proto), - .locals_dict = (mp_obj_dict_t *)&MP_VFS_LFSx(locals_dict), -}; + MP_TYPE_FLAG_NONE, + MP_VFS_LFSx(make_new), + protocol, &MP_VFS_LFSx(proto), + locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(locals_dict) + ); diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c index 124361feb99f..ba90cc608443 100644 --- a/extmod/vfs_lfsx_file.c +++ b/extmod/vfs_lfsx_file.c @@ -220,15 +220,17 @@ STATIC const mp_stream_p_t MP_VFS_LFSx(fileio_stream_p) = { .ioctl = MP_VFS_LFSx(file_ioctl), }; -const mp_obj_type_t MP_TYPE_VFS_LFSx_(_fileio) = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .print = MP_VFS_LFSx(file_print), - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &MP_VFS_LFSx(fileio_stream_p), - .locals_dict = (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict), -}; +MP_DEFINE_CONST_OBJ_TYPE( + MP_TYPE_VFS_LFSx_(_fileio), + MP_QSTR_FileIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, MP_VFS_LFSx(file_print), + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &MP_VFS_LFSx(fileio_stream_p), + locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict) + ); STATIC const mp_stream_p_t MP_VFS_LFSx(textio_stream_p) = { .read = MP_VFS_LFSx(file_read), @@ -237,12 +239,14 @@ STATIC const mp_stream_p_t MP_VFS_LFSx(textio_stream_p) = { .is_text = true, }; -const mp_obj_type_t MP_TYPE_VFS_LFSx_(_textio) = { - { &mp_type_type }, - .name = MP_QSTR_TextIOWrapper, - .print = MP_VFS_LFSx(file_print), - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &MP_VFS_LFSx(textio_stream_p), - .locals_dict = (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict), -}; +MP_DEFINE_CONST_OBJ_TYPE( + MP_TYPE_VFS_LFSx_(_textio), + MP_QSTR_TextIOWrapper, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, MP_VFS_LFSx(file_print), + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &MP_VFS_LFSx(textio_stream_p), + locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict) + ); diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 36b211b84d6b..79126c007068 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -398,12 +398,13 @@ STATIC const mp_vfs_proto_t vfs_posix_proto = { .import_stat = mp_vfs_posix_import_stat, }; -const mp_obj_type_t mp_type_vfs_posix = { - { &mp_type_type }, - .name = MP_QSTR_VfsPosix, - .make_new = vfs_posix_make_new, - .protocol = &vfs_posix_proto, - .locals_dict = (mp_obj_dict_t *)&vfs_posix_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_posix, + MP_QSTR_VfsPosix, + MP_TYPE_FLAG_NONE, + vfs_posix_make_new, + protocol, &vfs_posix_proto, + locals_dict, (mp_obj_dict_t *)&vfs_posix_locals_dict + ); #endif // MICROPY_VFS_POSIX diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index c550842cd4e8..85aef1617b80 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -249,15 +249,17 @@ STATIC const mp_stream_p_t vfs_posix_fileio_stream_p = { .ioctl = vfs_posix_file_ioctl, }; -const mp_obj_type_t mp_type_vfs_posix_fileio = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .print = vfs_posix_file_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &vfs_posix_fileio_stream_p, - .locals_dict = (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_posix_fileio, + MP_QSTR_FileIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, vfs_posix_file_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &vfs_posix_fileio_stream_p, + locals_dict, (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict + ); STATIC const mp_stream_p_t vfs_posix_textio_stream_p = { .read = vfs_posix_file_read, @@ -266,15 +268,17 @@ STATIC const mp_stream_p_t vfs_posix_textio_stream_p = { .is_text = true, }; -const mp_obj_type_t mp_type_vfs_posix_textio = { - { &mp_type_type }, - .name = MP_QSTR_TextIOWrapper, - .print = vfs_posix_file_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &vfs_posix_textio_stream_p, - .locals_dict = (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_posix_textio, + MP_QSTR_TextIOWrapper, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, vfs_posix_file_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &vfs_posix_textio_stream_p, + locals_dict, (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict + ); const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, STDIN_FILENO}; const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO}; diff --git a/ports/cc3200/misc/mpirq.c b/ports/cc3200/misc/mpirq.c index eb93e5eef0cc..e9cae92a327e 100644 --- a/ports/cc3200/misc/mpirq.c +++ b/ports/cc3200/misc/mpirq.c @@ -190,11 +190,13 @@ STATIC const mp_rom_map_elem_t mp_irq_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(mp_irq_locals_dict, mp_irq_locals_dict_table); -const mp_obj_type_t mp_irq_type = { - { &mp_type_type }, - .name = MP_QSTR_irq, - .call = mp_irq_call, - .locals_dict = (mp_obj_t)&mp_irq_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_irq_type, + MP_QSTR_irq, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + call, mp_irq_call, + locals_dict, (mp_obj_t)&mp_irq_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_list_t mp_irq_obj_list); diff --git a/ports/cc3200/mods/modnetwork.c b/ports/cc3200/mods/modnetwork.c index d6ccc7c6a04d..a74189300775 100644 --- a/ports/cc3200/mods/modnetwork.c +++ b/ports/cc3200/mods/modnetwork.c @@ -171,10 +171,11 @@ STATIC const mp_rom_map_elem_t network_server_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(network_server_locals_dict, network_server_locals_dict_table); -STATIC const mp_obj_type_t network_server_type = { - { &mp_type_type }, - .name = MP_QSTR_Server, - .make_new = network_server_make_new, - .locals_dict = (mp_obj_t)&network_server_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + network_server_type, + MP_QSTR_Server, + MP_TYPE_FLAG_NONE, + network_server_make_new, + locals_dict, (mp_obj_t)&network_server_locals_dict + ); #endif diff --git a/ports/cc3200/mods/moduhashlib.c b/ports/cc3200/mods/moduhashlib.c index fc11569b7f98..5437cfb264e6 100644 --- a/ports/cc3200/mods/moduhashlib.c +++ b/ports/cc3200/mods/moduhashlib.c @@ -177,19 +177,21 @@ STATIC MP_DEFINE_CONST_DICT(hash_locals_dict, hash_locals_dict_table); // .locals_dict = (mp_obj_t)&hash_locals_dict, //}; -STATIC const mp_obj_type_t sha1_type = { - { &mp_type_type }, - .name = MP_QSTR_sha1, - .make_new = hash_make_new, - .locals_dict = (mp_obj_t)&hash_locals_dict, -}; - -STATIC const mp_obj_type_t sha256_type = { - { &mp_type_type }, - .name = MP_QSTR_sha256, - .make_new = hash_make_new, - .locals_dict = (mp_obj_t)&hash_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + sha1_type, + MP_QSTR_sha1, + MP_TYPE_FLAG_NONE, + hash_make_new, + locals_dict, (mp_obj_t)&hash_locals_dict + ); + +STATIC MP_DEFINE_CONST_OBJ_TYPE( + sha256_type, + MP_QSTR_sha256, + MP_TYPE_FLAG_NONE, + hash_make_new, + locals_dict, (mp_obj_t)&hash_locals_dict + ); STATIC const mp_rom_map_elem_t mp_module_hashlib_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uhashlib) }, diff --git a/ports/cc3200/mods/modusocket.c b/ports/cc3200/mods/modusocket.c index 23982eb96602..11199de14628 100644 --- a/ports/cc3200/mods/modusocket.c +++ b/ports/cc3200/mods/modusocket.c @@ -759,13 +759,14 @@ const mp_stream_p_t socket_stream_p = { .is_text = false, }; -STATIC const mp_obj_type_t socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .make_new = socket_make_new, - .protocol = &socket_stream_p, - .locals_dict = (mp_obj_t)&socket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + socket_type, + MP_QSTR_socket, + MP_TYPE_FLAG_NONE, + socket_make_new, + protocol, &socket_stream_p, + locals_dict, (mp_obj_t)&socket_locals_dict + ); /******************************************************************************/ // usocket module diff --git a/ports/cc3200/mods/modussl.c b/ports/cc3200/mods/modussl.c index cd2c62dcb82e..d0909e7c2909 100644 --- a/ports/cc3200/mods/modussl.c +++ b/ports/cc3200/mods/modussl.c @@ -60,14 +60,16 @@ STATIC const mp_obj_type_t ssl_socket_type; // ssl sockets inherit from normal socket, so we take its // locals and stream methods -STATIC const mp_obj_type_t ssl_socket_type = { - { &mp_type_type }, - .name = MP_QSTR_ussl, - .getiter = NULL, - .iternext = NULL, - .protocol = &socket_stream_p, - .locals_dict = (mp_obj_t)&socket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ssl_socket_type, + MP_QSTR_ussl, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, NULL, + iternext, NULL, + protocol, &socket_stream_p, + locals_dict, (mp_obj_t)&socket_locals_dict + ); STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC const mp_arg_t allowed_args[] = { diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c index 3b686932e81d..24f5d196d2a3 100644 --- a/ports/cc3200/mods/modwlan.c +++ b/ports/cc3200/mods/modwlan.c @@ -1285,13 +1285,16 @@ STATIC const mp_rom_map_elem_t wlan_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table); +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mod_network_nic_type_wlan_base, + MP_QSTR_WLAN, + MP_TYPE_FLAG_NONE, + wlan_make_new, + locals_dict, (mp_obj_t)&wlan_locals_dict + ); + const mod_network_nic_type_t mod_network_nic_type_wlan = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_WLAN, - .make_new = wlan_make_new, - .locals_dict = (mp_obj_t)&wlan_locals_dict, - }, + .base = mod_network_nic_type_wlan_base, }; STATIC const mp_irq_methods_t wlan_irq_methods = { diff --git a/ports/cc3200/mods/pybadc.c b/ports/cc3200/mods/pybadc.c index fbdd393cd2ec..a114eeda169a 100644 --- a/ports/cc3200/mods/pybadc.c +++ b/ports/cc3200/mods/pybadc.c @@ -233,13 +233,14 @@ STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table); -const mp_obj_type_t pyb_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = adc_print, - .make_new = adc_make_new, - .locals_dict = (mp_obj_t)&adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + adc_make_new, + print, adc_print, + locals_dict, (mp_obj_t)&adc_locals_dict + ); STATIC void adc_channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_adc_channel_obj_t *self = self_in; @@ -300,10 +301,12 @@ STATIC const mp_rom_map_elem_t adc_channel_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(adc_channel_locals_dict, adc_channel_locals_dict_table); -STATIC const mp_obj_type_t pyb_adc_channel_type = { - { &mp_type_type }, - .name = MP_QSTR_ADCChannel, - .print = adc_channel_print, - .call = adc_channel_call, - .locals_dict = (mp_obj_t)&adc_channel_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pyb_adc_channel_type, + MP_QSTR_ADCChannel, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, adc_channel_print, + call, adc_channel_call, + locals_dict, (mp_obj_t)&adc_channel_locals_dict + ); diff --git a/ports/cc3200/mods/pybflash.c b/ports/cc3200/mods/pybflash.c index 9d534608becc..4cfafb7abf64 100644 --- a/ports/cc3200/mods/pybflash.c +++ b/ports/cc3200/mods/pybflash.c @@ -84,12 +84,13 @@ STATIC const mp_rom_map_elem_t pyb_flash_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table); -const mp_obj_type_t pyb_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .make_new = pyb_flash_make_new, - .locals_dict = (mp_obj_t)&pyb_flash_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_flash_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + pyb_flash_make_new, + locals_dict, (mp_obj_t)&pyb_flash_locals_dict + ); void pyb_flash_init_vfs(fs_user_mount_t *vfs) { vfs->base.type = &mp_fat_vfs_type; diff --git a/ports/cc3200/mods/pybi2c.c b/ports/cc3200/mods/pybi2c.c index 40b3e2a20714..91a0b9b9f9a9 100644 --- a/ports/cc3200/mods/pybi2c.c +++ b/ports/cc3200/mods/pybi2c.c @@ -521,10 +521,11 @@ STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table); -const mp_obj_type_t pyb_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = pyb_i2c_print, - .make_new = pyb_i2c_make_new, - .locals_dict = (mp_obj_t)&pyb_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + pyb_i2c_make_new, + print, pyb_i2c_print, + locals_dict, (mp_obj_t)&pyb_i2c_locals_dict + ); diff --git a/ports/cc3200/mods/pybpin.c b/ports/cc3200/mods/pybpin.c index fd2f032e8d7c..948cda70d4ab 100644 --- a/ports/cc3200/mods/pybpin.c +++ b/ports/cc3200/mods/pybpin.c @@ -931,14 +931,15 @@ STATIC const mp_rom_map_elem_t pin_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table); -const mp_obj_type_t pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = pin_print, - .make_new = pin_make_new, - .call = pin_call, - .locals_dict = (mp_obj_t)&pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + pin_make_new, + print, pin_print, + call, pin_call, + locals_dict, (mp_obj_t)&pin_locals_dict + ); STATIC const mp_irq_methods_t pin_irq_methods = { .init = pin_irq, @@ -952,10 +953,12 @@ STATIC void pin_named_pins_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_printf(print, "", self->name); } -const mp_obj_type_t pin_board_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_board, - .print = pin_named_pins_obj_print, - .locals_dict = (mp_obj_t)&pin_board_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_board_pins_obj_type, + MP_QSTR_board, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pin_named_pins_obj_print, + locals_dict, (mp_obj_t)&pin_board_pins_locals_dict + ); diff --git a/ports/cc3200/mods/pybrtc.c b/ports/cc3200/mods/pybrtc.c index 6c1918831c8c..2761cb3c64f5 100644 --- a/ports/cc3200/mods/pybrtc.c +++ b/ports/cc3200/mods/pybrtc.c @@ -469,12 +469,13 @@ STATIC const mp_rom_map_elem_t pyb_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table); -const mp_obj_type_t pyb_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = pyb_rtc_make_new, - .locals_dict = (mp_obj_t)&pyb_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + pyb_rtc_make_new, + locals_dict, (mp_obj_t)&pyb_rtc_locals_dict + ); STATIC const mp_irq_methods_t pyb_rtc_irq_methods = { .init = pyb_rtc_irq, diff --git a/ports/cc3200/mods/pybsd.c b/ports/cc3200/mods/pybsd.c index 817127634d89..d8834e36f744 100644 --- a/ports/cc3200/mods/pybsd.c +++ b/ports/cc3200/mods/pybsd.c @@ -212,9 +212,10 @@ STATIC const mp_rom_map_elem_t pyb_sd_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table); -const mp_obj_type_t pyb_sd_type = { - { &mp_type_type }, - .name = MP_QSTR_SD, - .make_new = pyb_sd_make_new, - .locals_dict = (mp_obj_t)&pyb_sd_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_sd_type, + MP_QSTR_SD, + MP_TYPE_FLAG_NONE, + pyb_sd_make_new, + locals_dict, (mp_obj_t)&pyb_sd_locals_dict + ); diff --git a/ports/cc3200/mods/pybsleep.c b/ports/cc3200/mods/pybsleep.c index 76fe0849a4bc..423099991f8d 100644 --- a/ports/cc3200/mods/pybsleep.c +++ b/ports/cc3200/mods/pybsleep.c @@ -125,10 +125,12 @@ STATIC pybsleep_data_t pybsleep_data = {NULL, NULL, NULL}; volatile arm_cm4_core_regs_t vault_arm_registers; STATIC pybsleep_reset_cause_t pybsleep_reset_cause = PYB_SLP_PWRON_RESET; STATIC pybsleep_wake_reason_t pybsleep_wake_reason = PYB_SLP_WAKED_PWRON; -STATIC const mp_obj_type_t pyb_sleep_type = { - { &mp_type_type }, - .name = MP_QSTR_sleep, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pyb_sleep_type, + MP_QSTR_sleep, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW + ); /****************************************************************************** DECLARE PRIVATE FUNCTIONS diff --git a/ports/cc3200/mods/pybspi.c b/ports/cc3200/mods/pybspi.c index ed03b0906081..50d897633e55 100644 --- a/ports/cc3200/mods/pybspi.c +++ b/ports/cc3200/mods/pybspi.c @@ -377,10 +377,11 @@ STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table); -const mp_obj_type_t pyb_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = pyb_spi_print, - .make_new = pyb_spi_make_new, - .locals_dict = (mp_obj_t)&pyb_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + pyb_spi_make_new, + print, pyb_spi_print, + locals_dict, (mp_obj_t)&pyb_spi_locals_dict + ); diff --git a/ports/cc3200/mods/pybtimer.c b/ports/cc3200/mods/pybtimer.c index b2725ae16653..a8bc7821e0ce 100644 --- a/ports/cc3200/mods/pybtimer.c +++ b/ports/cc3200/mods/pybtimer.c @@ -459,13 +459,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table); -const mp_obj_type_t pyb_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = pyb_timer_print, - .make_new = pyb_timer_make_new, - .locals_dict = (mp_obj_t)&pyb_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + pyb_timer_make_new, + print, pyb_timer_print, + locals_dict, (mp_obj_t)&pyb_timer_locals_dict + ); STATIC const mp_irq_methods_t pyb_timer_channel_irq_methods = { .init = pyb_timer_channel_irq, @@ -721,11 +722,13 @@ STATIC const mp_rom_map_elem_t pyb_timer_channel_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_channel_locals_dict, pyb_timer_channel_locals_dict_table); -STATIC const mp_obj_type_t pyb_timer_channel_type = { - { &mp_type_type }, - .name = MP_QSTR_TimerChannel, - .print = pyb_timer_channel_print, - .locals_dict = (mp_obj_t)&pyb_timer_channel_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_channel_type, + MP_QSTR_TimerChannel, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pyb_timer_channel_print, + locals_dict, (mp_obj_t)&pyb_timer_channel_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_list_t pyb_timer_channel_obj_list); diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c index a81954abb8b5..059101f4f205 100644 --- a/ports/cc3200/mods/pybuart.c +++ b/ports/cc3200/mods/pybuart.c @@ -685,15 +685,16 @@ STATIC const mp_irq_methods_t uart_irq_methods = { .flags = uart_irq_flags }; -const mp_obj_type_t pyb_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = pyb_uart_print, - .make_new = pyb_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_t)&pyb_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + pyb_uart_make_new, + print, pyb_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_t)&pyb_uart_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _pyb_uart_obj_t *pyb_uart_objs[2]); diff --git a/ports/cc3200/mods/pybwdt.c b/ports/cc3200/mods/pybwdt.c index 8db096d6b5fc..cde1abe59d89 100644 --- a/ports/cc3200/mods/pybwdt.c +++ b/ports/cc3200/mods/pybwdt.c @@ -150,10 +150,11 @@ STATIC const mp_rom_map_elem_t pybwdt_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pybwdt_locals_dict, pybwdt_locals_dict_table); -const mp_obj_type_t pyb_wdt_type = { - { &mp_type_type }, - .name = MP_QSTR_WDT, - .make_new = pyb_wdt_make_new, - .locals_dict = (mp_obj_t)&pybwdt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + pyb_wdt_make_new, + locals_dict, (mp_obj_t)&pybwdt_locals_dict + ); diff --git a/ports/esp32/esp32_nvs.c b/ports/esp32/esp32_nvs.c index 42d65be4a63b..1f96ad129d11 100644 --- a/ports/esp32/esp32_nvs.c +++ b/ports/esp32/esp32_nvs.c @@ -141,10 +141,11 @@ STATIC const mp_rom_map_elem_t esp32_nvs_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(esp32_nvs_locals_dict, esp32_nvs_locals_dict_table); -const mp_obj_type_t esp32_nvs_type = { - { &mp_type_type }, - .name = MP_QSTR_NVS, - .print = esp32_nvs_print, - .make_new = esp32_nvs_make_new, - .locals_dict = (mp_obj_dict_t *)&esp32_nvs_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + esp32_nvs_type, + MP_QSTR_NVS, + MP_TYPE_FLAG_NONE, + esp32_nvs_make_new, + print, esp32_nvs_print, + locals_dict, (mp_obj_dict_t *)&esp32_nvs_locals_dict + ); diff --git a/ports/esp32/esp32_partition.c b/ports/esp32/esp32_partition.c index 47e769486c9b..2e42e7a81903 100644 --- a/ports/esp32/esp32_partition.c +++ b/ports/esp32/esp32_partition.c @@ -284,10 +284,11 @@ STATIC const mp_rom_map_elem_t esp32_partition_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(esp32_partition_locals_dict, esp32_partition_locals_dict_table); -const mp_obj_type_t esp32_partition_type = { - { &mp_type_type }, - .name = MP_QSTR_Partition, - .print = esp32_partition_print, - .make_new = esp32_partition_make_new, - .locals_dict = (mp_obj_dict_t *)&esp32_partition_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + esp32_partition_type, + MP_QSTR_Partition, + MP_TYPE_FLAG_NONE, + esp32_partition_make_new, + print, esp32_partition_print, + locals_dict, (mp_obj_dict_t *)&esp32_partition_locals_dict + ); diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index ac897e33368a..36f33df3f5d4 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -372,10 +372,11 @@ STATIC const mp_rom_map_elem_t esp32_rmt_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(esp32_rmt_locals_dict, esp32_rmt_locals_dict_table); -const mp_obj_type_t esp32_rmt_type = { - { &mp_type_type }, - .name = MP_QSTR_RMT, - .print = esp32_rmt_print, - .make_new = esp32_rmt_make_new, - .locals_dict = (mp_obj_dict_t *)&esp32_rmt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + esp32_rmt_type, + MP_QSTR_RMT, + MP_TYPE_FLAG_NONE, + esp32_rmt_make_new, + print, esp32_rmt_print, + locals_dict, (mp_obj_dict_t *)&esp32_rmt_locals_dict + ); diff --git a/ports/esp32/esp32_ulp.c b/ports/esp32/esp32_ulp.c index 8e4ce9c5a41b..5eb0e5591e7e 100644 --- a/ports/esp32/esp32_ulp.c +++ b/ports/esp32/esp32_ulp.c @@ -91,11 +91,12 @@ STATIC const mp_rom_map_elem_t esp32_ulp_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(esp32_ulp_locals_dict, esp32_ulp_locals_dict_table); -const mp_obj_type_t esp32_ulp_type = { - { &mp_type_type }, - .name = MP_QSTR_ULP, - .make_new = esp32_ulp_make_new, - .locals_dict = (mp_obj_t)&esp32_ulp_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + esp32_ulp_type, + MP_QSTR_ULP, + MP_TYPE_FLAG_NONE, + esp32_ulp_make_new, + locals_dict, (mp_obj_t)&esp32_ulp_locals_dict + ); #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c index cb45aab33910..5cc2d8038491 100644 --- a/ports/esp32/machine_adc.c +++ b/ports/esp32/machine_adc.c @@ -256,10 +256,11 @@ STATIC const mp_rom_map_elem_t madc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(madc_locals_dict, madc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = madc_print, - .make_new = madc_make_new, - .locals_dict = (mp_obj_t)&madc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + madc_make_new, + print, madc_print, + locals_dict, (mp_obj_t)&madc_locals_dict + ); diff --git a/ports/esp32/machine_adcblock.c b/ports/esp32/machine_adcblock.c index 06c215f8ae73..770839e93e1b 100644 --- a/ports/esp32/machine_adcblock.c +++ b/ports/esp32/machine_adcblock.c @@ -194,10 +194,11 @@ STATIC const mp_rom_map_elem_t madcblock_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(madcblock_locals_dict, madcblock_locals_dict_table); -const mp_obj_type_t machine_adcblock_type = { - { &mp_type_type }, - .name = MP_QSTR_ADCBlock, - .print = madcblock_print, - .make_new = madcblock_make_new, - .locals_dict = (mp_obj_t)&madcblock_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adcblock_type, + MP_QSTR_ADCBlock, + MP_TYPE_FLAG_NONE, + madcblock_make_new, + print, madcblock_print, + locals_dict, (mp_obj_dict_t *)&madcblock_locals_dict + ); diff --git a/ports/esp32/machine_dac.c b/ports/esp32/machine_dac.c index 35826d4a99a8..c9b9c14e01e7 100644 --- a/ports/esp32/machine_dac.c +++ b/ports/esp32/machine_dac.c @@ -104,12 +104,13 @@ STATIC const mp_rom_map_elem_t mdac_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(mdac_locals_dict, mdac_locals_dict_table); -const mp_obj_type_t machine_dac_type = { - { &mp_type_type }, - .name = MP_QSTR_DAC, - .print = mdac_print, - .make_new = mdac_make_new, - .locals_dict = (mp_obj_t)&mdac_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_dac_type, + MP_QSTR_DAC, + MP_TYPE_FLAG_NONE, + mdac_make_new, + print, mdac_print, + locals_dict, (mp_obj_t)&mdac_locals_dict + ); #endif // MICROPY_PY_MACHINE_DAC diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 3e720adb1a5e..71583ef60e90 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -545,11 +545,12 @@ STATIC const mp_machine_spi_p_t machine_hw_spi_p = { .transfer = machine_hw_spi_transfer, }; -const mp_obj_type_t machine_hw_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_hw_spi_print, - .make_new = machine_hw_spi_make_new, - .protocol = &machine_hw_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hw_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_hw_spi_make_new, + print, machine_hw_spi_print, + protocol, &machine_hw_spi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index e25cad0b60a5..9e5be606dbf9 100644 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -192,11 +192,12 @@ STATIC const mp_machine_i2c_p_t machine_hw_i2c_p = { .transfer = machine_hw_i2c_transfer, }; -const mp_obj_type_t machine_hw_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_hw_i2c_print, - .make_new = machine_hw_i2c_make_new, - .protocol = &machine_hw_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hw_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_hw_i2c_make_new, + print, machine_hw_i2c_print, + protocol, &machine_hw_i2c_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + ); diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index 933e68684b9e..d30fb5d836e7 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -829,16 +829,17 @@ STATIC const mp_stream_p_t i2s_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_i2s_type = { - { &mp_type_type }, - .name = MP_QSTR_I2S, - .print = machine_i2s_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &i2s_stream_p, - .make_new = machine_i2s_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_i2s_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_i2s_type, + MP_QSTR_I2S, + MP_TYPE_FLAG_NONE, + machine_i2s_make_new, + print, machine_i2s_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &i2s_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_MAX]); diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index b57562633878..1a1a3a0f8d17 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -529,15 +529,16 @@ STATIC const mp_pin_p_t pin_pin_p = { .ioctl = pin_ioctl, }; -const mp_obj_type_t machine_pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = machine_pin_print, - .make_new = mp_pin_make_new, - .call = machine_pin_call, - .protocol = &pin_pin_p, - .locals_dict = (mp_obj_t)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, machine_pin_print, + call, machine_pin_call, + protocol, &pin_pin_p, + locals_dict, (mp_obj_t)&machine_pin_locals_dict + ); /******************************************************************************/ // Pin IRQ object @@ -723,11 +724,13 @@ STATIC const mp_rom_map_elem_t machine_pin_irq_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_pin_irq_locals_dict, machine_pin_irq_locals_dict_table); -STATIC const mp_obj_type_t machine_pin_irq_type = { - { &mp_type_type }, - .name = MP_QSTR_IRQ, - .call = machine_pin_irq_call, - .locals_dict = (mp_obj_dict_t *)&machine_pin_irq_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_irq_type, + MP_QSTR_IRQ, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + call, machine_pin_irq_call, + locals_dict, (mp_obj_dict_t *)&machine_pin_irq_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_t machine_pin_irq_handler[40]); diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index 72d7b5c8280a..6634bf5b03b9 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -173,9 +173,10 @@ STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); -const mp_obj_type_t machine_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = machine_rtc_make_new, - .locals_dict = (mp_obj_t)&machine_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + machine_rtc_make_new, + locals_dict, (mp_obj_t)&machine_rtc_locals_dict + ); diff --git a/ports/esp32/machine_sdcard.c b/ports/esp32/machine_sdcard.c index 3f94356adbb4..2d5663d476e8 100644 --- a/ports/esp32/machine_sdcard.c +++ b/ports/esp32/machine_sdcard.c @@ -399,11 +399,12 @@ STATIC const mp_rom_map_elem_t machine_sdcard_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(machine_sdcard_locals_dict, machine_sdcard_locals_dict_table); -const mp_obj_type_t machine_sdcard_type = { - { &mp_type_type }, - .name = MP_QSTR_SDCard, - .make_new = machine_sdcard_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_sdcard_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_sdcard_type, + MP_QSTR_SDCard, + MP_TYPE_FLAG_NONE, + machine_sdcard_make_new, + locals_dict, (mp_obj_dict_t *)&machine_sdcard_locals_dict + ); #endif // MICROPY_HW_ENABLE_SDCARD diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 66969b3a954f..3b1295095593 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -277,12 +277,13 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); -const mp_obj_type_t machine_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = machine_timer_print, - .make_new = machine_timer_make_new, - .locals_dict = (mp_obj_t)&machine_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + machine_timer_make_new, + print, machine_timer_print, + locals_dict, (mp_obj_t)&machine_timer_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _machine_timer_obj_t *machine_timer_obj_head); diff --git a/ports/esp32/machine_touchpad.c b/ports/esp32/machine_touchpad.c index 168ac16d0eef..c5e3483b74a0 100644 --- a/ports/esp32/machine_touchpad.c +++ b/ports/esp32/machine_touchpad.c @@ -134,11 +134,12 @@ STATIC const mp_rom_map_elem_t mtp_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(mtp_locals_dict, mtp_locals_dict_table); -const mp_obj_type_t machine_touchpad_type = { - { &mp_type_type }, - .name = MP_QSTR_TouchPad, - .make_new = mtp_make_new, - .locals_dict = (mp_obj_t)&mtp_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_touchpad_type, + MP_QSTR_TouchPad, + MP_TYPE_FLAG_NONE, + mtp_make_new, + locals_dict, (mp_obj_t)&mtp_locals_dict + ); #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 72445912897f..9df16ae41983 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -530,13 +530,14 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = machine_uart_print, - .make_new = machine_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&machine_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + machine_uart_make_new, + print, machine_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + ); diff --git a/ports/esp32/machine_wdt.c b/ports/esp32/machine_wdt.c index f0ec6928e05d..c2898c7fe158 100644 --- a/ports/esp32/machine_wdt.c +++ b/ports/esp32/machine_wdt.c @@ -83,9 +83,10 @@ STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); -const mp_obj_type_t machine_wdt_type = { - { &mp_type_type }, - .name = MP_QSTR_WDT, - .make_new = machine_wdt_make_new, - .locals_dict = (mp_obj_t)&machine_wdt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + machine_wdt_make_new, + locals_dict, (mp_obj_t)&machine_wdt_locals_dict + ); diff --git a/ports/esp32/modsocket.c b/ports/esp32/modsocket.c index a281558241dc..a2dcb3946cea 100644 --- a/ports/esp32/modsocket.c +++ b/ports/esp32/modsocket.c @@ -785,13 +785,14 @@ STATIC const mp_stream_p_t socket_stream_p = { .ioctl = socket_stream_ioctl }; -STATIC const mp_obj_type_t socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .make_new = socket_make_new, - .protocol = &socket_stream_p, - .locals_dict = (mp_obj_t)&socket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + socket_type, + MP_QSTR_socket, + MP_TYPE_FLAG_NONE, + socket_make_new, + protocol, &socket_stream_p, + locals_dict, (mp_obj_t)&socket_locals_dict + ); STATIC mp_obj_t esp_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { // TODO support additional args beyond the first two diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c index f302d70fec1d..fc50e13c48ed 100644 --- a/ports/esp32/network_lan.c +++ b/ports/esp32/network_lan.c @@ -302,10 +302,12 @@ STATIC const mp_rom_map_elem_t lan_if_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(lan_if_locals_dict, lan_if_locals_dict_table); -const mp_obj_type_t lan_if_type = { - { &mp_type_type }, - .name = MP_QSTR_LAN, - .locals_dict = (mp_obj_dict_t *)&lan_if_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + lan_if_type, + MP_QSTR_LAN, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&lan_if_locals_dict + ); #endif diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c index d74283c19cf6..d6368d9f2038 100644 --- a/ports/esp32/network_ppp.c +++ b/ports/esp32/network_ppp.c @@ -278,8 +278,10 @@ STATIC const mp_rom_map_elem_t ppp_if_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table); -const mp_obj_type_t ppp_if_type = { - { &mp_type_type }, - .name = MP_QSTR_PPP, - .locals_dict = (mp_obj_dict_t *)&ppp_if_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + ppp_if_type, + MP_QSTR_PPP, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&ppp_if_locals_dict + ); diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index 4f74262afc38..6ca5f9a9bafe 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -47,9 +47,8 @@ #error WIFI_MODE_STA and WIFI_MODE_AP are supposed to be bitfields! #endif -STATIC const mp_obj_type_t wlan_if_type; -STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; -STATIC const wlan_if_obj_t wlan_ap_obj = {{&wlan_if_type}, WIFI_IF_AP}; +STATIC const wlan_if_obj_t wlan_sta_obj; +STATIC const wlan_if_obj_t wlan_ap_obj; // Set to "true" if esp_wifi_start() was called static bool wifi_started = false; @@ -616,10 +615,15 @@ STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table); -STATIC const mp_obj_type_t wlan_if_type = { - { &mp_type_type }, - .name = MP_QSTR_WLAN, - .locals_dict = (mp_obj_t)&wlan_if_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + wlan_if_type, + MP_QSTR_WLAN, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&wlan_if_locals_dict + ); + +STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; +STATIC const wlan_if_obj_t wlan_ap_obj = {{&wlan_if_type}, WIFI_IF_AP}; #endif // MICROPY_PY_NETWORK_WLAN diff --git a/ports/esp8266/machine_adc.c b/ports/esp8266/machine_adc.c index 471e14d8dfbe..bface7f7e155 100644 --- a/ports/esp8266/machine_adc.c +++ b/ports/esp8266/machine_adc.c @@ -89,10 +89,11 @@ STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_adc_locals_dict, machine_adc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = machine_adc_print, - .make_new = machine_adc_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + machine_adc_make_new, + print, machine_adc_print, + locals_dict, (mp_obj_dict_t *)&machine_adc_locals_dict + ); diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c index 3ff76f5a02e0..c0d4a677e3ef 100644 --- a/ports/esp8266/machine_hspi.c +++ b/ports/esp8266/machine_hspi.c @@ -175,13 +175,14 @@ STATIC const mp_machine_spi_p_t machine_hspi_p = { .transfer = machine_hspi_transfer, }; -const mp_obj_type_t machine_hspi_type = { - { &mp_type_type }, - .name = MP_QSTR_HSPI, - .print = machine_hspi_print, - .make_new = machine_hspi_make_new, - .protocol = &machine_hspi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hspi_type, + MP_QSTR_HSPI, + MP_TYPE_FLAG_NONE, + machine_hspi_make_new, + print, machine_hspi_print, + protocol, &machine_hspi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); #endif // MICROPY_PY_MACHINE_SPI diff --git a/ports/esp8266/machine_pin.c b/ports/esp8266/machine_pin.c index 8171b8a8a3e3..8b759766cd6f 100644 --- a/ports/esp8266/machine_pin.c +++ b/ports/esp8266/machine_pin.c @@ -450,15 +450,16 @@ STATIC const mp_pin_p_t pin_pin_p = { .ioctl = pin_ioctl, }; -const mp_obj_type_t pyb_pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = pyb_pin_print, - .make_new = mp_pin_make_new, - .call = pyb_pin_call, - .protocol = &pin_pin_p, - .locals_dict = (mp_obj_dict_t *)&pyb_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, pyb_pin_print, + call, pyb_pin_call, + protocol, &pin_pin_p, + locals_dict, (mp_obj_dict_t *)&pyb_pin_locals_dict + ); /******************************************************************************/ // Pin IRQ object @@ -509,11 +510,13 @@ STATIC const mp_rom_map_elem_t pin_irq_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pin_irq_locals_dict, pin_irq_locals_dict_table); -STATIC const mp_obj_type_t pin_irq_type = { - { &mp_type_type }, - .name = MP_QSTR_IRQ, - .call = pin_irq_call, - .locals_dict = (mp_obj_dict_t *)&pin_irq_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pin_irq_type, + MP_QSTR_IRQ, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + call, pin_irq_call, + locals_dict, (mp_obj_dict_t *)&pin_irq_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_irq_handler[16]); diff --git a/ports/esp8266/machine_rtc.c b/ports/esp8266/machine_rtc.c index 38049ce72493..4235b325ef7a 100644 --- a/ports/esp8266/machine_rtc.c +++ b/ports/esp8266/machine_rtc.c @@ -262,9 +262,10 @@ STATIC const mp_rom_map_elem_t pyb_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table); -const mp_obj_type_t pyb_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = pyb_rtc_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + pyb_rtc_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_rtc_locals_dict + ); diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index 2fe6516dc7ce..82f5189388ca 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -343,15 +343,16 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t pyb_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = pyb_uart_print, - .make_new = pyb_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&pyb_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + pyb_uart_make_new, + print, pyb_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t *)&pyb_uart_locals_dict + ); MP_REGISTER_ROOT_POINTER(byte * uart0_rxbuf); diff --git a/ports/esp8266/machine_wdt.c b/ports/esp8266/machine_wdt.c index b06e75227728..d8c32ddd1a1f 100644 --- a/ports/esp8266/machine_wdt.c +++ b/ports/esp8266/machine_wdt.c @@ -69,9 +69,10 @@ STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); -const mp_obj_type_t esp_wdt_type = { - { &mp_type_type }, - .name = MP_QSTR_WDT, - .make_new = machine_wdt_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_wdt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + esp_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + machine_wdt_make_new, + locals_dict, (mp_obj_dict_t *)&machine_wdt_locals_dict + ); diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index 1dd87b9af8f7..2bb2c7bd7695 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -337,13 +337,14 @@ STATIC const mp_rom_map_elem_t esp_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(esp_timer_locals_dict, esp_timer_locals_dict_table); -const mp_obj_type_t esp_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = esp_timer_print, - .make_new = esp_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&esp_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + esp_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + esp_timer_make_new, + print, esp_timer_print, + locals_dict, (mp_obj_dict_t *)&esp_timer_locals_dict + ); // this bit is unused in the Xtensa PS register #define ETS_LOOP_ITER_BIT (12) diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index 5240d3b32064..f78bf5da52eb 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -510,11 +510,13 @@ STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table); -const mp_obj_type_t wlan_if_type = { - { &mp_type_type }, - .name = MP_QSTR_WLAN, - .locals_dict = (mp_obj_dict_t *)&wlan_if_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + wlan_if_type, + MP_QSTR_WLAN, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&wlan_if_locals_dict + ); STATIC mp_obj_t esp_phy_mode(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { diff --git a/ports/mimxrt/machine_adc.c b/ports/mimxrt/machine_adc.c index aa4cc831e561..cbac6b5734d2 100644 --- a/ports/mimxrt/machine_adc.c +++ b/ports/mimxrt/machine_adc.c @@ -117,13 +117,14 @@ STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - {&mp_type_type}, - .name = MP_QSTR_ADC, - .print = adc_obj_print, - .make_new = adc_obj_make_new, - .locals_dict = (mp_obj_dict_t *)&adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + adc_obj_make_new, + print, adc_obj_print, + locals_dict, (mp_obj_dict_t *)&adc_locals_dict + ); void machine_adc_init(void) { for (int i = 1; i < sizeof(adc_bases) / sizeof(ADC_Type *); ++i) { diff --git a/ports/mimxrt/machine_i2c.c b/ports/mimxrt/machine_i2c.c index c10fcaddbe38..b8b6b7bc6334 100644 --- a/ports/mimxrt/machine_i2c.c +++ b/ports/mimxrt/machine_i2c.c @@ -197,11 +197,12 @@ STATIC const mp_machine_i2c_p_t machine_i2c_p = { .transfer_single = machine_i2c_transfer_single, }; -const mp_obj_type_t machine_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_i2c_print, - .make_new = machine_i2c_make_new, - .protocol = &machine_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_i2c_make_new, + print, machine_i2c_print, + protocol, &machine_i2c_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + ); diff --git a/ports/mimxrt/machine_i2s.c b/ports/mimxrt/machine_i2s.c index a5446c7ac3ef..68bf3a820f59 100644 --- a/ports/mimxrt/machine_i2s.c +++ b/ports/mimxrt/machine_i2s.c @@ -1213,16 +1213,17 @@ STATIC const mp_stream_p_t i2s_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_i2s_type = { - { &mp_type_type }, - .name = MP_QSTR_I2S, - .print = machine_i2s_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &i2s_stream_p, - .make_new = machine_i2s_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_i2s_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_i2s_type, + MP_QSTR_I2S, + MP_TYPE_FLAG_NONE, + machine_i2s_make_new, + print, machine_i2s_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &i2s_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_I2S_NUM]); diff --git a/ports/mimxrt/machine_led.c b/ports/mimxrt/machine_led.c index 4082eb34bbbf..d766c8f3237a 100644 --- a/ports/mimxrt/machine_led.c +++ b/ports/mimxrt/machine_led.c @@ -80,12 +80,13 @@ STATIC const mp_rom_map_elem_t led_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table); -const mp_obj_type_t machine_led_type = { - {&mp_type_type}, - .name = MP_QSTR_LED, - .print = led_obj_print, - .make_new = led_obj_make_new, - .locals_dict = (mp_obj_dict_t *)&led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + led_obj_make_new, + print, led_obj_print, + locals_dict, (mp_obj_dict_t *)&led_locals_dict + ); #endif diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 64066af0e16c..7ec66d0eac95 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -58,17 +58,21 @@ enum { }; // Pin mapping dictionaries -const mp_obj_type_t machine_pin_cpu_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_cpu, - .locals_dict = (mp_obj_t)&machine_pin_cpu_pins_locals_dict, -}; - -const mp_obj_type_t machine_pin_board_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_board, - .locals_dict = (mp_obj_t)&machine_pin_board_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_cpu_pins_obj_type, + MP_QSTR_cpu, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_t)&machine_pin_cpu_pins_locals_dict + ); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_board_pins_obj_type, + MP_QSTR_board, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_t)&machine_pin_board_pins_locals_dict + ); STATIC const mp_irq_methods_t machine_pin_irq_methods; @@ -396,7 +400,6 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); - STATIC mp_uint_t machine_pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { (void)errcode; machine_pin_obj_t *self = self_in; @@ -417,24 +420,26 @@ STATIC const mp_pin_p_t machine_pin_obj_protocol = { .ioctl = machine_pin_ioctl, }; -const mp_obj_type_t machine_pin_type = { - {&mp_type_type}, - .name = MP_QSTR_Pin, - .print = machine_pin_obj_print, - .call = machine_pin_obj_call, - .make_new = mp_pin_make_new, - .protocol = &machine_pin_obj_protocol, - .locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, machine_pin_obj_print, + call, machine_pin_obj_call, + protocol, &machine_pin_obj_protocol, + locals_dict, (mp_obj_dict_t *)&machine_pin_locals_dict + ); // FIXME: Create actual pin_af type!!! -const mp_obj_type_t machine_pin_af_type = { - {&mp_type_type}, - .name = MP_QSTR_PinAF, - .print = machine_pin_obj_print, - .make_new = mp_pin_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_af_type, + MP_QSTR_PinAF, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, machine_pin_obj_print, + locals_dict, (mp_obj_dict_t *)&machine_pin_locals_dict + ); STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/ports/mimxrt/machine_rtc.c b/ports/mimxrt/machine_rtc.c index e0d33554b559..5211027bdf80 100644 --- a/ports/mimxrt/machine_rtc.c +++ b/ports/mimxrt/machine_rtc.c @@ -166,9 +166,10 @@ STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); -const mp_obj_type_t machine_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = machine_rtc_make_new, - .locals_dict = (mp_obj_t)&machine_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + machine_rtc_make_new, + locals_dict, (mp_obj_t)&machine_rtc_locals_dict + ); diff --git a/ports/mimxrt/machine_sdcard.c b/ports/mimxrt/machine_sdcard.c index 4a92aae00cef..b7bdceef47ed 100644 --- a/ports/mimxrt/machine_sdcard.c +++ b/ports/mimxrt/machine_sdcard.c @@ -208,12 +208,13 @@ STATIC const mp_rom_map_elem_t sdcard_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(sdcard_locals_dict, sdcard_locals_dict_table); -const mp_obj_type_t machine_sdcard_type = { - { &mp_type_type }, - .name = MP_QSTR_SDCard, - .make_new = sdcard_obj_make_new, - .locals_dict = (mp_obj_dict_t *)&sdcard_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_sdcard_type, + MP_QSTR_SDCard, + MP_TYPE_FLAG_NONE, + sdcard_obj_make_new, + locals_dict, (mp_obj_dict_t *)&sdcard_locals_dict + ); void machine_sdcard_init0(void) { return; diff --git a/ports/mimxrt/machine_spi.c b/ports/mimxrt/machine_spi.c index 32bc77c34ddf..ff3cf4fb2551 100644 --- a/ports/mimxrt/machine_spi.c +++ b/ports/mimxrt/machine_spi.c @@ -251,11 +251,12 @@ STATIC const mp_machine_spi_p_t machine_spi_p = { .transfer = machine_spi_transfer, }; -const mp_obj_type_t machine_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_spi_print, - .make_new = machine_spi_make_new, - .protocol = &machine_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_spi_make_new, + print, machine_spi_print, + protocol, &machine_spi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); diff --git a/ports/mimxrt/machine_timer.c b/ports/mimxrt/machine_timer.c index 62a560ebbfc4..9612388486e3 100644 --- a/ports/mimxrt/machine_timer.c +++ b/ports/mimxrt/machine_timer.c @@ -211,12 +211,13 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); -const mp_obj_type_t machine_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = machine_timer_print, - .make_new = machine_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + machine_timer_make_new, + print, machine_timer_print, + locals_dict, (mp_obj_dict_t *)&machine_timer_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _machine_timer_obj_t *timer_table[MICROPY_HW_PIT_NUM_CHANNELS]); diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index 83382a6cf2bc..4bb518eab25e 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -469,13 +469,14 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = machine_uart_print, - .make_new = machine_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&machine_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + machine_uart_make_new, + print, machine_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + ); diff --git a/ports/mimxrt/machine_wdt.c b/ports/mimxrt/machine_wdt.c index d09c464f69a3..cde80f085b99 100644 --- a/ports/mimxrt/machine_wdt.c +++ b/ports/mimxrt/machine_wdt.c @@ -99,9 +99,10 @@ STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); -const mp_obj_type_t machine_wdt_type = { - { &mp_type_type }, - .name = MP_QSTR_WDT, - .make_new = machine_wdt_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_wdt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + machine_wdt_make_new, + locals_dict, (mp_obj_dict_t *)&machine_wdt_locals_dict + ); diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index 27ab987ed17f..1a7d6cca8da0 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -215,9 +215,10 @@ STATIC const mp_rom_map_elem_t mimxrt_flash_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(mimxrt_flash_locals_dict, mimxrt_flash_locals_dict_table); -const mp_obj_type_t mimxrt_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .make_new = mimxrt_flash_make_new, - .locals_dict = (mp_obj_dict_t *)&mimxrt_flash_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mimxrt_flash_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + mimxrt_flash_make_new, + locals_dict, (mp_obj_dict_t *)&mimxrt_flash_locals_dict + ); diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index 5517b54bd02f..08c3c9e729f5 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -220,12 +220,14 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table); -const mp_obj_type_t network_lan_type = { - { &mp_type_type }, - .name = MP_QSTR_LAN, - .print = network_lan_print, - .make_new = network_lan_make_new, - .locals_dict = (mp_obj_dict_t *)&network_lan_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + network_lan_type, + MP_QSTR_LAN, + MP_TYPE_FLAG_NONE, + network_lan_make_new, + print, network_lan_print, + locals_dict, (mp_obj_dict_t *)&network_lan_locals_dict + ); + #endif // defined(MICROPY_HW_ETH_MDC) diff --git a/ports/nrf/boards/microbit/modules/iters.c b/ports/nrf/boards/microbit/modules/iters.c index 66f9f6c7f3ea..296fc1f51c52 100644 --- a/ports/nrf/boards/microbit/modules/iters.c +++ b/ports/nrf/boards/microbit/modules/iters.c @@ -43,12 +43,14 @@ static mp_obj_t microbit_repeat_iter_next(mp_obj_t iter_in) { return mp_obj_subscr(iter->iterable, MP_OBJ_NEW_SMALL_INT(iter->index), MP_OBJ_SENTINEL); } -const mp_obj_type_t microbit_repeat_iterator_type = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = microbit_repeat_iter_next, -}; +MP_DEFINE_CONST_OBJ_TYPE( + microbit_repeat_iterator_type, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, microbit_repeat_iter_next + ); mp_obj_t microbit_repeat_iterator(mp_obj_t iterable) { repeat_iterator_t *result = mp_obj_malloc(repeat_iterator_t, µbit_repeat_iterator_type); diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c index 93ba9772fe98..084cb09524da 100644 --- a/ports/nrf/boards/microbit/modules/microbitdisplay.c +++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c @@ -542,11 +542,13 @@ STATIC const mp_rom_map_elem_t microbit_display_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(microbit_display_locals_dict, microbit_display_locals_dict_table); -const mp_obj_type_t microbit_display_type = { - { &mp_type_type }, - .name = MP_QSTR_MicroBitDisplay, - .locals_dict = (mp_obj_dict_t*)µbit_display_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + microbit_display_type, + MP_QSTR_MicroBitDisplay, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t*)µbit_display_locals_dict + ); microbit_display_obj_t microbit_display_obj = { {µbit_display_type}, diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c index eb44660b974c..95b17bb6d339 100644 --- a/ports/nrf/boards/microbit/modules/microbitimage.c +++ b/ports/nrf/boards/microbit/modules/microbitimage.c @@ -678,14 +678,15 @@ STATIC mp_obj_t image_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs } -const mp_obj_type_t microbit_image_type = { - { &mp_type_type }, - .name = MP_QSTR_MicroBitImage, - .print = microbit_image_print, - .make_new = microbit_image_make_new, - .binary_op = image_binary_op, - .locals_dict = (mp_obj_dict_t*)µbit_image_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + microbit_image_type, + MP_QSTR_MicroBitImage, + MP_TYPE_FLAG_NONE, + microbit_image_make_new, + print, microbit_image_print, + binary_op, image_binary_op, + locals_dict, (mp_obj_dict_t*)µbit_image_locals_dict + ); typedef struct _scrolling_string_t { mp_obj_base_t base; @@ -820,18 +821,22 @@ STATIC mp_obj_t microbit_scrolling_string_iter_next(mp_obj_t o_in) { return iter->img; } -const mp_obj_type_t microbit_scrolling_string_type = { - { &mp_type_type }, - .name = MP_QSTR_ScrollingString, - .getiter = get_microbit_scrolling_string_iter, -}; +MP_DEFINE_CONST_OBJ_TYPE( + microbit_scrolling_string_type, + MP_QSTR_ScrollingString, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, get_microbit_scrolling_string_iter + ); -const mp_obj_type_t microbit_scrolling_string_iterator_type = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = microbit_scrolling_string_iter_next, -}; +MP_DEFINE_CONST_OBJ_TYPE( + microbit_scrolling_string_iterator_type, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, microbit_scrolling_string_iter_next + ); /** Facade types to present a string as a sequence of images. * These are necessary to avoid allocation during iteration, @@ -869,13 +874,15 @@ static mp_obj_t facade_unary_op(mp_unary_op_t op, mp_obj_t self_in) { static mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf); -const mp_obj_type_t string_image_facade_type = { - { &mp_type_type }, - .name = MP_QSTR_Facade, - .unary_op = facade_unary_op, - .subscr = string_image_facade_subscr, - .getiter = microbit_facade_iterator, -}; +MP_DEFINE_CONST_OBJ_TYPE( + string_image_facade_type, + MP_QSTR_Facade, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + unary_op, facade_unary_op, + subscr, string_image_facade_subscr, + getiter, microbit_facade_iterator + ); typedef struct _facade_iterator_t { @@ -904,12 +911,14 @@ static mp_obj_t microbit_facade_iter_next(mp_obj_t iter_in) { return iter->image; } -const mp_obj_type_t microbit_facade_iterator_type = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = microbit_facade_iter_next, -}; +MP_DEFINE_CONST_OBJ_TYPE( + microbit_facade_iterator_type, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, microbit_facade_iter_next + ); mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf) { (void)iter_buf; diff --git a/ports/nrf/modules/board/led.c b/ports/nrf/modules/board/led.c index cbfc330d6330..5eef8f046402 100644 --- a/ports/nrf/modules/board/led.c +++ b/ports/nrf/modules/board/led.c @@ -194,13 +194,14 @@ STATIC const mp_rom_map_elem_t led_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table); -const mp_obj_type_t board_led_type = { - { &mp_type_type }, - .name = MP_QSTR_LED, - .print = led_obj_print, - .make_new = led_obj_make_new, - .locals_dict = (mp_obj_dict_t*)&led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + board_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + led_obj_make_new, + print, led_obj_print, + locals_dict, (mp_obj_dict_t*)&led_locals_dict + ); #else // For boards with no LEDs, we leave an empty function here so that we don't diff --git a/ports/nrf/modules/machine/adc.c b/ports/nrf/modules/machine/adc.c index 54870d2c18ee..5814dcaa392c 100644 --- a/ports/nrf/modules/machine/adc.c +++ b/ports/nrf/modules/machine/adc.c @@ -294,12 +294,13 @@ STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(machine_adc_locals_dict, machine_adc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .make_new = machine_adc_make_new, - .locals_dict = (mp_obj_dict_t*)&machine_adc_locals_dict, - .print = machine_adc_print, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + machine_adc_make_new, + locals_dict, (mp_obj_dict_t*)&machine_adc_locals_dict, + print, machine_adc_print + ); #endif // MICROPY_PY_MACHINE_ADC diff --git a/ports/nrf/modules/machine/i2c.c b/ports/nrf/modules/machine/i2c.c index aac932087320..8468684428a7 100644 --- a/ports/nrf/modules/machine/i2c.c +++ b/ports/nrf/modules/machine/i2c.c @@ -161,13 +161,14 @@ STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { .transfer_single = machine_hard_i2c_transfer_single, }; -const mp_obj_type_t machine_hard_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_hard_i2c_print, - .make_new = machine_hard_i2c_make_new, - .protocol = &machine_hard_i2c_p, - .locals_dict = (mp_obj_dict_t*)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_hard_i2c_make_new, + print, machine_hard_i2c_print, + protocol, &machine_hard_i2c_p, + locals_dict, (mp_obj_dict_t*)&mp_machine_i2c_locals_dict + ); #endif // MICROPY_PY_MACHINE_I2C diff --git a/ports/nrf/modules/machine/pin.c b/ports/nrf/modules/machine/pin.c index 3a45c22d18ef..835f6cf2bd32 100644 --- a/ports/nrf/modules/machine/pin.c +++ b/ports/nrf/modules/machine/pin.c @@ -596,14 +596,15 @@ STATIC const mp_rom_map_elem_t pin_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table); -const mp_obj_type_t pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = pin_print, - .make_new = pin_make_new, - .call = pin_call, - .locals_dict = (mp_obj_dict_t*)&pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + pin_make_new, + print, pin_print, + call, pin_call, + locals_dict, (mp_obj_dict_t*)&pin_locals_dict + ); /// \moduleref machine /// \class PinAF - Pin Alternate Functions @@ -671,12 +672,14 @@ STATIC const mp_rom_map_elem_t pin_af_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pin_af_locals_dict, pin_af_locals_dict_table); -const mp_obj_type_t pin_af_type = { - { &mp_type_type }, - .name = MP_QSTR_PinAF, - .print = pin_af_obj_print, - .locals_dict = (mp_obj_dict_t*)&pin_af_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_af_type, + MP_QSTR_PinAF, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pin_af_obj_print, + locals_dict, (mp_obj_dict_t*)&pin_af_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_class_mapper); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_class_map_dict); diff --git a/ports/nrf/modules/machine/pwm.c b/ports/nrf/modules/machine/pwm.c index a750285841e2..d0ac0e9450c3 100644 --- a/ports/nrf/modules/machine/pwm.c +++ b/ports/nrf/modules/machine/pwm.c @@ -339,12 +339,13 @@ STATIC mp_obj_t machine_hard_pwm_freq(mp_obj_t self_in, mp_arg_val_t *args) { return mp_const_none; } -const mp_obj_type_t machine_hard_pwm_type = { - { &mp_type_type }, - .name = MP_QSTR_PWM, - .print = machine_pwm_print, - .make_new = machine_pwm_make_new, - .locals_dict = (mp_obj_dict_t*)&machine_pwm_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_pwm_type, + MP_QSTR_PWM, + MP_TYPE_FLAG_NONE, + machine_pwm_make_new, + print, machine_pwm_print, + locals_dict, (mp_obj_dict_t*)&machine_pwm_locals_dict + ); #endif // MICROPY_PY_MACHINE_HW_PWM diff --git a/ports/nrf/modules/machine/rtcounter.c b/ports/nrf/modules/machine/rtcounter.c index c9f907774e6a..3c48c4bb1fb2 100644 --- a/ports/nrf/modules/machine/rtcounter.c +++ b/ports/nrf/modules/machine/rtcounter.c @@ -262,12 +262,13 @@ STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); -const mp_obj_type_t machine_rtcounter_type = { - { &mp_type_type }, - .name = MP_QSTR_RTCounter, - .print = rtc_print, - .make_new = machine_rtc_make_new, - .locals_dict = (mp_obj_dict_t*)&machine_rtc_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtcounter_type, + MP_QSTR_RTCounter, + MP_TYPE_FLAG_NONE, + machine_rtc_make_new, + print, rtc_print, + locals_dict, (mp_obj_dict_t*)&machine_rtc_locals_dict + ); #endif // MICROPY_PY_MACHINE_RTCOUNTER diff --git a/ports/nrf/modules/machine/spi.c b/ports/nrf/modules/machine/spi.c index 81bc151bebd6..22b0ff56e59a 100644 --- a/ports/nrf/modules/machine/spi.c +++ b/ports/nrf/modules/machine/spi.c @@ -427,13 +427,14 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { .transfer = machine_hard_spi_transfer, }; -const mp_obj_type_t machine_hard_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_hard_spi_print, - .make_new = machine_spi_make_new, - .protocol = &machine_hard_spi_p, - .locals_dict = (mp_obj_dict_t*)&machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_spi_make_new, + print, machine_hard_spi_print, + protocol, &machine_hard_spi_p, + locals_dict, (mp_obj_dict_t*)&machine_spi_locals_dict + ); #endif // MICROPY_PY_MACHINE_HW_SPI diff --git a/ports/nrf/modules/machine/temp.c b/ports/nrf/modules/machine/temp.c index 1eb38c08d0bd..1e21f11253fd 100644 --- a/ports/nrf/modules/machine/temp.c +++ b/ports/nrf/modules/machine/temp.c @@ -112,12 +112,13 @@ STATIC const mp_rom_map_elem_t machine_temp_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(machine_temp_locals_dict, machine_temp_locals_dict_table); -const mp_obj_type_t machine_temp_type = { - { &mp_type_type }, - .name = MP_QSTR_Temp, - .make_new = machine_temp_make_new, - .locals_dict = (mp_obj_dict_t*)&machine_temp_locals_dict, - .print = machine_temp_print, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_temp_type, + MP_QSTR_Temp, + MP_TYPE_FLAG_NONE, + machine_temp_make_new, + locals_dict, (mp_obj_dict_t*)&machine_temp_locals_dict, + print, machine_temp_print + ); #endif // MICROPY_PY_MACHINE_TEMP diff --git a/ports/nrf/modules/machine/timer.c b/ports/nrf/modules/machine/timer.c index c99713ef52c5..3724881aa813 100644 --- a/ports/nrf/modules/machine/timer.c +++ b/ports/nrf/modules/machine/timer.c @@ -234,12 +234,13 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); -const mp_obj_type_t machine_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = timer_print, - .make_new = machine_timer_make_new, - .locals_dict = (mp_obj_dict_t*)&machine_timer_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + machine_timer_make_new, + print, timer_print, + locals_dict, (mp_obj_dict_t*)&machine_timer_locals_dict + ); #endif // MICROPY_PY_MACHINE_TIMER diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index 1fd2ccc06caf..5c9ba83ab662 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -370,15 +370,16 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_hard_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = machine_hard_uart_print, - .make_new = machine_hard_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t*)&machine_hard_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + machine_hard_uart_make_new, + print, machine_hard_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t*)&machine_hard_uart_locals_dict + ); #endif // MICROPY_PY_MACHINE_UART diff --git a/ports/nrf/modules/nrf/flashbdev.c b/ports/nrf/modules/nrf/flashbdev.c index f63a9b46b29c..b67e86d0d0df 100644 --- a/ports/nrf/modules/nrf/flashbdev.c +++ b/ports/nrf/modules/nrf/flashbdev.c @@ -183,13 +183,14 @@ STATIC mp_obj_t nrf_flashbdev_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } -const mp_obj_type_t nrf_flashbdev_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .print = nrf_flashbdev_print, - .make_new = nrf_flashbdev_make_new, - .locals_dict = (mp_obj_dict_t *)&nrf_flashbdev_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + nrf_flashbdev_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + nrf_flashbdev_make_new, + print, nrf_flashbdev_print, + locals_dict, (mp_obj_dict_t *)&nrf_flashbdev_locals_dict + ); void flashbdev_init(void) { // Set start to first aligned page from _fs_start. diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c index a66483f60dad..5544ac6aefed 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c +++ b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c @@ -209,12 +209,13 @@ STATIC const mp_rom_map_elem_t ubluepy_characteristic_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_characteristic_locals_dict, ubluepy_characteristic_locals_dict_table); -const mp_obj_type_t ubluepy_characteristic_type = { - { &mp_type_type }, - .name = MP_QSTR_Characteristic, - .print = ubluepy_characteristic_print, - .make_new = ubluepy_characteristic_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_characteristic_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_characteristic_type, + MP_QSTR_Characteristic, + MP_TYPE_FLAG_NONE, + ubluepy_characteristic_make_new, + print, ubluepy_characteristic_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_characteristic_locals_dict + ); #endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c index 14e433e6ebff..e4637c8cbce2 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ b/ports/nrf/modules/ubluepy/ubluepy_constants.c @@ -69,11 +69,13 @@ STATIC const mp_rom_map_elem_t ubluepy_constants_ad_types_locals_dict_table[] = STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_ad_types_locals_dict, ubluepy_constants_ad_types_locals_dict_table); -const mp_obj_type_t ubluepy_constants_ad_types_type = { - { &mp_type_type }, - .name = MP_QSTR_ad_types, - .locals_dict = (mp_obj_dict_t*)&ubluepy_constants_ad_types_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_constants_ad_types_type, + MP_QSTR_ad_types, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t*)&ubluepy_constants_ad_types_locals_dict + ); STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { // GAP events @@ -90,10 +92,12 @@ STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_locals_dict, ubluepy_constants_locals_dict_table); -const mp_obj_type_t ubluepy_constants_type = { - { &mp_type_type }, - .name = MP_QSTR_constants, - .locals_dict = (mp_obj_dict_t*)&ubluepy_constants_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_constants_type, + MP_QSTR_constants, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t*)&ubluepy_constants_locals_dict + ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_delegate.c b/ports/nrf/modules/ubluepy/ubluepy_delegate.c index 736bfbc9dd23..71648767e61d 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_delegate.c +++ b/ports/nrf/modules/ubluepy/ubluepy_delegate.c @@ -77,12 +77,13 @@ STATIC const mp_rom_map_elem_t ubluepy_delegate_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_delegate_locals_dict, ubluepy_delegate_locals_dict_table); -const mp_obj_type_t ubluepy_delegate_type = { - { &mp_type_type }, - .name = MP_QSTR_DefaultDelegate, - .print = ubluepy_delegate_print, - .make_new = ubluepy_delegate_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_delegate_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_delegate_type, + MP_QSTR_DefaultDelegate, + MP_TYPE_FLAG_NONE, + ubluepy_delegate_make_new, + print, ubluepy_delegate_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_delegate_locals_dict + ); #endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c index 370188f7fc7a..07035460ae4d 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c +++ b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c @@ -70,12 +70,13 @@ STATIC const mp_rom_map_elem_t ubluepy_descriptor_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_descriptor_locals_dict, ubluepy_descriptor_locals_dict_table); -const mp_obj_type_t ubluepy_descriptor_type = { - { &mp_type_type }, - .name = MP_QSTR_Descriptor, - .print = ubluepy_descriptor_print, - .make_new = ubluepy_descriptor_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_descriptor_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_descriptor_type, + MP_QSTR_Descriptor, + MP_TYPE_FLAG_NONE, + ubluepy_descriptor_make_new, + print, ubluepy_descriptor_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_descriptor_locals_dict + ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index acfe316c0cf7..9c346a885b2c 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -482,12 +482,13 @@ STATIC const mp_rom_map_elem_t ubluepy_peripheral_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_peripheral_locals_dict, ubluepy_peripheral_locals_dict_table); -const mp_obj_type_t ubluepy_peripheral_type = { - { &mp_type_type }, - .name = MP_QSTR_Peripheral, - .print = ubluepy_peripheral_print, - .make_new = ubluepy_peripheral_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_peripheral_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_peripheral_type, + MP_QSTR_Peripheral, + MP_TYPE_FLAG_NONE, + ubluepy_peripheral_make_new, + print, ubluepy_peripheral_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_peripheral_locals_dict + ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c index 773070b08907..64a81d215d37 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c @@ -136,11 +136,13 @@ STATIC const mp_rom_map_elem_t ubluepy_scan_entry_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_scan_entry_locals_dict, ubluepy_scan_entry_locals_dict_table); -const mp_obj_type_t ubluepy_scan_entry_type = { - { &mp_type_type }, - .name = MP_QSTR_ScanEntry, - .print = ubluepy_scan_entry_print, - .locals_dict = (mp_obj_dict_t*)&ubluepy_scan_entry_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_scan_entry_type, + MP_QSTR_ScanEntry, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, ubluepy_scan_entry_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_scan_entry_locals_dict + ); #endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_scanner.c b/ports/nrf/modules/ubluepy/ubluepy_scanner.c index 60895a3da93f..c47044cf0c37 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scanner.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scanner.c @@ -114,12 +114,13 @@ STATIC const mp_rom_map_elem_t ubluepy_scanner_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_scanner_locals_dict, ubluepy_scanner_locals_dict_table); -const mp_obj_type_t ubluepy_scanner_type = { - { &mp_type_type }, - .name = MP_QSTR_Scanner, - .print = ubluepy_scanner_print, - .make_new = ubluepy_scanner_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_scanner_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_scanner_type, + MP_QSTR_Scanner, + MP_TYPE_FLAG_NONE, + ubluepy_scanner_make_new, + print, ubluepy_scanner_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_scanner_locals_dict + ); #endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c index 6dac23177925..9d0d6e5b95f8 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ b/ports/nrf/modules/ubluepy/ubluepy_service.c @@ -171,12 +171,13 @@ STATIC const mp_rom_map_elem_t ubluepy_service_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_service_locals_dict, ubluepy_service_locals_dict_table); -const mp_obj_type_t ubluepy_service_type = { - { &mp_type_type }, - .name = MP_QSTR_Service, - .print = ubluepy_service_print, - .make_new = ubluepy_service_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_service_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_service_type, + MP_QSTR_Service, + MP_TYPE_FLAG_NONE, + ubluepy_service_make_new, + print, ubluepy_service_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_service_locals_dict + ); #endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c index aee7b9a1a899..0414a2a2867f 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c +++ b/ports/nrf/modules/ubluepy/ubluepy_uuid.c @@ -160,12 +160,13 @@ STATIC const mp_rom_map_elem_t ubluepy_uuid_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ubluepy_uuid_locals_dict, ubluepy_uuid_locals_dict_table); -const mp_obj_type_t ubluepy_uuid_type = { - { &mp_type_type }, - .name = MP_QSTR_UUID, - .print = ubluepy_uuid_print, - .make_new = ubluepy_uuid_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_uuid_locals_dict -}; +MP_DEFINE_CONST_OBJ_TYPE( + ubluepy_uuid_type, + MP_QSTR_UUID, + MP_TYPE_FLAG_NONE, + ubluepy_uuid_make_new, + print, ubluepy_uuid_print, + locals_dict, (mp_obj_dict_t*)&ubluepy_uuid_locals_dict + ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/uos/microbitfs.c b/ports/nrf/modules/uos/microbitfs.c index 6c8ffb0925d0..63ac8c93213f 100644 --- a/ports/nrf/modules/uos/microbitfs.c +++ b/ports/nrf/modules/uos/microbitfs.c @@ -626,12 +626,14 @@ STATIC const mp_stream_p_t textio_stream_p = { .is_text = true, }; -const mp_obj_type_t uos_mbfs_textio_type = { - { &mp_type_type }, - .name = MP_QSTR_TextIO, - .protocol = &textio_stream_p, - .locals_dict = (mp_obj_dict_t*)&uos_mbfs_file_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + uos_mbfs_textio_type, + MP_QSTR_TextIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + protocol, &textio_stream_p, + locals_dict, (mp_obj_dict_t*)&uos_mbfs_file_locals_dict + ); STATIC const mp_stream_p_t fileio_stream_p = { @@ -639,12 +641,14 @@ STATIC const mp_stream_p_t fileio_stream_p = { .write = microbit_file_write, }; -const mp_obj_type_t uos_mbfs_fileio_type = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .protocol = &fileio_stream_p, - .locals_dict = (mp_obj_dict_t*)&uos_mbfs_file_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + uos_mbfs_fileio_type, + MP_QSTR_FileIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + protocol, &fileio_stream_p, + locals_dict, (mp_obj_dict_t*)&uos_mbfs_file_locals_dict + ); // From micro:bit fileobj.c mp_obj_t uos_mbfs_open(size_t n_args, const mp_obj_t *args) { diff --git a/ports/nrf/pin_named_pins.c b/ports/nrf/pin_named_pins.c index e1d8736b9cf2..87fed746e64e 100644 --- a/ports/nrf/pin_named_pins.c +++ b/ports/nrf/pin_named_pins.c @@ -36,19 +36,23 @@ STATIC void pin_named_pins_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_printf(print, "", self->name); } -const mp_obj_type_t pin_cpu_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_cpu, - .print = pin_named_pins_obj_print, - .locals_dict = (mp_obj_t)&pin_cpu_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_cpu_pins_obj_type, + MP_QSTR_cpu, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pin_named_pins_obj_print, + locals_dict, (mp_obj_t)&pin_cpu_pins_locals_dict + ); -const mp_obj_type_t pin_board_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_board, - .print = pin_named_pins_obj_print, - .locals_dict = (mp_obj_t)&pin_board_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_board_pins_obj_type, + MP_QSTR_board, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pin_named_pins_obj_print, + locals_dict, (mp_obj_t)&pin_board_pins_locals_dict + ); const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); diff --git a/ports/pic16bit/modpybled.c b/ports/pic16bit/modpybled.c index 6adb2fda3126..fd4e8cce9c92 100644 --- a/ports/pic16bit/modpybled.c +++ b/ports/pic16bit/modpybled.c @@ -84,10 +84,11 @@ STATIC const mp_rom_map_elem_t pyb_led_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_led_locals_dict, pyb_led_locals_dict_table); -const mp_obj_type_t pyb_led_type = { - { &mp_type_type }, - .name = MP_QSTR_LED, - .print = pyb_led_print, - .make_new = pyb_led_make_new, - .locals_dict = (mp_obj_t)&pyb_led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + pyb_led_make_new, + print, pyb_led_print, + locals_dict, (mp_obj_t)&pyb_led_locals_dict + ); diff --git a/ports/pic16bit/modpybswitch.c b/ports/pic16bit/modpybswitch.c index 7b3d0f5f527b..e1096b1daaad 100644 --- a/ports/pic16bit/modpybswitch.c +++ b/ports/pic16bit/modpybswitch.c @@ -71,11 +71,12 @@ STATIC const mp_rom_map_elem_t pyb_switch_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_switch_locals_dict, pyb_switch_locals_dict_table); -const mp_obj_type_t pyb_switch_type = { - { &mp_type_type }, - .name = MP_QSTR_Switch, - .print = pyb_switch_print, - .make_new = pyb_switch_make_new, - .call = pyb_switch_call, - .locals_dict = (mp_obj_t)&pyb_switch_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_switch_type, + MP_QSTR_Switch, + MP_TYPE_FLAG_NONE, + pyb_switch_make_new, + print, pyb_switch_print, + call, pyb_switch_call, + locals_dict, (mp_obj_t)&pyb_switch_locals_dict + ); diff --git a/ports/renesas-ra/extint.c b/ports/renesas-ra/extint.c index 59f9ecfa37ea..496a50c3e827 100644 --- a/ports/renesas-ra/extint.c +++ b/ports/renesas-ra/extint.c @@ -374,13 +374,14 @@ STATIC const mp_rom_map_elem_t extint_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(extint_locals_dict, extint_locals_dict_table); -const mp_obj_type_t extint_type = { - { &mp_type_type }, - .name = MP_QSTR_ExtInt, - .print = extint_obj_print, - .make_new = extint_make_new, - .locals_dict = (mp_obj_dict_t *)&extint_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + extint_type, + MP_QSTR_ExtInt, + MP_TYPE_FLAG_NONE, + extint_make_new, + locals_dict, &extint_locals_dict, + print, extint_obj_print + ); void extint_init0(void) { ra_icu_init(); diff --git a/ports/renesas-ra/led.c b/ports/renesas-ra/led.c index efc09d9de1b0..9a3f1d40e965 100644 --- a/ports/renesas-ra/led.c +++ b/ports/renesas-ra/led.c @@ -170,13 +170,14 @@ STATIC const mp_rom_map_elem_t led_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table); -const mp_obj_type_t ra_led_type = { - { &mp_type_type }, - .name = MP_QSTR_LED, - .print = led_obj_print, - .make_new = led_obj_make_new, - .locals_dict = (mp_obj_dict_t *)&led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + ra_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + led_obj_make_new, + locals_dict, &led_locals_dict, + print, led_obj_print + ); #else // For boards with no LEDs, we leave an empty function here so that we don't diff --git a/ports/renesas-ra/machine_adc.c b/ports/renesas-ra/machine_adc.c index adeebeb4c4ac..99e35f48d997 100644 --- a/ports/renesas-ra/machine_adc.c +++ b/ports/renesas-ra/machine_adc.c @@ -126,10 +126,11 @@ STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_adc_locals_dict, machine_adc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = machine_adc_print, - .make_new = machine_adc_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + machine_adc_make_new, + locals_dict, &machine_adc_locals_dict, + print, machine_adc_print + ); diff --git a/ports/renesas-ra/machine_i2c.c b/ports/renesas-ra/machine_i2c.c index bc1cea0cd93b..eaca5ff4a85e 100644 --- a/ports/renesas-ra/machine_i2c.c +++ b/ports/renesas-ra/machine_i2c.c @@ -156,13 +156,14 @@ STATIC const mp_machine_i2c_p_t machine_i2c_p = { .transfer_single = machine_i2c_transfer_single, }; -const mp_obj_type_t machine_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_i2c_print, - .make_new = machine_i2c_make_new, - .protocol = &machine_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_i2c_make_new, + locals_dict, (void *)&mp_machine_i2c_locals_dict, + print, machine_i2c_print, + protocol, &machine_i2c_p + ); #endif // MICROPY_HW_ENABLE_HW_I2C diff --git a/ports/renesas-ra/machine_pin.c b/ports/renesas-ra/machine_pin.c index f940b55547eb..17ef1e19a413 100644 --- a/ports/renesas-ra/machine_pin.c +++ b/ports/renesas-ra/machine_pin.c @@ -349,15 +349,16 @@ STATIC const mp_pin_p_t machine_pin_pin_p = { .ioctl = machine_pin_ioctl, }; -const mp_obj_type_t machine_pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = machine_pin_print, - .make_new = mp_pin_make_new, - .call = machine_pin_call, - .protocol = &machine_pin_pin_p, - .locals_dict = (mp_obj_t)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + locals_dict, &machine_pin_locals_dict, + print, machine_pin_print, + call, machine_pin_call, + protocol, &machine_pin_pin_p + ); // Returns the pin mode. This value returned by this macro should be one of: // GPIO_MODE_INPUT, GPIO_MODE_OUTPUT_PP, GPIO_MODE_OUTPUT_OD, @@ -388,17 +389,21 @@ uint32_t pin_get_af(const machine_pin_obj_t *pin) { return (uint32_t)ra_gpio_get_af(pin->pin); } -const mp_obj_type_t pin_cpu_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_cpu, - .locals_dict = (mp_obj_dict_t *)&pin_cpu_pins_locals_dict, -}; - -const mp_obj_type_t pin_board_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_board, - .locals_dict = (mp_obj_dict_t *)&pin_board_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_cpu_pins_obj_type, + MP_QSTR_cpu, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, &pin_cpu_pins_locals_dict + ); + +MP_DEFINE_CONST_OBJ_TYPE( + pin_board_pins_obj_type, + MP_QSTR_board, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, &pin_board_pins_locals_dict + ); const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { const mp_map_t *named_map = &named_pins->map; diff --git a/ports/renesas-ra/machine_rtc.c b/ports/renesas-ra/machine_rtc.c index 9ddc90213774..c3f64c697108 100644 --- a/ports/renesas-ra/machine_rtc.c +++ b/ports/renesas-ra/machine_rtc.c @@ -341,9 +341,10 @@ STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); -const mp_obj_type_t machine_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = machine_rtc_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + machine_rtc_make_new, + locals_dict, &machine_rtc_locals_dict + ); diff --git a/ports/renesas-ra/machine_spi.c b/ports/renesas-ra/machine_spi.c index 01972ad45761..d0e8b03bd12e 100644 --- a/ports/renesas-ra/machine_spi.c +++ b/ports/renesas-ra/machine_spi.c @@ -297,14 +297,15 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { .transfer = machine_hard_spi_transfer, }; -const mp_obj_type_t machine_hard_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_hard_spi_print, - .make_new = machine_hard_spi_make_new, - .protocol = &machine_hard_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_hard_spi_make_new, + locals_dict, &mp_machine_spi_locals_dict, + print, machine_hard_spi_print, + protocol, &machine_hard_spi_p + ); void spi_init0(void) { } diff --git a/ports/renesas-ra/machine_timer.c b/ports/renesas-ra/machine_timer.c index c387d35117d8..f3e5aafb7cab 100644 --- a/ports/renesas-ra/machine_timer.c +++ b/ports/renesas-ra/machine_timer.c @@ -136,10 +136,11 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); -const mp_obj_type_t machine_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = machine_timer_print, - .make_new = machine_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + machine_timer_make_new, + locals_dict, &machine_timer_locals_dict, + print, machine_timer_print + ); diff --git a/ports/renesas-ra/machine_uart.c b/ports/renesas-ra/machine_uart.c index 4b4aa3396b62..11f5d6825eb2 100644 --- a/ports/renesas-ra/machine_uart.c +++ b/ports/renesas-ra/machine_uart.c @@ -571,15 +571,16 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = machine_uart_print, - .make_new = machine_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&machine_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + machine_uart_make_new, + locals_dict, &machine_uart_locals_dict, + print, machine_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p + ); MP_REGISTER_ROOT_POINTER(struct _machine_uart_obj_t *machine_uart_obj_all[MICROPY_HW_MAX_UART + MICROPY_HW_MAX_LPUART]); diff --git a/ports/renesas-ra/storage.c b/ports/renesas-ra/storage.c index 8d94f6fb9c3b..f573894a5014 100644 --- a/ports/renesas-ra/storage.c +++ b/ports/renesas-ra/storage.c @@ -400,13 +400,14 @@ STATIC const mp_rom_map_elem_t pyb_flash_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table); -const mp_obj_type_t pyb_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .print = pyb_flash_print, - .make_new = pyb_flash_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_flash_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_flash_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + pyb_flash_make_new, + locals_dict, &pyb_flash_locals_dict, + print, pyb_flash_print + ); void pyb_flash_init_vfs(fs_user_mount_t *vfs) { vfs->base.type = &mp_fat_vfs_type; diff --git a/ports/renesas-ra/timer.c b/ports/renesas-ra/timer.c index 1ae936525eaf..8f7acbcdaa47 100644 --- a/ports/renesas-ra/timer.c +++ b/ports/renesas-ra/timer.c @@ -410,13 +410,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table); -const mp_obj_type_t pyb_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = pyb_timer_print, - .make_new = pyb_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + pyb_timer_make_new, + locals_dict, &pyb_timer_locals_dict, + print, pyb_timer_print + ); #if defined(TIMER_CHANNEL) /* @@ -502,12 +503,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_channel_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_channel_locals_dict, pyb_timer_channel_locals_dict_table); -STATIC const mp_obj_type_t pyb_timer_channel_type = { - { &mp_type_type }, - .name = MP_QSTR_TimerChannel, - .print = pyb_timer_channel_print, - .locals_dict = (mp_obj_dict_t *)&pyb_timer_channel_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_channel_type, + MP_QSTR_TimerChannel, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, &pyb_timer_channel_locals_dict, + print, pyb_timer_channel_print + ); #endif STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_obj_t callback) { diff --git a/ports/renesas-ra/usrsw.c b/ports/renesas-ra/usrsw.c index 572510816b1f..4107d7850d38 100644 --- a/ports/renesas-ra/usrsw.c +++ b/ports/renesas-ra/usrsw.c @@ -135,14 +135,15 @@ STATIC const mp_rom_map_elem_t pyb_switch_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_switch_locals_dict, pyb_switch_locals_dict_table); -const mp_obj_type_t pyb_switch_type = { - { &mp_type_type }, - .name = MP_QSTR_Switch, - .print = pyb_switch_print, - .make_new = pyb_switch_make_new, - .call = pyb_switch_call, - .locals_dict = (mp_obj_dict_t *)&pyb_switch_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_switch_type, + MP_QSTR_Switch, + MP_TYPE_FLAG_NONE, + pyb_switch_make_new, + locals_dict, &pyb_switch_locals_dict, + print, pyb_switch_print, + call, pyb_switch_call + ); MP_REGISTER_ROOT_POINTER(mp_obj_t pyb_switch_callback); diff --git a/ports/rp2/machine_adc.c b/ports/rp2/machine_adc.c index 5f91392e142d..549f8d5ecdc5 100644 --- a/ports/rp2/machine_adc.c +++ b/ports/rp2/machine_adc.c @@ -113,10 +113,11 @@ STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_adc_locals_dict, machine_adc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = machine_adc_print, - .make_new = machine_adc_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + machine_adc_make_new, + print, machine_adc_print, + locals_dict, (mp_obj_dict_t *)&machine_adc_locals_dict + ); diff --git a/ports/rp2/machine_i2c.c b/ports/rp2/machine_i2c.c index 3390cc42101d..91d8bb59b76c 100644 --- a/ports/rp2/machine_i2c.c +++ b/ports/rp2/machine_i2c.c @@ -176,11 +176,12 @@ STATIC const mp_machine_i2c_p_t machine_i2c_p = { .transfer_single = machine_i2c_transfer_single, }; -const mp_obj_type_t machine_hw_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_i2c_print, - .make_new = machine_i2c_make_new, - .protocol = &machine_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hw_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_i2c_make_new, + print, machine_i2c_print, + protocol, &machine_i2c_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + ); diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c index 1015ba10179a..8446a59781bb 100644 --- a/ports/rp2/machine_i2s.c +++ b/ports/rp2/machine_i2s.c @@ -1137,15 +1137,16 @@ STATIC const mp_stream_p_t i2s_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_i2s_type = { - { &mp_type_type }, - .name = MP_QSTR_I2S, - .print = machine_i2s_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &i2s_stream_p, - .make_new = machine_i2s_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_i2s_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_i2s_type, + MP_QSTR_I2S, + MP_TYPE_FLAG_NONE, + machine_i2s_make_new, + print, machine_i2s_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &i2s_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + ); MP_REGISTER_ROOT_POINTER(void *machine_i2s_obj[2]); diff --git a/ports/rp2/machine_pin.c b/ports/rp2/machine_pin.c index 705f61242c25..38670f09abea 100644 --- a/ports/rp2/machine_pin.c +++ b/ports/rp2/machine_pin.c @@ -641,15 +641,16 @@ STATIC const mp_pin_p_t pin_pin_p = { .ioctl = pin_ioctl, }; -const mp_obj_type_t machine_pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = machine_pin_print, - .make_new = mp_pin_make_new, - .call = machine_pin_call, - .protocol = &pin_pin_p, - .locals_dict = (mp_obj_t)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, machine_pin_print, + call, machine_pin_call, + protocol, &pin_pin_p, + locals_dict, (mp_obj_t)&machine_pin_locals_dict + ); STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/ports/rp2/machine_rtc.c b/ports/rp2/machine_rtc.c index 9d59124a66e1..73bdaee6c760 100644 --- a/ports/rp2/machine_rtc.c +++ b/ports/rp2/machine_rtc.c @@ -115,9 +115,10 @@ STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); -const mp_obj_type_t machine_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = machine_rtc_make_new, - .locals_dict = (mp_obj_t)&machine_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + machine_rtc_make_new, + locals_dict, (mp_obj_t)&machine_rtc_locals_dict + ); diff --git a/ports/rp2/machine_spi.c b/ports/rp2/machine_spi.c index 104bd1fd5338..f3ac8d7cf811 100644 --- a/ports/rp2/machine_spi.c +++ b/ports/rp2/machine_spi.c @@ -290,14 +290,15 @@ STATIC const mp_machine_spi_p_t machine_spi_p = { .transfer = machine_spi_transfer, }; -const mp_obj_type_t machine_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_spi_print, - .make_new = machine_spi_make_new, - .protocol = &machine_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_spi_make_new, + print, machine_spi_print, + protocol, &machine_spi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t o) { if (mp_obj_is_type(o, &machine_spi_type)) { diff --git a/ports/rp2/machine_timer.c b/ports/rp2/machine_timer.c index e7e8f02d5517..d3b60155294f 100644 --- a/ports/rp2/machine_timer.c +++ b/ports/rp2/machine_timer.c @@ -156,10 +156,11 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); -const mp_obj_type_t machine_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = machine_timer_print, - .make_new = machine_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + machine_timer_make_new, + print, machine_timer_print, + locals_dict, (mp_obj_dict_t *)&machine_timer_locals_dict + ); diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index f7e44b6b256c..df6228058be7 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -579,16 +579,17 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = machine_uart_print, - .make_new = machine_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&machine_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + machine_uart_make_new, + print, machine_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + ); MP_REGISTER_ROOT_POINTER(void *rp2_uart_rx_buffer[2]); MP_REGISTER_ROOT_POINTER(void *rp2_uart_tx_buffer[2]); diff --git a/ports/rp2/machine_wdt.c b/ports/rp2/machine_wdt.c index d6914a4f2615..e8c433306922 100644 --- a/ports/rp2/machine_wdt.c +++ b/ports/rp2/machine_wdt.c @@ -77,9 +77,10 @@ STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); -const mp_obj_type_t machine_wdt_type = { - { &mp_type_type }, - .name = MP_QSTR_WDT, - .make_new = machine_wdt_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_wdt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + machine_wdt_make_new, + locals_dict, (mp_obj_dict_t *)&machine_wdt_locals_dict + ); diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c index 47c95ea5c822..37a3412db5cf 100644 --- a/ports/rp2/rp2_flash.c +++ b/ports/rp2/rp2_flash.c @@ -185,9 +185,10 @@ STATIC const mp_rom_map_elem_t rp2_flash_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(rp2_flash_locals_dict, rp2_flash_locals_dict_table); -const mp_obj_type_t rp2_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .make_new = rp2_flash_make_new, - .locals_dict = (mp_obj_dict_t *)&rp2_flash_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + rp2_flash_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + rp2_flash_make_new, + locals_dict, (mp_obj_dict_t *)&rp2_flash_locals_dict + ); diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index eb85eb22480d..9a195bdd8a64 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -376,13 +376,14 @@ STATIC const mp_rom_map_elem_t rp2_pio_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(rp2_pio_locals_dict, rp2_pio_locals_dict_table); -const mp_obj_type_t rp2_pio_type = { - { &mp_type_type }, - .name = MP_QSTR_PIO, - .print = rp2_pio_print, - .make_new = rp2_pio_make_new, - .locals_dict = (mp_obj_dict_t *)&rp2_pio_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + rp2_pio_type, + MP_QSTR_PIO, + MP_TYPE_FLAG_NONE, + rp2_pio_make_new, + print, rp2_pio_print, + locals_dict, (mp_obj_dict_t *)&rp2_pio_locals_dict + ); STATIC mp_uint_t rp2_pio_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { rp2_pio_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -806,13 +807,14 @@ STATIC const mp_rom_map_elem_t rp2_state_machine_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(rp2_state_machine_locals_dict, rp2_state_machine_locals_dict_table); -const mp_obj_type_t rp2_state_machine_type = { - { &mp_type_type }, - .name = MP_QSTR_StateMachine, - .print = rp2_state_machine_print, - .make_new = rp2_state_machine_make_new, - .locals_dict = (mp_obj_dict_t *)&rp2_state_machine_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + rp2_state_machine_type, + MP_QSTR_StateMachine, + MP_TYPE_FLAG_NONE, + rp2_state_machine_make_new, + print, rp2_state_machine_print, + locals_dict, (mp_obj_dict_t *)&rp2_state_machine_locals_dict + ); STATIC mp_uint_t rp2_state_machine_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { rp2_state_machine_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index f4dd1aeb3c65..76aae8ffc576 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -162,11 +162,12 @@ STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_led_locals_dict, machine_led_locals_dict_table); -const mp_obj_type_t machine_led_type = { - { &mp_type_type }, - .name = MP_QSTR_LED, - .print = machine_led_print, - .make_new = mp_led_make_new, - .call = machine_led_call, - .locals_dict = (mp_obj_t)&machine_led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + mp_led_make_new, + print, machine_led_print, + call, machine_led_call, + locals_dict, (mp_obj_t)&machine_led_locals_dict + ); diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 161a3ccddd2a..d47982e0e1c6 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -287,15 +287,16 @@ STATIC const mp_pin_p_t pin_pin_p = { .ioctl = pin_ioctl, }; -const mp_obj_type_t machine_pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = machine_pin_print, - .make_new = mp_pin_make_new, - .call = machine_pin_call, - .protocol = &pin_pin_p, - .locals_dict = (mp_obj_t)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, machine_pin_print, + call, machine_pin_call, + protocol, &pin_pin_p, + locals_dict, (mp_obj_t)&machine_pin_locals_dict + ); /* STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { diff --git a/ports/samd/samd_flash.c b/ports/samd/samd_flash.c index 530e3d9c8e5b..6c74b59a263a 100644 --- a/ports/samd/samd_flash.c +++ b/ports/samd/samd_flash.c @@ -181,9 +181,10 @@ STATIC const mp_rom_map_elem_t samd_flash_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(samd_flash_locals_dict, samd_flash_locals_dict_table); -const mp_obj_type_t samd_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .make_new = samd_flash_make_new, - .locals_dict = (mp_obj_dict_t *)&samd_flash_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + samd_flash_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + samd_flash_make_new, + locals_dict, (mp_obj_dict_t *)&samd_flash_locals_dict + ); diff --git a/ports/stm32/accel.c b/ports/stm32/accel.c index b07791a9a0b5..276ce37d3ad4 100644 --- a/ports/stm32/accel.c +++ b/ports/stm32/accel.c @@ -281,11 +281,12 @@ STATIC const mp_rom_map_elem_t pyb_accel_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_accel_locals_dict, pyb_accel_locals_dict_table); -const mp_obj_type_t pyb_accel_type = { - { &mp_type_type }, - .name = MP_QSTR_Accel, - .make_new = pyb_accel_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_accel_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_accel_type, + MP_QSTR_Accel, + MP_TYPE_FLAG_NONE, + pyb_accel_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_accel_locals_dict + ); #endif // MICROPY_HW_HAS_MMA7660 || MICROPY_HW_HAS_KXTJ3 diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index 9d58cf2e7cf0..7e627d088f74 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -703,13 +703,14 @@ STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table); -const mp_obj_type_t pyb_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = adc_print, - .make_new = adc_make_new, - .locals_dict = (mp_obj_dict_t *)&adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + adc_make_new, + print, adc_print, + locals_dict, (mp_obj_dict_t *)&adc_locals_dict + ); /******************************************************************************/ /* adc all object */ @@ -911,11 +912,12 @@ STATIC const mp_rom_map_elem_t adc_all_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(adc_all_locals_dict, adc_all_locals_dict_table); -const mp_obj_type_t pyb_adc_all_type = { - { &mp_type_type }, - .name = MP_QSTR_ADCAll, - .make_new = adc_all_make_new, - .locals_dict = (mp_obj_dict_t *)&adc_all_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_adc_all_type, + MP_QSTR_ADCAll, + MP_TYPE_FLAG_NONE, + adc_all_make_new, + locals_dict, (mp_obj_dict_t *)&adc_all_locals_dict + ); #endif // MICROPY_HW_ENABLE_ADC diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index c41bf858a7ed..da50b30fef13 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -502,12 +502,13 @@ STATIC const mp_rom_map_elem_t pyb_dac_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_dac_locals_dict, pyb_dac_locals_dict_table); -const mp_obj_type_t pyb_dac_type = { - { &mp_type_type }, - .name = MP_QSTR_DAC, - .print = pyb_dac_print, - .make_new = pyb_dac_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_dac_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_dac_type, + MP_QSTR_DAC, + MP_TYPE_FLAG_NONE, + pyb_dac_make_new, + print, pyb_dac_print, + locals_dict, (mp_obj_dict_t *)&pyb_dac_locals_dict + ); #endif // MICROPY_HW_ENABLE_DAC diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index d68275bf19c4..4d2dc5d23be9 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -659,13 +659,14 @@ STATIC const mp_rom_map_elem_t extint_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(extint_locals_dict, extint_locals_dict_table); -const mp_obj_type_t extint_type = { - { &mp_type_type }, - .name = MP_QSTR_ExtInt, - .print = extint_obj_print, - .make_new = extint_make_new, - .locals_dict = (mp_obj_dict_t *)&extint_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + extint_type, + MP_QSTR_ExtInt, + MP_TYPE_FLAG_NONE, + extint_make_new, + print, extint_obj_print, + locals_dict, (mp_obj_dict_t *)&extint_locals_dict + ); void extint_init0(void) { for (int i = 0; i < PYB_EXTI_NUM_VECTORS; i++) { diff --git a/ports/stm32/lcd.c b/ports/stm32/lcd.c index a0e001d1fdad..a951ea766844 100644 --- a/ports/stm32/lcd.c +++ b/ports/stm32/lcd.c @@ -525,11 +525,12 @@ STATIC const mp_rom_map_elem_t pyb_lcd_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_lcd_locals_dict, pyb_lcd_locals_dict_table); -const mp_obj_type_t pyb_lcd_type = { - { &mp_type_type }, - .name = MP_QSTR_LCD, - .make_new = pyb_lcd_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_lcd_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_lcd_type, + MP_QSTR_LCD, + MP_TYPE_FLAG_NONE, + pyb_lcd_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_lcd_locals_dict + ); #endif // MICROPY_HW_HAS_LCD diff --git a/ports/stm32/led.c b/ports/stm32/led.c index 078327462ae1..6745ef60b8d1 100644 --- a/ports/stm32/led.c +++ b/ports/stm32/led.c @@ -381,13 +381,14 @@ STATIC const mp_rom_map_elem_t led_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table); -const mp_obj_type_t pyb_led_type = { - { &mp_type_type }, - .name = MP_QSTR_LED, - .print = led_obj_print, - .make_new = led_obj_make_new, - .locals_dict = (mp_obj_dict_t *)&led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + led_obj_make_new, + print, led_obj_print, + locals_dict, (mp_obj_dict_t *)&led_locals_dict + ); #else // For boards with no LEDs, we leave an empty function here so that we don't diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index ad7c994ba111..682bae3a6d13 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -492,12 +492,13 @@ STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_adc_locals_dict, machine_adc_locals_dict_table); -const mp_obj_type_t machine_adc_type = { - { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = machine_adc_print, - .make_new = machine_adc_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_adc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + machine_adc_make_new, + print, machine_adc_print, + locals_dict, (mp_obj_dict_t *)&machine_adc_locals_dict + ); #endif diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 262944585aaa..89970f234d19 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -236,13 +236,14 @@ STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { .transfer = machine_hard_i2c_transfer, }; -const mp_obj_type_t machine_hard_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_hard_i2c_print, - .make_new = machine_hard_i2c_make_new, - .protocol = &machine_hard_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_hard_i2c_make_new, + print, machine_hard_i2c_print, + protocol, &machine_hard_i2c_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + ); #endif // MICROPY_HW_ENABLE_HW_I2C diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c index 4f583a53e87b..7dc6439f25c0 100644 --- a/ports/stm32/machine_i2s.c +++ b/ports/stm32/machine_i2s.c @@ -1114,16 +1114,17 @@ STATIC const mp_stream_p_t i2s_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_i2s_type = { - { &mp_type_type }, - .name = MP_QSTR_I2S, - .print = machine_i2s_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &i2s_stream_p, - .make_new = machine_i2s_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_i2s_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_i2s_type, + MP_QSTR_I2S, + MP_TYPE_FLAG_NONE, + machine_i2s_make_new, + print, machine_i2s_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &i2s_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_MAX_I2S]); diff --git a/ports/stm32/machine_spi.c b/ports/stm32/machine_spi.c index 37c026cefc33..87561c2b7b1d 100644 --- a/ports/stm32/machine_spi.c +++ b/ports/stm32/machine_spi.c @@ -135,11 +135,12 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { .transfer = machine_hard_spi_transfer, }; -const mp_obj_type_t machine_hard_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_hard_spi_print, - .make_new = machine_hard_spi_make_new, - .protocol = &machine_hard_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_hard_spi_make_new, + print, machine_hard_spi_print, + protocol, &machine_hard_spi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c index c387d35117d8..bd9dbe609849 100644 --- a/ports/stm32/machine_timer.c +++ b/ports/stm32/machine_timer.c @@ -136,10 +136,11 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); -const mp_obj_type_t machine_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = machine_timer_print, - .make_new = machine_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&machine_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + machine_timer_make_new, + print, machine_timer_print, + locals_dict, (mp_obj_dict_t *)&machine_timer_locals_dict + ); diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index 1bb1d2a1a784..4d25a0274cdd 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -660,13 +660,14 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t pyb_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = pyb_uart_print, - .make_new = pyb_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&pyb_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + pyb_uart_make_new, + print, pyb_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t *)&pyb_uart_locals_dict + ); diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c index f19916a1df09..f9c7d80b78e9 100644 --- a/ports/stm32/network_lan.c +++ b/ports/stm32/network_lan.c @@ -158,12 +158,13 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table); -const mp_obj_type_t network_lan_type = { - { &mp_type_type }, - .name = MP_QSTR_LAN, - .print = network_lan_print, - .make_new = network_lan_make_new, - .locals_dict = (mp_obj_dict_t *)&network_lan_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + network_lan_type, + MP_QSTR_LAN, + MP_TYPE_FLAG_NONE, + network_lan_make_new, + print, network_lan_print, + locals_dict, (mp_obj_dict_t *)&network_lan_locals_dict + ); #endif // defined(MICROPY_HW_ETH_MDC) diff --git a/ports/stm32/pin.c b/ports/stm32/pin.c index af6bafc43f21..992046cd17e5 100644 --- a/ports/stm32/pin.c +++ b/ports/stm32/pin.c @@ -592,15 +592,16 @@ STATIC const mp_pin_p_t pin_pin_p = { .ioctl = pin_ioctl, }; -const mp_obj_type_t pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = pin_print, - .make_new = mp_pin_make_new, - .call = pin_call, - .protocol = &pin_pin_p, - .locals_dict = (mp_obj_dict_t *)&pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, pin_print, + call, pin_call, + protocol, &pin_pin_p, + locals_dict, (mp_obj_dict_t *)&pin_locals_dict + ); /// \moduleref pyb /// \class PinAF - Pin Alternate Functions @@ -669,12 +670,14 @@ STATIC const mp_rom_map_elem_t pin_af_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pin_af_locals_dict, pin_af_locals_dict_table); -const mp_obj_type_t pin_af_type = { - { &mp_type_type }, - .name = MP_QSTR_PinAF, - .print = pin_af_obj_print, - .locals_dict = (mp_obj_dict_t *)&pin_af_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_af_type, + MP_QSTR_PinAF, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pin_af_obj_print, + locals_dict, (mp_obj_dict_t *)&pin_af_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_class_mapper); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_class_map_dict); diff --git a/ports/stm32/pin_named_pins.c b/ports/stm32/pin_named_pins.c index 3a8e0f9fce9d..620888878c4a 100644 --- a/ports/stm32/pin_named_pins.c +++ b/ports/stm32/pin_named_pins.c @@ -31,17 +31,21 @@ #include "py/mphal.h" #include "pin.h" -const mp_obj_type_t pin_cpu_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_cpu, - .locals_dict = (mp_obj_dict_t *)&pin_cpu_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_cpu_pins_obj_type, + MP_QSTR_cpu, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&pin_cpu_pins_locals_dict + ); -const mp_obj_type_t pin_board_pins_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_board, - .locals_dict = (mp_obj_dict_t *)&pin_board_pins_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pin_board_pins_obj_type, + MP_QSTR_board, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&pin_board_pins_locals_dict + ); const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { const mp_map_t *named_map = &named_pins->map; diff --git a/ports/stm32/pyb_can.c b/ports/stm32/pyb_can.c index ff41de31868d..6fdfd2c8549e 100644 --- a/ports/stm32/pyb_can.c +++ b/ports/stm32/pyb_can.c @@ -1072,14 +1072,15 @@ STATIC const mp_stream_p_t can_stream_p = { .is_text = false, }; -const mp_obj_type_t pyb_can_type = { - { &mp_type_type }, - .name = MP_QSTR_CAN, - .print = pyb_can_print, - .make_new = pyb_can_make_new, - .protocol = &can_stream_p, - .locals_dict = (mp_obj_dict_t *)&pyb_can_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_can_type, + MP_QSTR_CAN, + MP_TYPE_FLAG_NONE, + pyb_can_make_new, + print, pyb_can_print, + protocol, &can_stream_p, + locals_dict, (mp_obj_dict_t *)&pyb_can_locals_dict + ); MP_REGISTER_ROOT_POINTER(struct _pyb_can_obj_t *pyb_can_obj_all[MICROPY_HW_MAX_CAN]); diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index e9877422ca0b..ee6983a143fd 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -1104,12 +1104,13 @@ STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table); -const mp_obj_type_t pyb_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = pyb_i2c_print, - .make_new = pyb_i2c_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + pyb_i2c_make_new, + print, pyb_i2c_print, + locals_dict, (mp_obj_dict_t *)&pyb_i2c_locals_dict + ); #endif // MICROPY_PY_PYB_LEGACY && MICROPY_HW_ENABLE_HW_I2C diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c index f2cdcebf2a72..b1425272feee 100644 --- a/ports/stm32/pyb_spi.c +++ b/ports/stm32/pyb_spi.c @@ -350,11 +350,12 @@ STATIC const mp_machine_spi_p_t pyb_spi_p = { .transfer = spi_transfer_machine, }; -const mp_obj_type_t pyb_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = pyb_spi_print, - .make_new = pyb_spi_make_new, - .protocol = &pyb_spi_p, - .locals_dict = (mp_obj_dict_t *)&pyb_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + pyb_spi_make_new, + print, pyb_spi_print, + protocol, &pyb_spi_p, + locals_dict, (mp_obj_dict_t *)&pyb_spi_locals_dict + ); diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c index 55977791b8c2..c7698db1430a 100644 --- a/ports/stm32/rtc.c +++ b/ports/stm32/rtc.c @@ -837,9 +837,10 @@ STATIC const mp_rom_map_elem_t pyb_rtc_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table); -const mp_obj_type_t pyb_rtc_type = { - { &mp_type_type }, - .name = MP_QSTR_RTC, - .make_new = pyb_rtc_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_rtc_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + pyb_rtc_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_rtc_locals_dict + ); diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index 6f5892570baf..b9cc051e7f13 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -872,21 +872,23 @@ STATIC const mp_rom_map_elem_t pyb_sdcard_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_sdcard_locals_dict, pyb_sdcard_locals_dict_table); #if MICROPY_HW_ENABLE_SDCARD -const mp_obj_type_t pyb_sdcard_type = { - { &mp_type_type }, - .name = MP_QSTR_SDCard, - .make_new = pyb_sdcard_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_sdcard_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_sdcard_type, + MP_QSTR_SDCard, + MP_TYPE_FLAG_NONE, + pyb_sdcard_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_sdcard_locals_dict + ); #endif #if MICROPY_HW_ENABLE_MMCARD -const mp_obj_type_t pyb_mmcard_type = { - { &mp_type_type }, - .name = MP_QSTR_MMCard, - .make_new = pyb_mmcard_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_sdcard_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_mmcard_type, + MP_QSTR_MMCard, + MP_TYPE_FLAG_NONE, + pyb_mmcard_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_sdcard_locals_dict + ); #endif void sdcard_init_vfs(fs_user_mount_t *vfs, int part) { diff --git a/ports/stm32/servo.c b/ports/stm32/servo.c index 17084224637e..d552f5e6b5d3 100644 --- a/ports/stm32/servo.c +++ b/ports/stm32/servo.c @@ -336,12 +336,13 @@ STATIC const mp_rom_map_elem_t pyb_servo_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_servo_locals_dict, pyb_servo_locals_dict_table); -const mp_obj_type_t pyb_servo_type = { - { &mp_type_type }, - .name = MP_QSTR_Servo, - .print = pyb_servo_print, - .make_new = pyb_servo_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_servo_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_servo_type, + MP_QSTR_Servo, + MP_TYPE_FLAG_NONE, + pyb_servo_make_new, + print, pyb_servo_print, + locals_dict, (mp_obj_dict_t *)&pyb_servo_locals_dict + ); #endif // MICROPY_HW_ENABLE_SERVO diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c index c33a75f67100..92f705949338 100644 --- a/ports/stm32/storage.c +++ b/ports/stm32/storage.c @@ -453,13 +453,14 @@ STATIC const mp_rom_map_elem_t pyb_flash_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table); -const mp_obj_type_t pyb_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_Flash, - .print = pyb_flash_print, - .make_new = pyb_flash_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_flash_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_flash_type, + MP_QSTR_Flash, + MP_TYPE_FLAG_NONE, + pyb_flash_make_new, + print, pyb_flash_print, + locals_dict, (mp_obj_dict_t *)&pyb_flash_locals_dict + ); void pyb_flash_init_vfs(fs_user_mount_t *vfs) { vfs->base.type = &mp_fat_vfs_type; diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index 518a2e23b473..abf4c1f3fc4c 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -1471,13 +1471,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table); -const mp_obj_type_t pyb_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = pyb_timer_print, - .make_new = pyb_timer_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + pyb_timer_make_new, + print, pyb_timer_print, + locals_dict, (mp_obj_dict_t *)&pyb_timer_locals_dict + ); /// \moduleref pyb /// \class TimerChannel - setup a channel for a timer. @@ -1610,12 +1611,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_channel_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_channel_locals_dict, pyb_timer_channel_locals_dict_table); -STATIC const mp_obj_type_t pyb_timer_channel_type = { - { &mp_type_type }, - .name = MP_QSTR_TimerChannel, - .print = pyb_timer_channel_print, - .locals_dict = (mp_obj_dict_t *)&pyb_timer_channel_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_channel_type, + MP_QSTR_TimerChannel, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pyb_timer_channel_print, + locals_dict, (mp_obj_dict_t *)&pyb_timer_channel_locals_dict + ); STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_obj_t callback) { uint32_t irq_mask = TIMER_IRQ_MASK(channel); diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index c5fdd88acfb8..7c36765c28c1 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -936,16 +936,17 @@ STATIC const mp_stream_p_t pyb_usb_vcp_stream_p = { .ioctl = pyb_usb_vcp_ioctl, }; -const mp_obj_type_t pyb_usb_vcp_type = { - { &mp_type_type }, - .name = MP_QSTR_USB_VCP, - .print = pyb_usb_vcp_print, - .make_new = pyb_usb_vcp_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &pyb_usb_vcp_stream_p, - .locals_dict = (mp_obj_dict_t *)&pyb_usb_vcp_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_usb_vcp_type, + MP_QSTR_USB_VCP, + MP_TYPE_FLAG_NONE, + pyb_usb_vcp_make_new, + print, pyb_usb_vcp_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &pyb_usb_vcp_stream_p, + locals_dict, (mp_obj_dict_t *)&pyb_usb_vcp_locals_dict + ); /******************************************************************************/ // MicroPython bindings for USB HID @@ -1077,13 +1078,14 @@ STATIC const mp_stream_p_t pyb_usb_hid_stream_p = { .ioctl = pyb_usb_hid_ioctl, }; -const mp_obj_type_t pyb_usb_hid_type = { - { &mp_type_type }, - .name = MP_QSTR_USB_HID, - .make_new = pyb_usb_hid_make_new, - .protocol = &pyb_usb_hid_stream_p, - .locals_dict = (mp_obj_dict_t *)&pyb_usb_hid_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_usb_hid_type, + MP_QSTR_USB_HID, + MP_TYPE_FLAG_NONE, + pyb_usb_hid_make_new, + protocol, &pyb_usb_hid_stream_p, + locals_dict, (mp_obj_dict_t *)&pyb_usb_hid_locals_dict + ); #endif // MICROPY_HW_USB_HID diff --git a/ports/stm32/usrsw.c b/ports/stm32/usrsw.c index 60aae1c8839d..137f4dabfa5c 100644 --- a/ports/stm32/usrsw.c +++ b/ports/stm32/usrsw.c @@ -134,14 +134,15 @@ STATIC const mp_rom_map_elem_t pyb_switch_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_switch_locals_dict, pyb_switch_locals_dict_table); -const mp_obj_type_t pyb_switch_type = { - { &mp_type_type }, - .name = MP_QSTR_Switch, - .print = pyb_switch_print, - .make_new = pyb_switch_make_new, - .call = pyb_switch_call, - .locals_dict = (mp_obj_dict_t *)&pyb_switch_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_switch_type, + MP_QSTR_Switch, + MP_TYPE_FLAG_NONE, + pyb_switch_make_new, + print, pyb_switch_print, + call, pyb_switch_call, + locals_dict, (mp_obj_dict_t *)&pyb_switch_locals_dict + ); MP_REGISTER_ROOT_POINTER(mp_obj_t pyb_switch_callback); diff --git a/ports/stm32/wdt.c b/ports/stm32/wdt.c index d794607bc0a7..e3b8e2e0ae22 100644 --- a/ports/stm32/wdt.c +++ b/ports/stm32/wdt.c @@ -102,9 +102,10 @@ STATIC const mp_rom_map_elem_t pyb_wdt_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_wdt_locals_dict, pyb_wdt_locals_dict_table); -const mp_obj_type_t pyb_wdt_type = { - { &mp_type_type }, - .name = MP_QSTR_WDT, - .make_new = pyb_wdt_make_new, - .locals_dict = (mp_obj_dict_t *)&pyb_wdt_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + pyb_wdt_make_new, + locals_dict, (mp_obj_dict_t *)&pyb_wdt_locals_dict + ); diff --git a/ports/teensy/led.c b/ports/teensy/led.c index d79e63cf7102..ca548431feca 100644 --- a/ports/teensy/led.c +++ b/ports/teensy/led.c @@ -134,10 +134,11 @@ STATIC const mp_rom_map_elem_t led_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table); -const mp_obj_type_t pyb_led_type = { - { &mp_type_type }, - .name = MP_QSTR_LED, - .print = led_obj_print, - .make_new = led_obj_make_new, - .locals_dict = (mp_obj_t)&led_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_led_type, + MP_QSTR_LED, + MP_TYPE_FLAG_NONE, + led_obj_make_new, + print, led_obj_print, + locals_dict, (mp_obj_t)&led_locals_dict + ); diff --git a/ports/teensy/timer.c b/ports/teensy/timer.c index 68dc965eb8bc..4df24743356c 100644 --- a/ports/teensy/timer.c +++ b/ports/teensy/timer.c @@ -746,13 +746,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table); -const mp_obj_type_t pyb_timer_type = { - { &mp_type_type }, - .name = MP_QSTR_Timer, - .print = pyb_timer_print, - .make_new = pyb_timer_make_new, - .locals_dict = (mp_obj_t)&pyb_timer_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + pyb_timer_make_new, + print, pyb_timer_print, + locals_dict, (mp_obj_t)&pyb_timer_locals_dict + ); /// \moduleref pyb /// \class TimerChannel - setup a channel for a timer. @@ -889,12 +890,14 @@ STATIC const mp_rom_map_elem_t pyb_timer_channel_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(pyb_timer_channel_locals_dict, pyb_timer_channel_locals_dict_table); -STATIC const mp_obj_type_t pyb_timer_channel_type = { - { &mp_type_type }, - .name = MP_QSTR_TimerChannel, - .print = pyb_timer_channel_print, - .locals_dict = (mp_obj_t)&pyb_timer_channel_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + pyb_timer_channel_type, + MP_QSTR_TimerChannel, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, pyb_timer_channel_print, + locals_dict, (mp_obj_t)&pyb_timer_channel_locals_dict + ); STATIC bool ftm_handle_irq_callback(pyb_timer_obj_t *self, mp_uint_t channel, mp_obj_t callback) { // execute callback if it's set diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c index 5b63fcb3cdd5..8957d9270946 100644 --- a/ports/teensy/uart.c +++ b/ports/teensy/uart.c @@ -483,10 +483,11 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table); -const mp_obj_type_t pyb_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = pyb_uart_print, - .make_new = pyb_uart_make_new, - .locals_dict = (mp_obj_t)&pyb_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + pyb_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + pyb_uart_make_new, + print, pyb_uart_print, + locals_dict, (mp_obj_t)&pyb_uart_locals_dict + ); diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index cf425ac4334f..b4567417a22a 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -106,11 +106,14 @@ STATIC const mp_stream_p_t fileio_stream_p = { .ioctl = stest_ioctl, }; -STATIC const mp_obj_type_t mp_type_stest_fileio = { - { &mp_type_type }, - .protocol = &fileio_stream_p, - .locals_dict = (mp_obj_dict_t *)&rawfile_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_stest_fileio, + MP_QSTR_stest_fileio, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + protocol, &fileio_stream_p, + locals_dict, (mp_obj_dict_t *)&rawfile_locals_dict + ); // stream read returns non-blocking error STATIC mp_uint_t stest_read2(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { @@ -133,11 +136,14 @@ STATIC const mp_stream_p_t textio_stream_p2 = { .is_text = true, }; -STATIC const mp_obj_type_t mp_type_stest_textio2 = { - { &mp_type_type }, - .protocol = &textio_stream_p2, - .locals_dict = (mp_obj_dict_t *)&rawfile_locals_dict2, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_stest_textio2, + MP_QSTR_stest_textio2, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + protocol, &textio_stream_p2, + locals_dict, (mp_obj_dict_t *)&rawfile_locals_dict2 + ); // str/bytes objects without a valid hash STATIC const mp_obj_str_t str_no_hash_obj = {{&mp_type_str}, 0, 10, (const byte *)"0123456789"}; diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 6417b5d3b395..98f0a1aa0ff6 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -421,13 +421,14 @@ STATIC const mp_rom_map_elem_t ffimod_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ffimod_locals_dict, ffimod_locals_dict_table); -STATIC const mp_obj_type_t ffimod_type = { - { &mp_type_type }, - .name = MP_QSTR_ffimod, - .print = ffimod_print, - .make_new = ffimod_make_new, - .locals_dict = (mp_obj_dict_t *)&ffimod_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ffimod_type, + MP_QSTR_ffimod, + MP_TYPE_FLAG_NONE, + ffimod_make_new, + print, ffimod_print, + locals_dict, (mp_obj_dict_t *)&ffimod_locals_dict + ); // FFI function @@ -530,12 +531,14 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_raise_TypeError(MP_ERROR_TEXT("don't know how to pass object to native function")); } -STATIC const mp_obj_type_t ffifunc_type = { - { &mp_type_type }, - .name = MP_QSTR_ffifunc, - .print = ffifunc_print, - .call = ffifunc_call, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ffifunc_type, + MP_QSTR_ffifunc, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, ffifunc_print, + call, ffifunc_call + ); // FFI callback for Python function @@ -556,12 +559,14 @@ STATIC const mp_rom_map_elem_t fficallback_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(fficallback_locals_dict, fficallback_locals_dict_table); -STATIC const mp_obj_type_t fficallback_type = { - { &mp_type_type }, - .name = MP_QSTR_fficallback, - .print = fficallback_print, - .locals_dict = (mp_obj_dict_t *)&fficallback_locals_dict -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + fficallback_type, + MP_QSTR_fficallback, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, fficallback_print, + locals_dict, (mp_obj_dict_t *)&fficallback_locals_dict + ); // FFI variable @@ -592,21 +597,25 @@ STATIC const mp_rom_map_elem_t ffivar_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(ffivar_locals_dict, ffivar_locals_dict_table); -STATIC const mp_obj_type_t ffivar_type = { - { &mp_type_type }, - .name = MP_QSTR_ffivar, - .print = ffivar_print, - .locals_dict = (mp_obj_dict_t *)&ffivar_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + ffivar_type, + MP_QSTR_ffivar, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, ffivar_print, + locals_dict, (mp_obj_dict_t *)&ffivar_locals_dict + ); // Generic opaque storage object (unused) /* -STATIC const mp_obj_type_t opaque_type = { - { &mp_type_type }, - .name = MP_QSTR_opaqueval, -// .print = opaque_print, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + opaque_type, + MP_QSTR_opaqueval, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + // .print = opaque_print, + ); */ STATIC mp_obj_t mod_ffi_open(size_t n_args, const mp_obj_t *args) { diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 6fa00731fb75..72f95b645b25 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -174,14 +174,16 @@ STATIC const mp_rom_map_elem_t jclass_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(jclass_locals_dict, jclass_locals_dict_table); -STATIC const mp_obj_type_t jclass_type = { - { &mp_type_type }, - .name = MP_QSTR_jclass, - .print = jclass_print, - .attr = jclass_attr, - .call = jclass_call, - .locals_dict = (mp_obj_dict_t *)&jclass_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + jclass_type, + MP_QSTR_jclass, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, jclass_print, + attr, jclass_attr, + call, jclass_call, + locals_dict, (mp_obj_dict_t *)&jclass_locals_dict + ); STATIC mp_obj_t new_jclass(jclass jc) { mp_obj_jclass_t *o = mp_obj_malloc(mp_obj_jclass_t, &jclass_type); @@ -320,16 +322,18 @@ STATIC mp_obj_t subscr_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { return mp_obj_new_getitem_iter(dest, iter_buf); } -STATIC const mp_obj_type_t jobject_type = { - { &mp_type_type }, - .name = MP_QSTR_jobject, - .print = jobject_print, - .unary_op = jobject_unary_op, - .attr = jobject_attr, - .subscr = jobject_subscr, - .getiter = subscr_getiter, -// .locals_dict = (mp_obj_dict_t*)&jobject_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + jobject_type, + MP_QSTR_jobject, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, jobject_print, + unary_op, jobject_unary_op, + attr, jobject_attr, + subscr, jobject_subscr, + getiter, subscr_getiter, + // .locals_dict = (mp_obj_dict_t*)&jobject_locals_dict, + ); STATIC mp_obj_t new_jobject(jobject jo) { if (jo == NULL) { @@ -567,14 +571,16 @@ STATIC mp_obj_t jmethod_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const return call_method(self->obj, name, methods, false, n_args, args); } -STATIC const mp_obj_type_t jmethod_type = { - { &mp_type_type }, - .name = MP_QSTR_jmethod, - .print = jmethod_print, - .call = jmethod_call, -// .attr = jobject_attr, -// .locals_dict = (mp_obj_dict_t*)&jobject_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + jmethod_type, + MP_QSTR_jmethod, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, jmethod_print, + call, jmethod_call, + // .attr = jobject_attr, + // .locals_dict = (mp_obj_dict_t*)&jobject_locals_dict, + ); #ifdef __ANDROID__ #define LIBJVM_SO "libdvm.so" diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index 2de4a316edb9..d8a8d1d8c38b 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -311,13 +311,15 @@ STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table); -STATIC const mp_obj_type_t mp_type_poll = { - { &mp_type_type }, - .name = MP_QSTR_poll, - .getiter = mp_identity_getiter, - .iternext = poll_iternext, - .locals_dict = (void *)&poll_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_poll, + MP_QSTR_poll, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, poll_iternext, + locals_dict, (void *)&poll_locals_dict + ); STATIC mp_obj_t select_poll(size_t n_args, const mp_obj_t *args) { int alloc = 4; diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 72c70d1750b5..7e4476cbd0ad 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -516,16 +516,17 @@ STATIC const mp_stream_p_t usocket_stream_p = { .ioctl = socket_ioctl, }; -const mp_obj_type_t mp_type_socket = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .print = socket_print, - .make_new = socket_make_new, - .getiter = NULL, - .iternext = NULL, - .protocol = &usocket_stream_p, - .locals_dict = (mp_obj_dict_t *)&usocket_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_socket, + MP_QSTR_socket, + MP_TYPE_FLAG_NONE, + socket_make_new, + print, socket_print, + getiter, NULL, + iternext, NULL, + protocol, &usocket_stream_p, + locals_dict, (mp_obj_dict_t *)&usocket_locals_dict + ); #define BINADDR_MAX_LEN sizeof(struct in6_addr) STATIC mp_obj_t mod_socket_inet_pton(mp_obj_t family_in, mp_obj_t addr_in) { diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c index 9bb63229ddb5..60a1924d803d 100644 --- a/ports/zephyr/machine_i2c.c +++ b/ports/zephyr/machine_i2c.c @@ -126,13 +126,14 @@ STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { .transfer_single = machine_hard_i2c_transfer_single, }; -const mp_obj_type_t machine_hard_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .print = machine_hard_i2c_print, - .make_new = machine_hard_i2c_make_new, - .protocol = &machine_hard_i2c_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + machine_hard_i2c_make_new, + print, machine_hard_i2c_print, + protocol, &machine_hard_i2c_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + ); #endif // MICROPY_PY_MACHINE_I2C diff --git a/ports/zephyr/machine_pin.c b/ports/zephyr/machine_pin.c index aa55c04104e4..48303edd8167 100644 --- a/ports/zephyr/machine_pin.c +++ b/ports/zephyr/machine_pin.c @@ -285,15 +285,16 @@ STATIC const mp_pin_p_t machine_pin_pin_p = { .ioctl = machine_pin_ioctl, }; -const mp_obj_type_t machine_pin_type = { - { &mp_type_type }, - .name = MP_QSTR_Pin, - .print = machine_pin_print, - .make_new = mp_pin_make_new, - .call = machine_pin_call, - .protocol = &machine_pin_pin_p, - .locals_dict = (mp_obj_t)&machine_pin_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_type, + MP_QSTR_Pin, + MP_TYPE_FLAG_NONE, + mp_pin_make_new, + print, machine_pin_print, + call, machine_pin_call, + protocol, &machine_pin_pin_p, + locals_dict, (mp_obj_t)&machine_pin_locals_dict + ); STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/ports/zephyr/machine_spi.c b/ports/zephyr/machine_spi.c index 2b0911c5917e..6d9bf896b06d 100644 --- a/ports/zephyr/machine_spi.c +++ b/ports/zephyr/machine_spi.c @@ -197,13 +197,14 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { .transfer = machine_hard_spi_transfer, }; -const mp_obj_type_t machine_hard_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .print = machine_hard_spi_print, - .make_new = machine_hard_spi_make_new, - .protocol = &machine_hard_spi_p, - .locals_dict = (mp_obj_dict_t *)&mp_machine_spi_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_hard_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + machine_hard_spi_make_new, + print, machine_hard_spi_print, + protocol, &machine_hard_spi_p, + locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + ); #endif // MICROPY_PY_MACHINE_SPI diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c index 3520795c5aad..3f5df7465791 100644 --- a/ports/zephyr/machine_uart.c +++ b/ports/zephyr/machine_uart.c @@ -154,13 +154,14 @@ STATIC const mp_stream_p_t uart_stream_p = { .is_text = false, }; -const mp_obj_type_t machine_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .print = machine_uart_print, - .make_new = machine_uart_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t *)&machine_uart_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + machine_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_NONE, + machine_uart_make_new, + print, machine_uart_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &uart_stream_p, + locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + ); diff --git a/ports/zephyr/modusocket.c b/ports/zephyr/modusocket.c index 17cf9babd333..a7bef74ca6de 100644 --- a/ports/zephyr/modusocket.c +++ b/ports/zephyr/modusocket.c @@ -353,14 +353,15 @@ STATIC const mp_stream_p_t socket_stream_p = { .ioctl = sock_ioctl, }; -STATIC const mp_obj_type_t socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .print = socket_print, - .make_new = socket_make_new, - .protocol = &socket_stream_p, - .locals_dict = (mp_obj_t)&socket_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + socket_type, + MP_QSTR_socket, + MP_TYPE_FLAG_NONE, + socket_make_new, + print, socket_print, + protocol, &socket_stream_p, + locals_dict, (mp_obj_t)&socket_locals_dict + ); // // getaddrinfo() implementation diff --git a/ports/zephyr/modzsensor.c b/ports/zephyr/modzsensor.c index ba6717046fa4..7c0b0193d326 100644 --- a/ports/zephyr/modzsensor.c +++ b/ports/zephyr/modzsensor.c @@ -105,12 +105,13 @@ STATIC const mp_rom_map_elem_t sensor_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(sensor_locals_dict, sensor_locals_dict_table); -STATIC const mp_obj_type_t sensor_type = { - { &mp_type_type }, - .name = MP_QSTR_Sensor, - .make_new = sensor_make_new, - .locals_dict = (void *)&sensor_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + sensor_type, + MP_QSTR_Sensor, + MP_TYPE_FLAG_NONE, + sensor_make_new, + locals_dict, (void *)&sensor_locals_dict + ); STATIC const mp_rom_map_elem_t mp_module_zsensor_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_zsensor) }, diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c index 1179c3fda809..ded7caa65763 100644 --- a/ports/zephyr/zephyr_storage.c +++ b/ports/zephyr/zephyr_storage.c @@ -128,13 +128,14 @@ STATIC const mp_rom_map_elem_t zephyr_disk_access_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(zephyr_disk_access_locals_dict, zephyr_disk_access_locals_dict_table); -const mp_obj_type_t zephyr_disk_access_type = { - { &mp_type_type }, - .name = MP_QSTR_DiskAccess, - .print = zephyr_disk_access_print, - .make_new = zephyr_disk_access_make_new, - .locals_dict = (mp_obj_dict_t *)&zephyr_disk_access_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + zephyr_disk_access_type, + MP_QSTR_DiskAccess, + MP_TYPE_FLAG_NONE, + zephyr_disk_access_make_new, + print, zephyr_disk_access_print, + locals_dict, (mp_obj_dict_t *)&zephyr_disk_access_locals_dict + ); #endif // CONFIG_DISK_ACCESS #ifdef CONFIG_FLASH_MAP @@ -249,11 +250,12 @@ STATIC const mp_rom_map_elem_t zephyr_flash_area_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(zephyr_flash_area_locals_dict, zephyr_flash_area_locals_dict_table); -const mp_obj_type_t zephyr_flash_area_type = { - { &mp_type_type }, - .name = MP_QSTR_FlashArea, - .print = zephyr_flash_area_print, - .make_new = zephyr_flash_area_make_new, - .locals_dict = (mp_obj_dict_t *)&zephyr_flash_area_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + zephyr_flash_area_type, + MP_QSTR_FlashArea, + MP_TYPE_FLAG_NONE, + zephyr_flash_area_make_new, + print, zephyr_flash_area_print, + locals_dict, (mp_obj_dict_t *)&zephyr_flash_area_locals_dict + ); #endif // CONFIG_FLASH_MAP diff --git a/py/builtinevex.c b/py/builtinevex.c index 73b77b40b70f..403cd95a9dee 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -38,10 +38,12 @@ typedef struct _mp_obj_code_t { mp_obj_t module_fun; } mp_obj_code_t; -STATIC const mp_obj_type_t mp_type_code = { - { &mp_type_type }, - .name = MP_QSTR_code, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_code, + MP_QSTR_code, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW + ); STATIC mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj_dict_t *locals) { // save context and set new context diff --git a/py/modio.c b/py/modio.c index d44c1948ab27..093cb1f7e78d 100644 --- a/py/modio.c +++ b/py/modio.c @@ -97,12 +97,13 @@ STATIC const mp_stream_p_t iobase_p = { .ioctl = iobase_ioctl, }; -STATIC const mp_obj_type_t mp_type_iobase = { - { &mp_type_type }, - .name = MP_QSTR_IOBase, - .make_new = iobase_make_new, - .protocol = &iobase_p, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_iobase, + MP_QSTR_IOBase, + MP_TYPE_FLAG_NONE, + iobase_make_new, + protocol, &iobase_p + ); #endif // MICROPY_PY_IO_IOBASE @@ -191,13 +192,14 @@ STATIC const mp_stream_p_t bufwriter_stream_p = { .write = bufwriter_write, }; -STATIC const mp_obj_type_t mp_type_bufwriter = { - { &mp_type_type }, - .name = MP_QSTR_BufferedWriter, - .make_new = bufwriter_make_new, - .protocol = &bufwriter_stream_p, - .locals_dict = (mp_obj_dict_t *)&bufwriter_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bufwriter, + MP_QSTR_BufferedWriter, + MP_TYPE_FLAG_NONE, + bufwriter_make_new, + protocol, &bufwriter_stream_p, + locals_dict, (mp_obj_dict_t *)&bufwriter_locals_dict + ); #endif // MICROPY_PY_IO_BUFFEREDWRITER STATIC const mp_rom_map_elem_t mp_module_io_globals_table[] = { diff --git a/py/modthread.c b/py/modthread.c index bad94fbf2f08..0a154474252d 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -116,11 +116,13 @@ STATIC const mp_rom_map_elem_t thread_lock_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(thread_lock_locals_dict, thread_lock_locals_dict_table); -STATIC const mp_obj_type_t mp_type_thread_lock = { - { &mp_type_type }, - .name = MP_QSTR_lock, - .locals_dict = (mp_obj_dict_t *)&thread_lock_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_thread_lock, + MP_QSTR_lock, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + locals_dict, (mp_obj_dict_t *)&thread_lock_locals_dict + ); /****************************************************************/ // _thread module diff --git a/py/objarray.c b/py/objarray.c index dca41c2931d6..d93cce29eef5 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -571,54 +571,55 @@ STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_ui } #if MICROPY_PY_ARRAY -const mp_obj_type_t mp_type_array = { - { &mp_type_type }, - .name = MP_QSTR_array, - .print = array_print, - .make_new = array_make_new, - .getiter = array_iterator_new, - .unary_op = array_unary_op, - .binary_op = array_binary_op, - .subscr = array_subscr, - .buffer_p = array_get_buffer, - .locals_dict = (mp_obj_dict_t *)&mp_obj_array_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_array, + MP_QSTR_array, + MP_TYPE_FLAG_NONE, + array_make_new, + print, array_print, + getiter, array_iterator_new, + unary_op, array_unary_op, + binary_op, array_binary_op, + subscr, array_subscr, + buffer, array_get_buffer, + locals_dict, (mp_obj_dict_t *)&mp_obj_array_locals_dict + ); #endif #if MICROPY_PY_BUILTINS_BYTEARRAY -const mp_obj_type_t mp_type_bytearray = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, - .name = MP_QSTR_bytearray, - .print = array_print, - .make_new = bytearray_make_new, - .getiter = array_iterator_new, - .unary_op = array_unary_op, - .binary_op = array_binary_op, - .subscr = array_subscr, - .buffer = array_get_buffer, - .locals_dict = (mp_obj_dict_t *)&mp_obj_bytearray_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bytearray, + MP_QSTR_bytearray, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + bytearray_make_new, + print, array_print, + getiter, array_iterator_new, + unary_op, array_unary_op, + binary_op, array_binary_op, + subscr, array_subscr, + buffer, array_get_buffer, + locals_dict, (mp_obj_dict_t *)&mp_obj_bytearray_locals_dict + ); #endif #if MICROPY_PY_BUILTINS_MEMORYVIEW -const mp_obj_type_t mp_type_memoryview = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, - .name = MP_QSTR_memoryview, - .make_new = memoryview_make_new, - .getiter = array_iterator_new, - .unary_op = array_unary_op, - .binary_op = array_binary_op, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_memoryview, + MP_QSTR_memoryview, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + memoryview_make_new, + getiter, array_iterator_new, + unary_op, array_unary_op, + binary_op, array_binary_op, #if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE - .attr = memoryview_attr, + attr, memoryview_attr, #endif #if MICROPY_PY_BUILTINS_BYTES_HEX - .locals_dict = (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, + locals_dict, (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, #endif .subscr = array_subscr, .buffer = array_get_buffer, -}; + ); #endif /* unused @@ -664,12 +665,14 @@ STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) { } } -STATIC const mp_obj_type_t mp_type_array_it = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = array_it_iternext, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_array_it, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, array_it_iternext + ); STATIC mp_obj_t array_iterator_new(mp_obj_t array_in, mp_obj_iter_buf_t *iter_buf) { assert(sizeof(mp_obj_array_t) <= sizeof(mp_obj_iter_buf_t)); diff --git a/py/objattrtuple.c b/py/objattrtuple.c index 13c281aa1c60..0d41ee52354a 100644 --- a/py/objattrtuple.c +++ b/py/objattrtuple.c @@ -80,15 +80,18 @@ mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *item return MP_OBJ_FROM_PTR(o); } -const mp_obj_type_t mp_type_attrtuple = { - { &mp_type_type }, - .name = MP_QSTR_tuple, // reuse tuple to save on a qstr - .print = mp_obj_attrtuple_print, - .unary_op = mp_obj_tuple_unary_op, - .binary_op = mp_obj_tuple_binary_op, - .attr = mp_obj_attrtuple_attr, - .subscr = mp_obj_tuple_subscr, - .getiter = mp_obj_tuple_getiter, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_attrtuple, + MP_QSTR_tuple, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + // reuse tuple to save on a qstr + print, mp_obj_attrtuple_print, + unary_op, mp_obj_tuple_unary_op, + binary_op, mp_obj_tuple_binary_op, + attr, mp_obj_attrtuple_attr, + subscr, mp_obj_tuple_subscr, + getiter, mp_obj_tuple_getiter + ); #endif // MICROPY_PY_ATTRTUPLE diff --git a/py/objbool.c b/py/objbool.c index 23e023d8cbc1..5d014bbb8eaf 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -84,15 +84,16 @@ STATIC mp_obj_t bool_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_ return mp_binary_op(op, MP_OBJ_NEW_SMALL_INT(value), rhs_in); } -const mp_obj_type_t mp_type_bool = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, // can match all numeric types - .name = MP_QSTR_bool, - .print = bool_print, - .make_new = bool_make_new, - .unary_op = bool_unary_op, - .binary_op = bool_binary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + // can match all numeric types + mp_type_bool, + MP_QSTR_bool, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + bool_make_new, + print, bool_print, + unary_op, bool_unary_op, + binary_op, bool_binary_op + ); #if !MICROPY_OBJ_IMMEDIATE_OBJS const mp_obj_bool_t mp_const_false_obj = {{&mp_type_bool}, false}; diff --git a/py/objboundmeth.c b/py/objboundmeth.c index 9936c06e494b..353364cdc70a 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -95,17 +95,19 @@ STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif -STATIC const mp_obj_type_t mp_type_bound_meth = { - { &mp_type_type }, - .name = MP_QSTR_bound_method, +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bound_meth, + MP_QSTR_bound_method, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - .print = bound_meth_print, + print, bound_meth_print, #endif - .call = bound_meth_call, + call, bound_meth_call #if MICROPY_PY_FUNCTION_ATTRS - .attr = bound_meth_attr, + , attr, bound_meth_attr #endif -}; + ); mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) { mp_obj_bound_meth_t *o = mp_obj_malloc(mp_obj_bound_meth_t, &mp_type_bound_meth); diff --git a/py/objcell.c b/py/objcell.c index cab0d0b030ee..a17a94b9b78e 100644 --- a/py/objcell.c +++ b/py/objcell.c @@ -40,13 +40,13 @@ STATIC void cell_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t k } #endif -STATIC const mp_obj_type_t mp_type_cell = { - { &mp_type_type }, - .name = MP_QSTR_, // cell representation is just value in < > +STATIC MP_DEFINE_CONST_OBJ_TYPE( + // cell representation is just value in < > + mp_type_cell, MP_QSTR_, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - .print = cell_print, + , print, cell_print #endif -}; + ); mp_obj_t mp_obj_new_cell(mp_obj_t obj) { mp_obj_cell_t *o = mp_obj_malloc(mp_obj_cell_t, &mp_type_cell); diff --git a/py/objclosure.c b/py/objclosure.c index 5b9923a44bc7..15ed994d3726 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -86,18 +86,19 @@ STATIC void mp_obj_closure_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif -const mp_obj_type_t mp_type_closure = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_closure, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_closure, + MP_QSTR_closure, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - .print = closure_print, + print, closure_print, #endif - .call = closure_call, #if MICROPY_PY_FUNCTION_ATTRS - .attr = mp_obj_closure_attr, + attr, mp_obj_closure_attr, #endif -}; + call, closure_call + ); mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed_over, const mp_obj_t *closed) { mp_obj_closure_t *o = mp_obj_malloc_var(mp_obj_closure_t, mp_obj_t, n_closed_over, &mp_type_closure); diff --git a/py/objcomplex.c b/py/objcomplex.c index 4aa598a0bcb7..cf213d718a79 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -151,16 +151,13 @@ STATIC void complex_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -const mp_obj_type_t mp_type_complex = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, - .name = MP_QSTR_complex, - .print = complex_print, - .make_new = complex_make_new, - .unary_op = complex_unary_op, - .binary_op = complex_binary_op, - .attr = complex_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_complex, MP_QSTR_complex, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, complex_make_new, + print, complex_print, + unary_op, complex_unary_op, + binary_op, complex_binary_op, + attr, complex_attr + ); mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) { mp_obj_complex_t *o = mp_obj_malloc(mp_obj_complex_t, &mp_type_complex); diff --git a/py/objdeque.c b/py/objdeque.c index b1c59a81e9f3..22770317ab31 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -155,12 +155,13 @@ STATIC const mp_rom_map_elem_t deque_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(deque_locals_dict, deque_locals_dict_table); -const mp_obj_type_t mp_type_deque = { - { &mp_type_type }, - .name = MP_QSTR_deque, - .make_new = deque_make_new, - .unary_op = deque_unary_op, - .locals_dict = (mp_obj_dict_t *)&deque_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_deque, + MP_QSTR_deque, + MP_TYPE_FLAG_NONE, + deque_make_new, + unary_op, deque_unary_op, + locals_dict, (mp_obj_dict_t *)&deque_locals_dict + ); #endif // MICROPY_PY_COLLECTIONS_DEQUE diff --git a/py/objdict.c b/py/objdict.c index 1d8e9059a188..6e217d5c9a71 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -461,12 +461,14 @@ STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) { } } -STATIC const mp_obj_type_t mp_type_dict_view_it = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = dict_view_it_iternext, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_dict_view_it, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, dict_view_it_iternext + ); STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in, mp_obj_iter_buf_t *iter_buf) { assert(sizeof(mp_obj_dict_view_it_t) <= sizeof(mp_obj_iter_buf_t)); @@ -512,13 +514,15 @@ STATIC mp_obj_t dict_view_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t return dict_binary_op(op, o->dict, rhs_in); } -STATIC const mp_obj_type_t mp_type_dict_view = { - { &mp_type_type }, - .name = MP_QSTR_dict_view, - .print = dict_view_print, - .binary_op = dict_view_binary_op, - .getiter = dict_view_getiter, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_dict_view, + MP_QSTR_dict_view, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, dict_view_print, + binary_op, dict_view_binary_op, + getiter, dict_view_getiter + ); STATIC mp_obj_t mp_obj_new_dict_view(mp_obj_t dict, mp_dict_view_kind_t kind) { mp_obj_dict_view_t *o = mp_obj_malloc(mp_obj_dict_view_t, &mp_type_dict_view); @@ -585,31 +589,33 @@ STATIC const mp_rom_map_elem_t dict_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table); -const mp_obj_type_t mp_type_dict = { - { &mp_type_type }, - .name = MP_QSTR_dict, - .print = dict_print, - .make_new = mp_obj_dict_make_new, - .unary_op = dict_unary_op, - .binary_op = dict_binary_op, - .subscr = dict_subscr, - .getiter = dict_getiter, - .locals_dict = (mp_obj_dict_t *)&dict_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_dict, + MP_QSTR_dict, + MP_TYPE_FLAG_NONE, + mp_obj_dict_make_new, + print, dict_print, + unary_op, dict_unary_op, + binary_op, dict_binary_op, + subscr, dict_subscr, + getiter, dict_getiter, + locals_dict, (mp_obj_dict_t *)&dict_locals_dict + ); #if MICROPY_PY_COLLECTIONS_ORDEREDDICT -const mp_obj_type_t mp_type_ordereddict = { - { &mp_type_type }, - .name = MP_QSTR_OrderedDict, - .print = dict_print, - .make_new = mp_obj_dict_make_new, - .unary_op = dict_unary_op, - .binary_op = dict_binary_op, - .subscr = dict_subscr, - .getiter = dict_getiter, - .parent = &mp_type_dict, - .locals_dict = (mp_obj_dict_t *)&dict_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_ordereddict, + MP_QSTR_OrderedDict, + MP_TYPE_FLAG_NONE, + mp_obj_dict_make_new, + print, dict_print, + unary_op, dict_unary_op, + binary_op, dict_binary_op, + subscr, dict_subscr, + getiter, dict_getiter, + parent, &mp_type_dict, + locals_dict, (mp_obj_dict_t *)&dict_locals_dict + ); #endif void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args) { diff --git a/py/objenumerate.c b/py/objenumerate.c index 241aef30236f..f4f4ff6ae1d9 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -67,13 +67,14 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz return MP_OBJ_FROM_PTR(o); } -const mp_obj_type_t mp_type_enumerate = { - { &mp_type_type }, - .name = MP_QSTR_enumerate, - .make_new = enumerate_make_new, - .iternext = enumerate_iternext, - .getiter = mp_identity_getiter, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_enumerate, + MP_QSTR_enumerate, + MP_TYPE_FLAG_NONE, + enumerate_make_new, + iternext, enumerate_iternext, + getiter, mp_identity_getiter + ); STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in) { assert(mp_obj_is_type(self_in, &mp_type_enumerate)); diff --git a/py/objexcept.c b/py/objexcept.c index 028b73fd8b21..190213e12f61 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -284,13 +284,14 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -const mp_obj_type_t mp_type_BaseException = { - { &mp_type_type }, - .name = MP_QSTR_BaseException, - .print = mp_obj_exception_print, - .make_new = mp_obj_exception_make_new, - .attr = mp_obj_exception_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_BaseException, + MP_QSTR_BaseException, + MP_TYPE_FLAG_NONE, + mp_obj_exception_make_new, + print, mp_obj_exception_print, + attr, mp_obj_exception_attr + ); // *FORMAT-OFF* diff --git a/py/objfilter.c b/py/objfilter.c index a402d8c64889..2b57300af3df 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -60,12 +60,13 @@ STATIC mp_obj_t filter_iternext(mp_obj_t self_in) { return MP_OBJ_STOP_ITERATION; } -const mp_obj_type_t mp_type_filter = { - { &mp_type_type }, - .name = MP_QSTR_filter, - .make_new = filter_make_new, - .getiter = mp_identity_getiter, - .iternext = filter_iternext, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_filter, + MP_QSTR_filter, + MP_TYPE_FLAG_NONE, + filter_make_new, + getiter, mp_identity_getiter, + iternext, filter_iternext + ); #endif // MICROPY_PY_BUILTINS_FILTER diff --git a/py/objfloat.c b/py/objfloat.c index 8e89b3da37be..9ecbab7a4ded 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -182,15 +182,12 @@ STATIC mp_obj_t float_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs return mp_obj_float_binary_op(op, lhs_val, rhs_in); } -const mp_obj_type_t mp_type_float = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, - .name = MP_QSTR_float, - .print = float_print, - .make_new = float_make_new, - .unary_op = float_unary_op, - .binary_op = float_binary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_float, MP_QSTR_float, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, float_make_new, + print, float_print, + unary_op, float_unary_op, + binary_op, float_binary_op + ); #if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D diff --git a/py/objfun.c b/py/objfun.c index 5fa9d71ddaf4..30de8670a1de 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -56,13 +56,11 @@ STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, return self->fun._0(); } -const mp_obj_type_t mp_type_fun_builtin_0 = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, - .name = MP_QSTR_function, - .call = fun_builtin_0_call, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_builtin_0, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + call, fun_builtin_0_call, + unary_op, mp_generic_unary_op + ); STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_1)); @@ -71,13 +69,11 @@ STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, return self->fun._1(args[0]); } -const mp_obj_type_t mp_type_fun_builtin_1 = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, - .name = MP_QSTR_function, - .call = fun_builtin_1_call, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_builtin_1, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + call, fun_builtin_1_call, + unary_op, mp_generic_unary_op + ); STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_2)); @@ -86,13 +82,11 @@ STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, return self->fun._2(args[0], args[1]); } -const mp_obj_type_t mp_type_fun_builtin_2 = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, - .name = MP_QSTR_function, - .call = fun_builtin_2_call, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_builtin_2, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + call, fun_builtin_2_call, + unary_op, mp_generic_unary_op + ); STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_3)); @@ -101,13 +95,11 @@ STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, return self->fun._3(args[0], args[1], args[2]); } -const mp_obj_type_t mp_type_fun_builtin_3 = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, - .name = MP_QSTR_function, - .call = fun_builtin_3_call, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_builtin_3, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + call, fun_builtin_3_call, + unary_op, mp_generic_unary_op + ); STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_var)); @@ -132,13 +124,11 @@ STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k } } -const mp_obj_type_t mp_type_fun_builtin_var = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, - .name = MP_QSTR_function, - .call = fun_builtin_var_call, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_builtin_var, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + call, fun_builtin_var_call, + unary_op, mp_generic_unary_op + ); /******************************************************************************/ /* byte code functions */ @@ -362,19 +352,20 @@ void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif -const mp_obj_type_t mp_type_fun_bc = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_function, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_bc, + MP_QSTR_function, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, #if MICROPY_CPYTHON_COMPAT - .print = fun_bc_print, + print, fun_bc_print, #endif - .call = fun_bc_call, - .unary_op = mp_generic_unary_op, + call, fun_bc_call, + unary_op, mp_generic_unary_op #if MICROPY_PY_FUNCTION_ATTRS - .attr = mp_obj_fun_bc_attr, + , attr, mp_obj_fun_bc_attr #endif -}; + ); mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *context, struct _mp_raw_code_t *const *child_table) { size_t n_def_args = 0; @@ -417,19 +408,20 @@ STATIC mp_obj_t fun_native_call(mp_obj_t self_in, size_t n_args, size_t n_kw, co return fun(self_in, n_args, n_kw, args); } -STATIC const mp_obj_type_t mp_type_fun_native = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_function, +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_native, + MP_QSTR_function, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, #if MICROPY_CPYTHON_COMPAT - .print = fun_bc_print, + print, fun_bc_print, #endif - .call = fun_native_call, - .unary_op = mp_generic_unary_op, #if MICROPY_PY_FUNCTION_ATTRS - .attr = mp_obj_fun_bc_attr, + attr, mp_obj_fun_bc_attr, #endif -}; + call, fun_native_call, + unary_op, mp_generic_unary_op + ); mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) { mp_obj_fun_bc_t *o = MP_OBJ_TO_PTR(mp_obj_new_fun_bc(def_args, (const byte *)fun_data, mc, child_table)); @@ -531,13 +523,14 @@ STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const return mp_native_to_obj(ret, self->type_sig); } -STATIC const mp_obj_type_t mp_type_fun_asm = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_function, - .call = fun_asm_call, - .unary_op = mp_generic_unary_op, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_asm, + MP_QSTR_function, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, + call, fun_asm_call, + unary_op, mp_generic_unary_op + ); mp_obj_t mp_obj_new_fun_asm(size_t n_args, const void *fun_data, mp_uint_t type_sig) { mp_obj_fun_asm_t *o = mp_obj_malloc(mp_obj_fun_asm_t, &mp_type_fun_asm); diff --git a/py/objgenerator.c b/py/objgenerator.c index 802fd45bbdf6..0ab80ca11825 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -70,16 +70,17 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons return MP_OBJ_FROM_PTR(o); } -const mp_obj_type_t mp_type_gen_wrap = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_generator, - .call = gen_wrap_call, - .unary_op = mp_generic_unary_op, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_gen_wrap, + MP_QSTR_generator, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, + call, gen_wrap_call, + unary_op, mp_generic_unary_op #if MICROPY_PY_FUNCTION_ATTRS - .attr = mp_obj_fun_bc_attr, + , attr, mp_obj_fun_bc_attr #endif -}; + ); /******************************************************************************/ // native generator wrapper @@ -131,16 +132,17 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k return MP_OBJ_FROM_PTR(o); } -const mp_obj_type_t mp_type_native_gen_wrap = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_generator, - .call = native_gen_wrap_call, - .unary_op = mp_generic_unary_op, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_native_gen_wrap, + MP_QSTR_generator, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, + call, native_gen_wrap_call, + unary_op, mp_generic_unary_op #if MICROPY_PY_FUNCTION_ATTRS - .attr = mp_obj_fun_bc_attr, + , attr, mp_obj_fun_bc_attr #endif -}; + ); #endif // MICROPY_EMIT_NATIVE @@ -357,12 +359,14 @@ STATIC const mp_rom_map_elem_t gen_instance_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(gen_instance_locals_dict, gen_instance_locals_dict_table); -const mp_obj_type_t mp_type_gen_instance = { - { &mp_type_type }, - .name = MP_QSTR_generator, - .print = gen_instance_print, - .unary_op = mp_generic_unary_op, - .getiter = mp_identity_getiter, - .iternext = gen_instance_iternext, - .locals_dict = (mp_obj_dict_t *)&gen_instance_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_gen_instance, + MP_QSTR_generator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, gen_instance_print, + unary_op, mp_generic_unary_op, + getiter, mp_identity_getiter, + iternext, gen_instance_iternext, + locals_dict, (mp_obj_dict_t *)&gen_instance_locals_dict + ); diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c index 31ed4a9228ce..ed2dfbbe1f9e 100644 --- a/py/objgetitemiter.c +++ b/py/objgetitemiter.c @@ -56,12 +56,14 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) { } } -STATIC const mp_obj_type_t mp_type_it = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = it_iternext, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_it, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, it_iternext + ); // args are those returned from mp_load_method_maybe (ie either an attribute or a method) mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args, mp_obj_iter_buf_t *iter_buf) { diff --git a/py/objint.c b/py/objint.c index 645b26996689..d7a3f9eb9d18 100644 --- a/py/objint.c +++ b/py/objint.c @@ -457,12 +457,13 @@ STATIC const mp_rom_map_elem_t int_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(int_locals_dict, int_locals_dict_table); -const mp_obj_type_t mp_type_int = { - { &mp_type_type }, - .name = MP_QSTR_int, - .print = mp_obj_int_print, - .make_new = mp_obj_int_make_new, - .unary_op = mp_obj_int_unary_op, - .binary_op = mp_obj_int_binary_op, - .locals_dict = (mp_obj_dict_t *)&int_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_int, + MP_QSTR_int, + MP_TYPE_FLAG_NONE, + mp_obj_int_make_new, + print, mp_obj_int_print, + unary_op, mp_obj_int_unary_op, + binary_op, mp_obj_int_binary_op, + locals_dict, (mp_obj_dict_t *)&int_locals_dict + ); diff --git a/py/objlist.c b/py/objlist.c index f431e273df0a..8c7921b9891b 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -452,17 +452,19 @@ STATIC const mp_rom_map_elem_t list_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(list_locals_dict, list_locals_dict_table); -const mp_obj_type_t mp_type_list = { - { &mp_type_type }, - .name = MP_QSTR_list, - .print = list_print, - .make_new = list_make_new, - .unary_op = list_unary_op, - .binary_op = list_binary_op, - .subscr = list_subscr, - .getiter = list_getiter, - .locals_dict = (mp_obj_dict_t *)&list_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_list, + MP_QSTR_list, + MP_TYPE_FLAG_NONE, + list_make_new, + print, list_print, + unary_op, list_unary_op, + binary_op, list_binary_op, + subscr, list_subscr, + getiter, list_getiter, + locals_dict, (mp_obj_dict_t *)&list_locals_dict + ); + void mp_obj_list_init(mp_obj_list_t *o, size_t n) { o->base.type = &mp_type_list; diff --git a/py/objmap.c b/py/objmap.c index 1f9275854f83..dc305e21b5cb 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -63,10 +63,11 @@ STATIC mp_obj_t map_iternext(mp_obj_t self_in) { return mp_call_function_n_kw(self->fun, self->n_iters, 0, nextses); } -const mp_obj_type_t mp_type_map = { - { &mp_type_type }, - .name = MP_QSTR_map, - .make_new = map_make_new, - .getiter = mp_identity_getiter, - .iternext = map_iternext, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_map, + MP_QSTR_map, + MP_TYPE_FLAG_NONE, + map_make_new, + getiter, mp_identity_getiter, + iternext, map_iternext + ); diff --git a/py/objmodule.c b/py/objmodule.c index 783d6b050868..6fc3653e6a24 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -130,12 +130,14 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -const mp_obj_type_t mp_type_module = { - { &mp_type_type }, - .name = MP_QSTR_module, - .print = module_print, - .attr = module_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_module, + MP_QSTR_module, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, module_print, + attr, module_attr + ); mp_obj_t mp_obj_new_module(qstr module_name) { mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map; diff --git a/py/objnone.c b/py/objnone.c index 271a8543f971..4fffbc997e89 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -43,12 +43,14 @@ STATIC void none_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } -const mp_obj_type_t mp_type_NoneType = { - { &mp_type_type }, - .name = MP_QSTR_NoneType, - .print = none_print, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_NoneType, + MP_QSTR_NoneType, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, none_print, + unary_op, mp_generic_unary_op + ); #if !MICROPY_OBJ_IMMEDIATE_OBJS const mp_obj_none_t mp_const_none_obj = {{&mp_type_NoneType}}; diff --git a/py/objobject.c b/py/objobject.c index 1652802805bb..617b40fbbf05 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -111,11 +111,12 @@ STATIC const mp_rom_map_elem_t object_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(object_locals_dict, object_locals_dict_table); #endif -const mp_obj_type_t mp_type_object = { - { &mp_type_type }, - .name = MP_QSTR_object, - .make_new = object_make_new, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_object, + MP_QSTR_object, + MP_TYPE_FLAG_NONE, + object_make_new #if MICROPY_CPYTHON_COMPAT - .locals_dict = (mp_obj_dict_t *)&object_locals_dict, + , locals_dict, (mp_obj_dict_t *)&object_locals_dict #endif -}; + ); diff --git a/py/objpolyiter.c b/py/objpolyiter.c index dac6a2545575..326153182bca 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -45,12 +45,14 @@ STATIC mp_obj_t polymorph_it_iternext(mp_obj_t self_in) { return self->iternext(self_in); } -const mp_obj_type_t mp_type_polymorph_iter = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = polymorph_it_iternext, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_polymorph_iter, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, polymorph_it_iternext + ); #if MICROPY_ENABLE_FINALISER // mp_type_polymorph_iter_with_finaliser is a variant of the universal iterator @@ -76,12 +78,13 @@ STATIC const mp_rom_map_elem_t mp_obj_polymorph_iter_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(mp_obj_polymorph_iter_locals_dict, mp_obj_polymorph_iter_locals_dict_table); -const mp_obj_type_t mp_type_polymorph_iter_with_finaliser = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = polymorph_it_iternext, - .locals_dict = (mp_obj_dict_t *)&mp_obj_polymorph_iter_locals_dict, -}; - +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_polymorph_iter_with_finaliser, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, polymorph_it_iternext, + locals_dict, (mp_obj_dict_t *)&mp_obj_polymorph_iter_locals_dict + ); #endif diff --git a/py/objproperty.c b/py/objproperty.c index 49327c981e0b..42c357f33050 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -90,12 +90,13 @@ STATIC const mp_rom_map_elem_t property_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(property_locals_dict, property_locals_dict_table); -const mp_obj_type_t mp_type_property = { - { &mp_type_type }, - .name = MP_QSTR_property, - .make_new = property_make_new, - .locals_dict = (mp_obj_dict_t *)&property_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_property, + MP_QSTR_property, + MP_TYPE_FLAG_NONE, + property_make_new, + locals_dict, (mp_obj_dict_t *)&property_locals_dict + ); const mp_obj_t *mp_obj_property_get(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &mp_type_property)); diff --git a/py/objrange.c b/py/objrange.c index 5496021892cb..adf4b17466ad 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -50,12 +50,14 @@ STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) { } } -STATIC const mp_obj_type_t mp_type_range_it = { - { &mp_type_type }, - .name = MP_QSTR_iterator, - .getiter = mp_identity_getiter, - .iternext = range_it_iternext, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_range_it, + MP_QSTR_iterator, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + getiter, mp_identity_getiter, + iternext, range_it_iternext + ); STATIC mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step, mp_obj_iter_buf_t *iter_buf) { assert(sizeof(mp_obj_range_it_t) <= sizeof(mp_obj_iter_buf_t)); @@ -208,18 +210,19 @@ STATIC void range_attr(mp_obj_t o_in, qstr attr, mp_obj_t *dest) { } #endif -const mp_obj_type_t mp_type_range = { - { &mp_type_type }, - .name = MP_QSTR_range, - .print = range_print, - .make_new = range_make_new, - .unary_op = range_unary_op, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_range, + MP_QSTR_range, + MP_TYPE_FLAG_NONE, + range_make_new, + print, range_print, + unary_op, range_unary_op, #if MICROPY_PY_BUILTINS_RANGE_BINOP - .binary_op = range_binary_op, + binary_op, range_binary_op, #endif - .subscr = range_subscr, - .getiter = range_getiter, + subscr, range_subscr, + getiter, range_getiter #if MICROPY_PY_BUILTINS_RANGE_ATTRS - .attr = range_attr, + , attr, range_attr #endif -}; + ); diff --git a/py/objreversed.c b/py/objreversed.c index 08961c0d2d89..bc1f07ddecc4 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -68,12 +68,13 @@ STATIC mp_obj_t reversed_iternext(mp_obj_t self_in) { return mp_obj_subscr(self->seq, MP_OBJ_NEW_SMALL_INT(self->cur_index), MP_OBJ_SENTINEL); } -const mp_obj_type_t mp_type_reversed = { - { &mp_type_type }, - .name = MP_QSTR_reversed, - .make_new = reversed_make_new, - .getiter = mp_identity_getiter, - .iternext = reversed_iternext, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_reversed, + MP_QSTR_reversed, + MP_TYPE_FLAG_NONE, + reversed_make_new, + getiter, mp_identity_getiter, + iternext, reversed_iternext + ); #endif // MICROPY_PY_BUILTINS_REVERSED diff --git a/py/objset.c b/py/objset.c index 26fd74398b8a..8fc744a14047 100644 --- a/py/objset.c +++ b/py/objset.c @@ -539,16 +539,17 @@ STATIC const mp_rom_map_elem_t set_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(set_locals_dict, set_locals_dict_table); -const mp_obj_type_t mp_type_set = { - { &mp_type_type }, - .name = MP_QSTR_set, - .print = set_print, - .make_new = set_make_new, - .unary_op = set_unary_op, - .binary_op = set_binary_op, - .getiter = set_getiter, - .locals_dict = (mp_obj_dict_t *)&set_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_set, + MP_QSTR_set, + MP_TYPE_FLAG_NONE, + set_make_new, + print, set_print, + unary_op, set_unary_op, + binary_op, set_binary_op, + getiter, set_getiter, + locals_dict, (mp_obj_dict_t *)&set_locals_dict + ); #if MICROPY_PY_BUILTINS_FROZENSET STATIC const mp_rom_map_elem_t frozenset_locals_dict_table[] = { @@ -564,17 +565,17 @@ STATIC const mp_rom_map_elem_t frozenset_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(frozenset_locals_dict, frozenset_locals_dict_table); -const mp_obj_type_t mp_type_frozenset = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, - .name = MP_QSTR_frozenset, - .print = set_print, - .make_new = set_make_new, - .unary_op = set_unary_op, - .binary_op = set_binary_op, - .getiter = set_getiter, - .locals_dict = (mp_obj_dict_t *)&frozenset_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_frozenset, + MP_QSTR_frozenset, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + set_make_new, + print, set_print, + unary_op, set_unary_op, + binary_op, set_binary_op, + getiter, set_getiter, + locals_dict, (mp_obj_dict_t *)&frozenset_locals_dict + ); #endif mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) { diff --git a/py/objsingleton.c b/py/objsingleton.c index 2b896305cff5..4a099657d4be 100644 --- a/py/objsingleton.c +++ b/py/objsingleton.c @@ -43,12 +43,11 @@ STATIC void singleton_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ mp_printf(print, "%q", self->name); } -const mp_obj_type_t mp_type_singleton = { - { &mp_type_type }, - .name = MP_QSTR_, - .print = singleton_print, - .unary_op = mp_generic_unary_op, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_singleton, MP_QSTR_, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, + print, singleton_print, + unary_op, mp_generic_unary_op + ); const mp_obj_singleton_t mp_const_ellipsis_obj = {{&mp_type_singleton}, MP_QSTR_Ellipsis}; #if MICROPY_PY_BUILTINS_NOTIMPLEMENTED diff --git a/py/objslice.c b/py/objslice.c index 0b34516c185a..98c03485ff39 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -92,16 +92,18 @@ STATIC const mp_rom_map_elem_t slice_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(slice_locals_dict, slice_locals_dict_table); #endif -const mp_obj_type_t mp_type_slice = { - { &mp_type_type }, - .name = MP_QSTR_slice, - .print = slice_print, +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_slice, + MP_QSTR_slice, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, slice_print #if MICROPY_PY_BUILTINS_SLICE_ATTRS - .attr = slice_attr, + , attr, slice_attr #elif MICROPY_PY_BUILTINS_SLICE_INDICES - .locals_dict = (mp_obj_dict_t *)&slice_locals_dict, + , locals_dict, (mp_obj_dict_t *)&slice_locals_dict #endif -}; + ); mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { mp_obj_slice_t *o = mp_obj_malloc(mp_obj_slice_t, &mp_type_slice); diff --git a/py/objstr.c b/py/objstr.c index 9dd7f65e66ca..77ca269d423b 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2143,31 +2143,33 @@ MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_memoryview_locals_dict, #if !MICROPY_PY_BUILTINS_STR_UNICODE STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); -const mp_obj_type_t mp_type_str = { - { &mp_type_type }, - .name = MP_QSTR_str, - .print = str_print, - .make_new = mp_obj_str_make_new, - .binary_op = mp_obj_str_binary_op, - .subscr = bytes_subscr, - .getiter = mp_obj_new_str_iterator, - .buffer = mp_obj_str_get_buffer, - .locals_dict = (mp_obj_dict_t *)&mp_obj_str_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_str, + MP_QSTR_str, + MP_TYPE_FLAG_NONE, + mp_obj_str_make_new, + print, str_print, + binary_op, mp_obj_str_binary_op, + subscr, bytes_subscr, + getiter, mp_obj_new_str_iterator, + buffer, mp_obj_str_get_buffer, + locals_dict, (mp_obj_dict_t *)&mp_obj_str_locals_dict + ); #endif // !MICROPY_PY_BUILTINS_STR_UNICODE -// Reuses most of methods from str -const mp_obj_type_t mp_type_bytes = { - { &mp_type_type }, - .name = MP_QSTR_bytes, - .print = str_print, - .make_new = bytes_make_new, - .binary_op = mp_obj_str_binary_op, - .subscr = bytes_subscr, - .getiter = mp_obj_new_bytes_iterator, - .buffer = mp_obj_str_get_buffer, - .locals_dict = (mp_obj_dict_t *)&mp_obj_bytes_locals_dict, -}; +// Reuses most methods from str +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bytes, + MP_QSTR_bytes, + MP_TYPE_FLAG_NONE, + bytes_make_new, + print, str_print, + binary_op, mp_obj_str_binary_op, + subscr, bytes_subscr, + getiter, mp_obj_new_bytes_iterator, + buffer, mp_obj_str_get_buffer, + locals_dict, (mp_obj_dict_t *)&mp_obj_bytes_locals_dict + ); // The zero-length bytes object, with data that includes a null-terminating byte const mp_obj_str_t mp_const_empty_bytes_obj = {{&mp_type_bytes}, 0, 0, (const byte *)""}; diff --git a/py/objstringio.c b/py/objstringio.c index 8b6c7531d79d..d781ccc789d2 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -244,16 +244,17 @@ STATIC const mp_stream_p_t stringio_stream_p = { .is_text = true, }; -const mp_obj_type_t mp_type_stringio = { - { &mp_type_type }, - .name = MP_QSTR_StringIO, - .print = stringio_print, - .make_new = stringio_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &stringio_stream_p, - .locals_dict = (mp_obj_dict_t *)&stringio_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_stringio, + MP_QSTR_StringIO, + MP_TYPE_FLAG_NONE, + stringio_make_new, + print, stringio_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &stringio_stream_p, + locals_dict, (mp_obj_dict_t *)&stringio_locals_dict + ); #if MICROPY_PY_IO_BYTESIO STATIC const mp_stream_p_t bytesio_stream_p = { @@ -262,16 +263,17 @@ STATIC const mp_stream_p_t bytesio_stream_p = { .ioctl = stringio_ioctl, }; -const mp_obj_type_t mp_type_bytesio = { - { &mp_type_type }, - .name = MP_QSTR_BytesIO, - .print = stringio_print, - .make_new = stringio_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &bytesio_stream_p, - .locals_dict = (mp_obj_dict_t *)&stringio_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_bytesio, + MP_QSTR_BytesIO, + MP_TYPE_FLAG_NONE, + stringio_make_new, + print, stringio_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &bytesio_stream_p, + locals_dict, (mp_obj_dict_t *)&stringio_locals_dict + ); #endif #endif diff --git a/py/objstrunicode.c b/py/objstrunicode.c index fef0353683c1..afef1498e98e 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -229,18 +229,19 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } } -const mp_obj_type_t mp_type_str = { - { &mp_type_type }, - .name = MP_QSTR_str, - .print = uni_print, - .make_new = mp_obj_str_make_new, - .unary_op = uni_unary_op, - .binary_op = mp_obj_str_binary_op, - .subscr = str_subscr, - .getiter = mp_obj_new_str_iterator, - .buffer = mp_obj_str_get_buffer, - .locals_dict = (mp_obj_dict_t *)&mp_obj_str_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_str, + MP_QSTR_str, + MP_TYPE_FLAG_NONE, + mp_obj_str_make_new, + print, uni_print, + unary_op, uni_unary_op, + binary_op, mp_obj_str_binary_op, + subscr, str_subscr, + getiter, mp_obj_new_str_iterator, + buffer, mp_obj_str_get_buffer, + locals_dict, (mp_obj_dict_t *)&mp_obj_str_locals_dict + ); /******************************************************************************/ /* str iterator */ diff --git a/py/objtuple.c b/py/objtuple.c index e0cec8447363..b2ea6e380eb1 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -224,17 +224,18 @@ STATIC const mp_rom_map_elem_t tuple_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(tuple_locals_dict, tuple_locals_dict_table); -const mp_obj_type_t mp_type_tuple = { - { &mp_type_type }, - .name = MP_QSTR_tuple, - .print = mp_obj_tuple_print, - .make_new = mp_obj_tuple_make_new, - .unary_op = mp_obj_tuple_unary_op, - .binary_op = mp_obj_tuple_binary_op, - .subscr = mp_obj_tuple_subscr, - .getiter = mp_obj_tuple_getiter, - .locals_dict = (mp_obj_dict_t *)&tuple_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_tuple, + MP_QSTR_tuple, + MP_TYPE_FLAG_NONE, + mp_obj_tuple_make_new, + print, mp_obj_tuple_print, + unary_op, mp_obj_tuple_unary_op, + binary_op, mp_obj_tuple_binary_op, + subscr, mp_obj_tuple_subscr, + getiter, mp_obj_tuple_getiter, + locals_dict, (mp_obj_dict_t *)&tuple_locals_dict + ); // the zero-length tuple const mp_obj_tuple_t mp_const_empty_tuple_obj = {{&mp_type_tuple}, 0}; diff --git a/py/objtype.c b/py/objtype.c index c0f68578092d..77fe8e22e384 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1098,15 +1098,16 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -const mp_obj_type_t mp_type_type = { - { &mp_type_type }, - .name = MP_QSTR_type, - .print = type_print, - .make_new = type_make_new, - .call = type_call, - .unary_op = mp_generic_unary_op, - .attr = type_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_type, + MP_QSTR_type, + MP_TYPE_FLAG_NONE, + type_make_new, + print, type_print, + call, type_call, + unary_op, mp_generic_unary_op, + attr, type_attr + ); mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) { // Verify input objects have expected type @@ -1314,13 +1315,14 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_class_lookup(&lookup, &mp_type_object); } -const mp_obj_type_t mp_type_super = { - { &mp_type_type }, - .name = MP_QSTR_super, - .print = super_print, - .make_new = super_make_new, - .attr = super_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_super, + MP_QSTR_super, + MP_TYPE_FLAG_NONE, + super_make_new, + print, super_print, + attr, super_attr + ); void mp_load_super_method(qstr attr, mp_obj_t *dest) { mp_obj_super_t super = {{&mp_type_super}, dest[1], dest[2]}; @@ -1436,14 +1438,16 @@ STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n return MP_OBJ_FROM_PTR(o); } -const mp_obj_type_t mp_type_staticmethod = { - { &mp_type_type }, - .name = MP_QSTR_staticmethod, - .make_new = static_class_method_make_new, -}; - -const mp_obj_type_t mp_type_classmethod = { - { &mp_type_type }, - .name = MP_QSTR_classmethod, - .make_new = static_class_method_make_new, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_staticmethod, + MP_QSTR_staticmethod, + MP_TYPE_FLAG_NONE, + static_class_method_make_new + ); + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_classmethod, + MP_QSTR_classmethod, + MP_TYPE_FLAG_NONE, + static_class_method_make_new + ); diff --git a/py/objzip.c b/py/objzip.c index 81fa1d587e37..0ceafd97f240 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -66,10 +66,11 @@ STATIC mp_obj_t zip_iternext(mp_obj_t self_in) { return MP_OBJ_FROM_PTR(tuple); } -const mp_obj_type_t mp_type_zip = { - { &mp_type_type }, - .name = MP_QSTR_zip, - .make_new = zip_make_new, - .getiter = mp_identity_getiter, - .iternext = zip_iternext, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_zip, + MP_QSTR_zip, + MP_TYPE_FLAG_NONE, + zip_make_new, + getiter, mp_identity_getiter, + iternext, zip_iternext + ); diff --git a/py/profile.c b/py/profile.c index 4e23e9eac43b..2b9531e245ac 100644 --- a/py/profile.c +++ b/py/profile.c @@ -172,13 +172,15 @@ STATIC void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -const mp_obj_type_t mp_type_settrace_codeobj = { - { &mp_type_type }, - .name = MP_QSTR_code, - .print = code_print, - .unary_op = mp_generic_unary_op, - .attr = code_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_settrace_codeobj, + MP_QSTR_code, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, code_print, + unary_op, mp_generic_unary_op, + attr, code_attr + ); mp_obj_t mp_obj_new_code(const mp_module_context_t *context, const mp_raw_code_t *rc) { mp_obj_code_t *o = m_new_obj_maybe(mp_obj_code_t); @@ -241,13 +243,15 @@ STATIC void frame_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -const mp_obj_type_t mp_type_frame = { - { &mp_type_type }, - .name = MP_QSTR_frame, - .print = frame_print, - .unary_op = mp_generic_unary_op, - .attr = frame_attr, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_frame, + MP_QSTR_frame, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, frame_print, + unary_op, mp_generic_unary_op, + attr, frame_attr + ); mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state) { if (gc_is_locked()) { diff --git a/py/runtime.c b/py/runtime.c index ea3553db7227..27b4f05f0460 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1070,12 +1070,13 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c return mp_call_function_n_kw(self->fun, n_args, n_kw, args); } -STATIC const mp_obj_type_t mp_type_checked_fun = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_BINDS_SELF, - .name = MP_QSTR_function, - .call = checked_fun_call, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + mp_type_checked_fun, + MP_QSTR_function, + MP_TYPE_FLAG_BINDS_SELF, + MP_TYPE_NULL_MAKE_NEW, + call, checked_fun_call + ); STATIC mp_obj_t mp_obj_new_checked_fun(const mp_obj_type_t *type, mp_obj_t fun) { mp_obj_checked_fun_t *o = mp_obj_malloc(mp_obj_checked_fun_t, &mp_type_checked_fun); diff --git a/shared/runtime/mpirq.c b/shared/runtime/mpirq.c index 8e474bf5a2b1..763da6e0e444 100644 --- a/shared/runtime/mpirq.c +++ b/shared/runtime/mpirq.c @@ -125,11 +125,13 @@ STATIC const mp_rom_map_elem_t mp_irq_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(mp_irq_locals_dict, mp_irq_locals_dict_table); -const mp_obj_type_t mp_irq_type = { - { &mp_type_type }, - .name = MP_QSTR_irq, - .call = mp_irq_call, - .locals_dict = (mp_obj_dict_t *)&mp_irq_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + mp_irq_type, + MP_QSTR_irq, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + call, mp_irq_call, + locals_dict, (mp_obj_dict_t *)&mp_irq_locals_dict + ); #endif // MICROPY_ENABLE_SCHEDULER diff --git a/shared/runtime/sys_stdio_mphal.c b/shared/runtime/sys_stdio_mphal.c index 24f528b0c4f8..f1290853da73 100644 --- a/shared/runtime/sys_stdio_mphal.c +++ b/shared/runtime/sys_stdio_mphal.c @@ -123,15 +123,17 @@ STATIC const mp_stream_p_t stdio_obj_stream_p = { .is_text = true, }; -STATIC const mp_obj_type_t stdio_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .print = stdio_obj_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &stdio_obj_stream_p, - .locals_dict = (mp_obj_dict_t *)&stdio_locals_dict, -}; +MP_DEFINE_CONST_OBJ_TYPE( + stdio_obj_type, + MP_QSTR_FileIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, stdio_obj_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &stdio_obj_stream_p, + locals_dict, (mp_obj_dict_t *)&stdio_locals_dict + ); const sys_stdio_obj_t mp_sys_stdin_obj = {{&stdio_obj_type}, .fd = STDIO_FD_IN}; const sys_stdio_obj_t mp_sys_stdout_obj = {{&stdio_obj_type}, .fd = STDIO_FD_OUT}; @@ -157,15 +159,17 @@ STATIC const mp_stream_p_t stdio_buffer_obj_stream_p = { .is_text = false, }; -STATIC const mp_obj_type_t stdio_buffer_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .print = stdio_obj_print, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &stdio_buffer_obj_stream_p, - .locals_dict = (mp_obj_dict_t *)&stdio_locals_dict, -}; +STATIC MP_DEFINE_CONST_OBJ_TYPE( + stdio_buffer_obj_type, + MP_QSTR_FileIO, + MP_TYPE_FLAG_NONE, + MP_TYPE_NULL_MAKE_NEW, + print, stdio_obj_print, + getiter, mp_identity_getiter, + iternext, mp_stream_unbuffered_iter, + protocol, &stdio_buffer_obj_stream_p, + locals_dict, (mp_obj_dict_t *)&stdio_locals_dict + ); STATIC const sys_stdio_obj_t stdio_buffer_obj = {{&stdio_buffer_obj_type}, .fd = 0}; // fd unused #endif From b7d6ee9b75650bd0ac36e89077d5d08a3eed9e3f Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 24 Jun 2022 16:22:38 +1000 Subject: [PATCH 1743/4290] all: Fix #if inside MP_DEFINE_CONST_OBJ_TYPE for msvc. Changes: MP_DEFINE_CONST_OBJ_TYPE( ... #if FOO ... #endif ... ); to: MP_DEFINE_CONST_OBJ_TYPE( ... FOO_TYPE_ATTR ... ); Signed-off-by: Jim Mussared --- extmod/vfs_lfsx.c | 14 +++++++++----- py/objarray.c | 26 +++++++++++++++++--------- py/objboundmeth.c | 20 ++++++++++++++------ py/objcell.c | 10 +++++++--- py/objclosure.c | 17 +++++++++++------ py/objfun.c | 39 +++++++++++++++++++++++++++------------ py/objgenerator.c | 20 ++++++++++++++------ py/objobject.c | 10 +++++++--- py/objrange.c | 20 ++++++++++++++------ py/objslice.c | 14 +++++++++----- 10 files changed, 129 insertions(+), 61 deletions(-) diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index 72c6696105d9..3f8d262a4858 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -502,15 +502,19 @@ STATIC const mp_vfs_proto_t MP_VFS_LFSx(proto) = { .import_stat = MP_VFS_LFSx(import_stat), }; +#if LFS_BUILD_VERSION == 1 +#define VFS_LFSx_QSTR MP_QSTR_VfsLfs1 +#else +#define VFS_LFSx_QSTR MP_QSTR_VfsLfs2 +#endif + MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_VFS_LFSx, - #if LFS_BUILD_VERSION == 1 - MP_QSTR_VfsLfs1, - #else - MP_QSTR_VfsLfs2, - #endif + VFS_LFSx_QSTR, MP_TYPE_FLAG_NONE, MP_VFS_LFSx(make_new), protocol, &MP_VFS_LFSx(proto), locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(locals_dict) ); + +#undef VFS_LFSx_QSTR diff --git a/py/objarray.c b/py/objarray.c index d93cce29eef5..8d0fe7f58503 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -603,6 +603,18 @@ MP_DEFINE_CONST_OBJ_TYPE( #endif #if MICROPY_PY_BUILTINS_MEMORYVIEW +#if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE +#define MEMORYVIEW_TYPE_ATTR attr, memoryview_attr, +#else +#define MEMORYVIEW_TYPE_ATTR +#endif + +#if MICROPY_PY_BUILTINS_BYTES_HEX +#define MEMORYVIEW_TYPE_LOCALS_DICT locals_dict, (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, +#else +#define MEMORYVIEW_TYPE_LOCALS_DICT +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_memoryview, MP_QSTR_memoryview, @@ -611,16 +623,12 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, array_iterator_new, unary_op, array_unary_op, binary_op, array_binary_op, - #if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE - attr, memoryview_attr, - #endif - #if MICROPY_PY_BUILTINS_BYTES_HEX - locals_dict, (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, - #endif - .subscr = array_subscr, - .buffer = array_get_buffer, + MEMORYVIEW_TYPE_LOCALS_DICT + MEMORYVIEW_TYPE_ATTR + subscr, array_subscr, + buffer, array_get_buffer ); -#endif +#endif // MICROPY_PY_BUILTINS_MEMORYVIEW /* unused size_t mp_obj_array_len(mp_obj_t self_in) { diff --git a/py/objboundmeth.c b/py/objboundmeth.c index 353364cdc70a..f4b3b9b7df9c 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -95,18 +95,26 @@ STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED +#define BOUND_METH_TYPE_PRINT print, bound_meth_print, +#else +#define BOUND_METH_TYPE_PRINT +#endif + +#if MICROPY_PY_FUNCTION_ATTRS +#define BOUND_METH_TYPE_ATTR attr, bound_meth_attr, +#else +#define BOUND_METH_TYPE_ATTR +#endif + STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_bound_meth, MP_QSTR_bound_method, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - print, bound_meth_print, - #endif + BOUND_METH_TYPE_PRINT + BOUND_METH_TYPE_ATTR call, bound_meth_call - #if MICROPY_PY_FUNCTION_ATTRS - , attr, bound_meth_attr - #endif ); mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) { diff --git a/py/objcell.c b/py/objcell.c index a17a94b9b78e..b100fae4fe99 100644 --- a/py/objcell.c +++ b/py/objcell.c @@ -40,12 +40,16 @@ STATIC void cell_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t k } #endif +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED +#define CELL_TYPE_PRINT , print, cell_print +#else +#define CELL_TYPE_PRINT +#endif + STATIC MP_DEFINE_CONST_OBJ_TYPE( // cell representation is just value in < > mp_type_cell, MP_QSTR_, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - , print, cell_print - #endif + CELL_TYPE_PRINT ); mp_obj_t mp_obj_new_cell(mp_obj_t obj) { diff --git a/py/objclosure.c b/py/objclosure.c index 15ed994d3726..45a3e83c462d 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -84,6 +84,15 @@ STATIC void mp_obj_closure_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_closure_t *o = MP_OBJ_TO_PTR(self_in); mp_load_method_maybe(o->fun, attr, dest); } +#define CLOSURE_TYPE_ATTR attr, mp_obj_closure_attr, +#else +#define CLOSURE_TYPE_ATTR +#endif + +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED +#define CLOSURE_TYPE_PRINT print, closure_print, +#else +#define CLOSURE_TYPE_PRINT #endif MP_DEFINE_CONST_OBJ_TYPE( @@ -91,12 +100,8 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_closure, MP_TYPE_FLAG_BINDS_SELF, MP_TYPE_NULL_MAKE_NEW, - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - print, closure_print, - #endif - #if MICROPY_PY_FUNCTION_ATTRS - attr, mp_obj_closure_attr, - #endif + CLOSURE_TYPE_ATTR + CLOSURE_TYPE_PRINT call, closure_call ); diff --git a/py/objfun.c b/py/objfun.c index 30de8670a1de..d6ff354575bf 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -352,19 +352,27 @@ void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif +#if MICROPY_CPYTHON_COMPAT +#define FUN_BC_TYPE_PRINT print, fun_bc_print, +#else +#define FUN_BC_TYPE_PRINT +#endif + +#if MICROPY_PY_FUNCTION_ATTRS +#define FUN_BC_TYPE_ATTR attr, mp_obj_fun_bc_attr, +#else +#define FUN_BC_TYPE_ATTR +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_fun_bc, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, MP_TYPE_NULL_MAKE_NEW, - #if MICROPY_CPYTHON_COMPAT - print, fun_bc_print, - #endif + FUN_BC_TYPE_PRINT + FUN_BC_TYPE_ATTR call, fun_bc_call, unary_op, mp_generic_unary_op - #if MICROPY_PY_FUNCTION_ATTRS - , attr, mp_obj_fun_bc_attr - #endif ); mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *context, struct _mp_raw_code_t *const *child_table) { @@ -408,17 +416,24 @@ STATIC mp_obj_t fun_native_call(mp_obj_t self_in, size_t n_args, size_t n_kw, co return fun(self_in, n_args, n_kw, args); } +#if MICROPY_CPYTHON_COMPAT +#define FUN_BC_TYPE_PRINT print, fun_bc_print, +#else +#define FUN_BC_TYPE_PRINT +#endif +#if MICROPY_PY_FUNCTION_ATTRS +#define FUN_BC_TYPE_ATTR attr, mp_obj_fun_bc_attr, +#else +#define FUN_BC_TYPE_ATTR +#endif + STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_fun_native, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, MP_TYPE_NULL_MAKE_NEW, - #if MICROPY_CPYTHON_COMPAT - print, fun_bc_print, - #endif - #if MICROPY_PY_FUNCTION_ATTRS - attr, mp_obj_fun_bc_attr, - #endif + FUN_BC_TYPE_PRINT + FUN_BC_TYPE_ATTR call, fun_native_call, unary_op, mp_generic_unary_op ); diff --git a/py/objgenerator.c b/py/objgenerator.c index 0ab80ca11825..299f25e7bb63 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -70,16 +70,20 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons return MP_OBJ_FROM_PTR(o); } +#if MICROPY_PY_FUNCTION_ATTRS +#define GEN_WRAP_TYPE_ATTR attr, mp_obj_fun_bc_attr, +#else +#define GEN_WRAP_TYPE_ATTR +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_gen_wrap, MP_QSTR_generator, MP_TYPE_FLAG_BINDS_SELF, MP_TYPE_NULL_MAKE_NEW, + GEN_WRAP_TYPE_ATTR call, gen_wrap_call, unary_op, mp_generic_unary_op - #if MICROPY_PY_FUNCTION_ATTRS - , attr, mp_obj_fun_bc_attr - #endif ); /******************************************************************************/ @@ -132,16 +136,20 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k return MP_OBJ_FROM_PTR(o); } +#if MICROPY_PY_FUNCTION_ATTRS +#define NATIVE_GEN_WRAP_TYPE_ATTR attr, mp_obj_fun_bc_attr, +#else +#define NATIVE_GEN_WRAP_TYPE_ATTR +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_native_gen_wrap, MP_QSTR_generator, MP_TYPE_FLAG_BINDS_SELF, MP_TYPE_NULL_MAKE_NEW, call, native_gen_wrap_call, + NATIVE_GEN_WRAP_TYPE_ATTR unary_op, mp_generic_unary_op - #if MICROPY_PY_FUNCTION_ATTRS - , attr, mp_obj_fun_bc_attr - #endif ); #endif // MICROPY_EMIT_NATIVE diff --git a/py/objobject.c b/py/objobject.c index 617b40fbbf05..868a85b32ab0 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -111,12 +111,16 @@ STATIC const mp_rom_map_elem_t object_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(object_locals_dict, object_locals_dict_table); #endif +#if MICROPY_CPYTHON_COMPAT +#define OBJECT_TYPE_LOCALS_DICT , locals_dict, (mp_obj_dict_t *)&object_locals_dict +#else +#define OBJECT_TYPE_LOCALS_DICT +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_object, MP_QSTR_object, MP_TYPE_FLAG_NONE, object_make_new - #if MICROPY_CPYTHON_COMPAT - , locals_dict, (mp_obj_dict_t *)&object_locals_dict - #endif + OBJECT_TYPE_LOCALS_DICT ); diff --git a/py/objrange.c b/py/objrange.c index adf4b17466ad..3140504b2bb4 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -210,19 +210,27 @@ STATIC void range_attr(mp_obj_t o_in, qstr attr, mp_obj_t *dest) { } #endif +#if MICROPY_PY_BUILTINS_RANGE_BINOP +#define RANGE_TYPE_BINOP binary_op, range_binary_op, +#else +#define RANGE_TYPE_BINOP +#endif + +#if MICROPY_PY_BUILTINS_RANGE_ATTRS +#define RANGE_TYPE_ATTR attr, range_attr, +#else +#define RANGE_TYPE_ATTR +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_range, MP_QSTR_range, MP_TYPE_FLAG_NONE, range_make_new, + RANGE_TYPE_BINOP + RANGE_TYPE_ATTR print, range_print, unary_op, range_unary_op, - #if MICROPY_PY_BUILTINS_RANGE_BINOP - binary_op, range_binary_op, - #endif subscr, range_subscr, getiter, range_getiter - #if MICROPY_PY_BUILTINS_RANGE_ATTRS - , attr, range_attr - #endif ); diff --git a/py/objslice.c b/py/objslice.c index 98c03485ff39..7baca1fbe668 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -92,17 +92,21 @@ STATIC const mp_rom_map_elem_t slice_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(slice_locals_dict, slice_locals_dict_table); #endif +#if MICROPY_PY_BUILTINS_SLICE_ATTRS +#define SLICE_TYPE_ATTR_OR_LOCALS_DICT attr, slice_attr, +#elif MICROPY_PY_BUILTINS_SLICE_INDICES +#define SLICE_TYPE_ATTR_OR_LOCALS_DICT locals_dict, (mp_obj_dict_t *)&slice_locals_dict, +#else +#define SLICE_TYPE_ATTR_OR_LOCALS_DICT +#endif + MP_DEFINE_CONST_OBJ_TYPE( mp_type_slice, MP_QSTR_slice, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, + SLICE_TYPE_ATTR_OR_LOCALS_DICT print, slice_print - #if MICROPY_PY_BUILTINS_SLICE_ATTRS - , attr, slice_attr - #elif MICROPY_PY_BUILTINS_SLICE_INDICES - , locals_dict, (mp_obj_dict_t *)&slice_locals_dict - #endif ); mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { From 9dce82776db104750283b213095a7aedfb95a1d9 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 24 Jun 2022 16:27:46 +1000 Subject: [PATCH 1744/4290] all: Remove unnecessary locals_dict cast. Signed-off-by: Jim Mussared --- extmod/machine_i2c.c | 2 +- extmod/machine_signal.c | 2 +- extmod/machine_spi.c | 2 +- extmod/modbluetooth.c | 2 +- extmod/modbtree.c | 2 +- extmod/modframebuf.c | 2 +- extmod/modlwip.c | 4 ++-- extmod/moduasyncio.c | 2 +- extmod/moducryptolib.c | 2 +- extmod/moduhashlib.c | 6 +++--- extmod/modure.c | 4 ++-- extmod/moduselect.c | 2 +- extmod/modusocket.c | 2 +- extmod/modussl_axtls.c | 2 +- extmod/modussl_mbedtls.c | 2 +- extmod/modutimeq.c | 2 +- extmod/moduwebsocket.c | 2 +- extmod/moduzlib.c | 2 +- extmod/modwebrepl.c | 2 +- extmod/network_cyw43.c | 2 +- extmod/vfs_fat.c | 2 +- extmod/vfs_fat_file.c | 4 ++-- extmod/vfs_lfsx.c | 2 +- extmod/vfs_lfsx_file.c | 4 ++-- extmod/vfs_posix.c | 2 +- extmod/vfs_posix_file.c | 4 ++-- ports/cc3200/misc/mpirq.c | 2 +- ports/cc3200/mods/modnetwork.c | 2 +- ports/cc3200/mods/moduhashlib.c | 4 ++-- ports/cc3200/mods/modusocket.c | 2 +- ports/cc3200/mods/modussl.c | 2 +- ports/cc3200/mods/modwlan.c | 2 +- ports/cc3200/mods/pybadc.c | 4 ++-- ports/cc3200/mods/pybflash.c | 2 +- ports/cc3200/mods/pybi2c.c | 2 +- ports/cc3200/mods/pybpin.c | 4 ++-- ports/cc3200/mods/pybrtc.c | 2 +- ports/cc3200/mods/pybsd.c | 2 +- ports/cc3200/mods/pybspi.c | 2 +- ports/cc3200/mods/pybtimer.c | 4 ++-- ports/cc3200/mods/pybuart.c | 2 +- ports/cc3200/mods/pybwdt.c | 2 +- ports/esp32/esp32_nvs.c | 2 +- ports/esp32/esp32_partition.c | 2 +- ports/esp32/esp32_rmt.c | 2 +- ports/esp32/esp32_ulp.c | 2 +- ports/esp32/machine_adc.c | 2 +- ports/esp32/machine_adcblock.c | 2 +- ports/esp32/machine_dac.c | 2 +- ports/esp32/machine_hw_spi.c | 2 +- ports/esp32/machine_i2c.c | 2 +- ports/esp32/machine_i2s.c | 2 +- ports/esp32/machine_pin.c | 4 ++-- ports/esp32/machine_rtc.c | 2 +- ports/esp32/machine_sdcard.c | 2 +- ports/esp32/machine_timer.c | 2 +- ports/esp32/machine_touchpad.c | 2 +- ports/esp32/machine_uart.c | 2 +- ports/esp32/machine_wdt.c | 2 +- ports/esp32/modsocket.c | 2 +- ports/esp32/network_lan.c | 2 +- ports/esp32/network_ppp.c | 2 +- ports/esp32/network_wlan.c | 2 +- ports/esp8266/machine_adc.c | 2 +- ports/esp8266/machine_hspi.c | 2 +- ports/esp8266/machine_pin.c | 4 ++-- ports/esp8266/machine_rtc.c | 2 +- ports/esp8266/machine_uart.c | 2 +- ports/esp8266/machine_wdt.c | 2 +- ports/esp8266/modmachine.c | 2 +- ports/esp8266/modnetwork.c | 2 +- ports/mimxrt/machine_adc.c | 2 +- ports/mimxrt/machine_i2c.c | 2 +- ports/mimxrt/machine_i2s.c | 2 +- ports/mimxrt/machine_led.c | 2 +- ports/mimxrt/machine_pin.c | 8 ++++---- ports/mimxrt/machine_rtc.c | 2 +- ports/mimxrt/machine_sdcard.c | 2 +- ports/mimxrt/machine_spi.c | 2 +- ports/mimxrt/machine_timer.c | 2 +- ports/mimxrt/machine_uart.c | 2 +- ports/mimxrt/machine_wdt.c | 2 +- ports/mimxrt/mimxrt_flash.c | 2 +- ports/mimxrt/network_lan.c | 2 +- ports/nrf/boards/microbit/modules/microbitdisplay.c | 2 +- ports/nrf/boards/microbit/modules/microbitimage.c | 2 +- ports/nrf/modules/board/led.c | 2 +- ports/nrf/modules/machine/adc.c | 2 +- ports/nrf/modules/machine/i2c.c | 2 +- ports/nrf/modules/machine/pin.c | 4 ++-- ports/nrf/modules/machine/pwm.c | 2 +- ports/nrf/modules/machine/rtcounter.c | 2 +- ports/nrf/modules/machine/spi.c | 2 +- ports/nrf/modules/machine/temp.c | 2 +- ports/nrf/modules/machine/timer.c | 2 +- ports/nrf/modules/machine/uart.c | 2 +- ports/nrf/modules/nrf/flashbdev.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_characteristic.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_constants.c | 4 ++-- ports/nrf/modules/ubluepy/ubluepy_delegate.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_descriptor.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_scan_entry.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_scanner.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_service.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_uuid.c | 2 +- ports/nrf/modules/uos/microbitfs.c | 4 ++-- ports/nrf/pin_named_pins.c | 4 ++-- ports/pic16bit/modpybled.c | 2 +- ports/pic16bit/modpybswitch.c | 2 +- ports/renesas-ra/machine_i2c.c | 2 +- ports/rp2/machine_adc.c | 2 +- ports/rp2/machine_i2c.c | 2 +- ports/rp2/machine_i2s.c | 2 +- ports/rp2/machine_pin.c | 2 +- ports/rp2/machine_rtc.c | 2 +- ports/rp2/machine_spi.c | 2 +- ports/rp2/machine_timer.c | 2 +- ports/rp2/machine_uart.c | 2 +- ports/rp2/machine_wdt.c | 2 +- ports/rp2/rp2_flash.c | 2 +- ports/rp2/rp2_pio.c | 4 ++-- ports/samd/machine_led.c | 2 +- ports/samd/machine_pin.c | 2 +- ports/samd/samd_flash.c | 2 +- ports/stm32/accel.c | 2 +- ports/stm32/adc.c | 4 ++-- ports/stm32/dac.c | 2 +- ports/stm32/extint.c | 2 +- ports/stm32/lcd.c | 2 +- ports/stm32/led.c | 2 +- ports/stm32/machine_adc.c | 2 +- ports/stm32/machine_i2c.c | 2 +- ports/stm32/machine_i2s.c | 2 +- ports/stm32/machine_spi.c | 2 +- ports/stm32/machine_timer.c | 2 +- ports/stm32/machine_uart.c | 2 +- ports/stm32/network_lan.c | 2 +- ports/stm32/pin.c | 4 ++-- ports/stm32/pin_named_pins.c | 4 ++-- ports/stm32/pyb_can.c | 2 +- ports/stm32/pyb_i2c.c | 2 +- ports/stm32/pyb_spi.c | 2 +- ports/stm32/rtc.c | 2 +- ports/stm32/sdcard.c | 4 ++-- ports/stm32/servo.c | 2 +- ports/stm32/storage.c | 2 +- ports/stm32/timer.c | 4 ++-- ports/stm32/usb.c | 4 ++-- ports/stm32/usrsw.c | 2 +- ports/stm32/wdt.c | 2 +- ports/teensy/led.c | 2 +- ports/teensy/timer.c | 4 ++-- ports/teensy/uart.c | 2 +- ports/unix/coverage.c | 4 ++-- ports/unix/modffi.c | 6 +++--- ports/unix/modjni.c | 6 +++--- ports/unix/moduselect.c | 2 +- ports/unix/modusocket.c | 2 +- ports/zephyr/machine_i2c.c | 2 +- ports/zephyr/machine_pin.c | 2 +- ports/zephyr/machine_spi.c | 2 +- ports/zephyr/machine_uart.c | 2 +- ports/zephyr/modusocket.c | 2 +- ports/zephyr/modzsensor.c | 2 +- ports/zephyr/zephyr_storage.c | 4 ++-- py/modio.c | 2 +- py/modthread.c | 2 +- py/objarray.c | 6 +++--- py/objdeque.c | 2 +- py/objdict.c | 4 ++-- py/objgenerator.c | 2 +- py/objint.c | 2 +- py/objlist.c | 2 +- py/objobject.c | 2 +- py/objpolyiter.c | 2 +- py/objproperty.c | 2 +- py/objset.c | 4 ++-- py/objslice.c | 2 +- py/objstr.c | 4 ++-- py/objstringio.c | 4 ++-- py/objstrunicode.c | 2 +- py/objtuple.c | 2 +- shared/runtime/mpirq.c | 2 +- shared/runtime/sys_stdio_mphal.c | 4 ++-- 185 files changed, 226 insertions(+), 226 deletions(-) diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index 7e597b791029..378bf8fc914b 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -737,7 +737,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_machine_soft_i2c_make_new, print, mp_machine_soft_i2c_print, protocol, &mp_machine_soft_i2c_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); #endif // MICROPY_PY_MACHINE_SOFTI2C diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c index 818bc01c2711..f665ffaa494e 100644 --- a/extmod/machine_signal.c +++ b/extmod/machine_signal.c @@ -179,7 +179,7 @@ MP_DEFINE_CONST_OBJ_TYPE( signal_make_new, call, signal_call, protocol, &signal_pin_p, - locals_dict, (void *)&signal_locals_dict + locals_dict, &signal_locals_dict ); #endif // MICROPY_PY_MACHINE diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index 43148c9c8d46..c7fc5877b1b0 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -258,7 +258,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_machine_soft_spi_make_new, print, mp_machine_soft_spi_print, protocol, &mp_machine_soft_spi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); #endif // MICROPY_PY_MACHINE_SOFTSPI diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 2b7497e1b655..2e058fc7deb2 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -981,7 +981,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_BLE, MP_TYPE_FLAG_NONE, bluetooth_ble_make_new, - locals_dict, (void *)&bluetooth_ble_locals_dict + locals_dict, &bluetooth_ble_locals_dict ); STATIC const mp_rom_map_elem_t mp_module_bluetooth_globals_table[] = { diff --git a/extmod/modbtree.c b/extmod/modbtree.c index f115be44fec1..15cb6341637a 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -330,7 +330,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( iternext, btree_iternext, binary_op, btree_binary_op, subscr, btree_subscr, - locals_dict, (void *)&btree_locals_dict + locals_dict, &btree_locals_dict ); #endif diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 1d44312cf304..f29eab272f0e 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -835,7 +835,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, framebuf_make_new, buffer, framebuf_get_buffer, - locals_dict, (mp_obj_dict_t *)&framebuf_locals_dict + locals_dict, &framebuf_locals_dict ); #endif diff --git a/extmod/modlwip.c b/extmod/modlwip.c index f9d5b76b2c8b..2f5da36f4084 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -182,7 +182,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_slip, MP_TYPE_FLAG_NONE, lwip_slip_make_new, - locals_dict, (mp_obj_dict_t *)&lwip_slip_locals_dict + locals_dict, &lwip_slip_locals_dict ); #endif // MICROPY_PY_LWIP_SLIP @@ -1602,7 +1602,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( lwip_socket_make_new, print, lwip_socket_print, protocol, &lwip_socket_stream_p, - locals_dict, (mp_obj_dict_t *)&lwip_socket_locals_dict + locals_dict, &lwip_socket_locals_dict ); /******************************************************************************/ diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c index 500d13c5b859..546764209608 100644 --- a/extmod/moduasyncio.c +++ b/extmod/moduasyncio.c @@ -149,7 +149,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_TaskQueue, MP_TYPE_FLAG_NONE, task_queue_make_new, - locals_dict, (mp_obj_dict_t *)&task_queue_locals_dict + locals_dict, &task_queue_locals_dict ); /******************************************************************************/ diff --git a/extmod/moducryptolib.c b/extmod/moducryptolib.c index 236b7edfd7aa..e4625c21a878 100644 --- a/extmod/moducryptolib.c +++ b/extmod/moducryptolib.c @@ -353,7 +353,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_aes, MP_TYPE_FLAG_NONE, ucryptolib_aes_make_new, - locals_dict, (void *)&ucryptolib_aes_locals_dict + locals_dict, &ucryptolib_aes_locals_dict ); STATIC const mp_rom_map_elem_t mp_module_ucryptolib_globals_table[] = { diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 44625ed6da2a..9535e00b406d 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -162,7 +162,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_sha256, MP_TYPE_FLAG_NONE, uhashlib_sha256_make_new, - locals_dict, (void *)&uhashlib_sha256_locals_dict + locals_dict, &uhashlib_sha256_locals_dict ); #endif @@ -256,7 +256,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_sha1, MP_TYPE_FLAG_NONE, uhashlib_sha1_make_new, - locals_dict, (void *)&uhashlib_sha1_locals_dict + locals_dict, &uhashlib_sha1_locals_dict ); #endif @@ -350,7 +350,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_md5, MP_TYPE_FLAG_NONE, uhashlib_md5_make_new, - locals_dict, (void *)&uhashlib_md5_locals_dict + locals_dict, &uhashlib_md5_locals_dict ); #endif // MICROPY_PY_UHASHLIB_MD5 diff --git a/extmod/modure.c b/extmod/modure.c index a27c7ff9fdc5..43959924053b 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -185,7 +185,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, match_print, - locals_dict, (void *)&match_locals_dict + locals_dict, &match_locals_dict ); #endif @@ -419,7 +419,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, re_print, - locals_dict, (void *)&re_locals_dict + locals_dict, &re_locals_dict ); #endif diff --git a/extmod/moduselect.c b/extmod/moduselect.c index 1a11ee0eab50..352b15d983d8 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -343,7 +343,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_NULL_MAKE_NEW, getiter, mp_identity_getiter, iternext, poll_iternext, - locals_dict, (void *)&poll_locals_dict + locals_dict, &poll_locals_dict ); // poll() diff --git a/extmod/modusocket.c b/extmod/modusocket.c index 6008edb11c76..fc16d7e27030 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -534,7 +534,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, socket_make_new, protocol, &socket_stream_p, - locals_dict, (mp_obj_dict_t *)&socket_locals_dict, + locals_dict, &socket_locals_dict, print, socket_print ); diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c index 72eb0e214fe3..78470ea6df04 100644 --- a/extmod/modussl_axtls.c +++ b/extmod/modussl_axtls.c @@ -324,7 +324,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( getiter, NULL, iternext, NULL, protocol, &ussl_socket_stream_p, - locals_dict, (void *)&ussl_socket_locals_dict + locals_dict, &ussl_socket_locals_dict ); STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 0fab915f3f06..76ca3ac719c9 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -402,7 +402,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( getiter, NULL, iternext, NULL, protocol, &ussl_socket_stream_p, - locals_dict, (void *)&ussl_socket_locals_dict + locals_dict, &ussl_socket_locals_dict ); STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index bf4e031895fa..1a7575adc9e5 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -215,7 +215,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, utimeq_make_new, unary_op, utimeq_unary_op, - locals_dict, (void *)&utimeq_locals_dict + locals_dict, &utimeq_locals_dict ); STATIC const mp_rom_map_elem_t mp_module_utimeq_globals_table[] = { diff --git a/extmod/moduwebsocket.c b/extmod/moduwebsocket.c index 2895978f3d5d..c6be50d0e15a 100644 --- a/extmod/moduwebsocket.c +++ b/extmod/moduwebsocket.c @@ -296,7 +296,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, websocket_make_new, protocol, &websocket_stream_p, - locals_dict, (void *)&websocket_locals_dict + locals_dict, &websocket_locals_dict ); STATIC const mp_rom_map_elem_t uwebsocket_module_globals_table[] = { diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 93c939129eab..533168d0b054 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -146,7 +146,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, decompio_make_new, protocol, &decompio_stream_p, - locals_dict, (void *)&decompio_locals_dict + locals_dict, &decompio_locals_dict ); #endif diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index cb893b38dcbe..fc5ca35ea033 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -348,7 +348,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, webrepl_make_new, protocol, &webrepl_stream_p, - locals_dict, (mp_obj_dict_t *)&webrepl_locals_dict + locals_dict, &webrepl_locals_dict ); STATIC const mp_rom_map_elem_t webrepl_module_globals_table[] = { diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index fbd0a750b8e6..329ba53ef51a 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -502,7 +502,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, network_cyw43_make_new, print, network_cyw43_print, - locals_dict, (mp_obj_dict_t *)&network_cyw43_locals_dict + locals_dict, &network_cyw43_locals_dict ); #endif // MICROPY_PY_NETWORK_CYW43 diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 4a2ef883c26c..7c18a5163374 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -437,7 +437,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, fat_vfs_make_new, protocol, &fat_vfs_proto, - locals_dict, (mp_obj_dict_t *)&fat_vfs_locals_dict + locals_dict, &fat_vfs_locals_dict ); #endif // MICROPY_VFS_FAT diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 0d4af09b452c..00980459db8b 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -185,7 +185,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &vfs_fat_fileio_stream_p, - locals_dict, (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict + locals_dict, &vfs_fat_rawfile_locals_dict ); STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { @@ -204,7 +204,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &vfs_fat_textio_stream_p, - locals_dict, (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict + locals_dict, &vfs_fat_rawfile_locals_dict ); // Factory function for I/O stream classes diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index 3f8d262a4858..33e2ef551987 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -514,7 +514,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_VFS_LFSx(make_new), protocol, &MP_VFS_LFSx(proto), - locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(locals_dict) + locals_dict, &MP_VFS_LFSx(locals_dict) ); #undef VFS_LFSx_QSTR diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c index ba90cc608443..fda1b97b2a13 100644 --- a/extmod/vfs_lfsx_file.c +++ b/extmod/vfs_lfsx_file.c @@ -229,7 +229,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &MP_VFS_LFSx(fileio_stream_p), - locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict) + locals_dict, &MP_VFS_LFSx(file_locals_dict) ); STATIC const mp_stream_p_t MP_VFS_LFSx(textio_stream_p) = { @@ -248,5 +248,5 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &MP_VFS_LFSx(textio_stream_p), - locals_dict, (mp_obj_dict_t *)&MP_VFS_LFSx(file_locals_dict) + locals_dict, &MP_VFS_LFSx(file_locals_dict) ); diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 79126c007068..b02827e8647c 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -404,7 +404,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, vfs_posix_make_new, protocol, &vfs_posix_proto, - locals_dict, (mp_obj_dict_t *)&vfs_posix_locals_dict + locals_dict, &vfs_posix_locals_dict ); #endif // MICROPY_VFS_POSIX diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 85aef1617b80..f0b5436fe1ea 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -258,7 +258,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &vfs_posix_fileio_stream_p, - locals_dict, (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict + locals_dict, &vfs_posix_rawfile_locals_dict ); STATIC const mp_stream_p_t vfs_posix_textio_stream_p = { @@ -277,7 +277,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &vfs_posix_textio_stream_p, - locals_dict, (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict + locals_dict, &vfs_posix_rawfile_locals_dict ); const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, STDIN_FILENO}; diff --git a/ports/cc3200/misc/mpirq.c b/ports/cc3200/misc/mpirq.c index e9cae92a327e..9c3c2f719672 100644 --- a/ports/cc3200/misc/mpirq.c +++ b/ports/cc3200/misc/mpirq.c @@ -196,7 +196,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, call, mp_irq_call, - locals_dict, (mp_obj_t)&mp_irq_locals_dict + locals_dict, &mp_irq_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_list_t mp_irq_obj_list); diff --git a/ports/cc3200/mods/modnetwork.c b/ports/cc3200/mods/modnetwork.c index a74189300775..0a72a1ab3256 100644 --- a/ports/cc3200/mods/modnetwork.c +++ b/ports/cc3200/mods/modnetwork.c @@ -176,6 +176,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Server, MP_TYPE_FLAG_NONE, network_server_make_new, - locals_dict, (mp_obj_t)&network_server_locals_dict + locals_dict, &network_server_locals_dict ); #endif diff --git a/ports/cc3200/mods/moduhashlib.c b/ports/cc3200/mods/moduhashlib.c index 5437cfb264e6..4a759d8ea5c5 100644 --- a/ports/cc3200/mods/moduhashlib.c +++ b/ports/cc3200/mods/moduhashlib.c @@ -182,7 +182,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_sha1, MP_TYPE_FLAG_NONE, hash_make_new, - locals_dict, (mp_obj_t)&hash_locals_dict + locals_dict, &hash_locals_dict ); STATIC MP_DEFINE_CONST_OBJ_TYPE( @@ -190,7 +190,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_sha256, MP_TYPE_FLAG_NONE, hash_make_new, - locals_dict, (mp_obj_t)&hash_locals_dict + locals_dict, &hash_locals_dict ); STATIC const mp_rom_map_elem_t mp_module_hashlib_globals_table[] = { diff --git a/ports/cc3200/mods/modusocket.c b/ports/cc3200/mods/modusocket.c index 11199de14628..55d504a70972 100644 --- a/ports/cc3200/mods/modusocket.c +++ b/ports/cc3200/mods/modusocket.c @@ -765,7 +765,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, socket_make_new, protocol, &socket_stream_p, - locals_dict, (mp_obj_t)&socket_locals_dict + locals_dict, &socket_locals_dict ); /******************************************************************************/ diff --git a/ports/cc3200/mods/modussl.c b/ports/cc3200/mods/modussl.c index d0909e7c2909..abc9917c8134 100644 --- a/ports/cc3200/mods/modussl.c +++ b/ports/cc3200/mods/modussl.c @@ -68,7 +68,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( getiter, NULL, iternext, NULL, protocol, &socket_stream_p, - locals_dict, (mp_obj_t)&socket_locals_dict + locals_dict, &socket_locals_dict ); STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c index 24f5d196d2a3..1c99f075e902 100644 --- a/ports/cc3200/mods/modwlan.c +++ b/ports/cc3200/mods/modwlan.c @@ -1290,7 +1290,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, wlan_make_new, - locals_dict, (mp_obj_t)&wlan_locals_dict + locals_dict, &wlan_locals_dict ); const mod_network_nic_type_t mod_network_nic_type_wlan = { diff --git a/ports/cc3200/mods/pybadc.c b/ports/cc3200/mods/pybadc.c index a114eeda169a..a14f9aced261 100644 --- a/ports/cc3200/mods/pybadc.c +++ b/ports/cc3200/mods/pybadc.c @@ -239,7 +239,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, adc_make_new, print, adc_print, - locals_dict, (mp_obj_t)&adc_locals_dict + locals_dict, &adc_locals_dict ); STATIC void adc_channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -308,5 +308,5 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_NULL_MAKE_NEW, print, adc_channel_print, call, adc_channel_call, - locals_dict, (mp_obj_t)&adc_channel_locals_dict + locals_dict, &adc_channel_locals_dict ); diff --git a/ports/cc3200/mods/pybflash.c b/ports/cc3200/mods/pybflash.c index 4cfafb7abf64..a6d1e23fbf02 100644 --- a/ports/cc3200/mods/pybflash.c +++ b/ports/cc3200/mods/pybflash.c @@ -89,7 +89,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Flash, MP_TYPE_FLAG_NONE, pyb_flash_make_new, - locals_dict, (mp_obj_t)&pyb_flash_locals_dict + locals_dict, &pyb_flash_locals_dict ); void pyb_flash_init_vfs(fs_user_mount_t *vfs) { diff --git a/ports/cc3200/mods/pybi2c.c b/ports/cc3200/mods/pybi2c.c index 91a0b9b9f9a9..de92cc7c32b3 100644 --- a/ports/cc3200/mods/pybi2c.c +++ b/ports/cc3200/mods/pybi2c.c @@ -527,5 +527,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_i2c_make_new, print, pyb_i2c_print, - locals_dict, (mp_obj_t)&pyb_i2c_locals_dict + locals_dict, &pyb_i2c_locals_dict ); diff --git a/ports/cc3200/mods/pybpin.c b/ports/cc3200/mods/pybpin.c index 948cda70d4ab..374d09ddfbd7 100644 --- a/ports/cc3200/mods/pybpin.c +++ b/ports/cc3200/mods/pybpin.c @@ -938,7 +938,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_make_new, print, pin_print, call, pin_call, - locals_dict, (mp_obj_t)&pin_locals_dict + locals_dict, &pin_locals_dict ); STATIC const mp_irq_methods_t pin_irq_methods = { @@ -959,6 +959,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pin_named_pins_obj_print, - locals_dict, (mp_obj_t)&pin_board_pins_locals_dict + locals_dict, &pin_board_pins_locals_dict ); diff --git a/ports/cc3200/mods/pybrtc.c b/ports/cc3200/mods/pybrtc.c index 2761cb3c64f5..ed7a20fecbf6 100644 --- a/ports/cc3200/mods/pybrtc.c +++ b/ports/cc3200/mods/pybrtc.c @@ -474,7 +474,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_RTC, MP_TYPE_FLAG_NONE, pyb_rtc_make_new, - locals_dict, (mp_obj_t)&pyb_rtc_locals_dict + locals_dict, &pyb_rtc_locals_dict ); STATIC const mp_irq_methods_t pyb_rtc_irq_methods = { diff --git a/ports/cc3200/mods/pybsd.c b/ports/cc3200/mods/pybsd.c index d8834e36f744..968a6a87ec4d 100644 --- a/ports/cc3200/mods/pybsd.c +++ b/ports/cc3200/mods/pybsd.c @@ -217,5 +217,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_SD, MP_TYPE_FLAG_NONE, pyb_sd_make_new, - locals_dict, (mp_obj_t)&pyb_sd_locals_dict + locals_dict, &pyb_sd_locals_dict ); diff --git a/ports/cc3200/mods/pybspi.c b/ports/cc3200/mods/pybspi.c index 50d897633e55..7d83fabfde4d 100644 --- a/ports/cc3200/mods/pybspi.c +++ b/ports/cc3200/mods/pybspi.c @@ -383,5 +383,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_spi_make_new, print, pyb_spi_print, - locals_dict, (mp_obj_t)&pyb_spi_locals_dict + locals_dict, &pyb_spi_locals_dict ); diff --git a/ports/cc3200/mods/pybtimer.c b/ports/cc3200/mods/pybtimer.c index a8bc7821e0ce..14e1deb083ed 100644 --- a/ports/cc3200/mods/pybtimer.c +++ b/ports/cc3200/mods/pybtimer.c @@ -465,7 +465,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_timer_make_new, print, pyb_timer_print, - locals_dict, (mp_obj_t)&pyb_timer_locals_dict + locals_dict, &pyb_timer_locals_dict ); STATIC const mp_irq_methods_t pyb_timer_channel_irq_methods = { @@ -728,7 +728,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pyb_timer_channel_print, - locals_dict, (mp_obj_t)&pyb_timer_channel_locals_dict + locals_dict, &pyb_timer_channel_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_list_t pyb_timer_channel_obj_list); diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c index 059101f4f205..e7896c4ca5cf 100644 --- a/ports/cc3200/mods/pybuart.c +++ b/ports/cc3200/mods/pybuart.c @@ -694,7 +694,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_t)&pyb_uart_locals_dict + locals_dict, &pyb_uart_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _pyb_uart_obj_t *pyb_uart_objs[2]); diff --git a/ports/cc3200/mods/pybwdt.c b/ports/cc3200/mods/pybwdt.c index cde1abe59d89..3c1f9eb195f1 100644 --- a/ports/cc3200/mods/pybwdt.c +++ b/ports/cc3200/mods/pybwdt.c @@ -155,6 +155,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WDT, MP_TYPE_FLAG_NONE, pyb_wdt_make_new, - locals_dict, (mp_obj_t)&pybwdt_locals_dict + locals_dict, &pybwdt_locals_dict ); diff --git a/ports/esp32/esp32_nvs.c b/ports/esp32/esp32_nvs.c index 1f96ad129d11..d935a13d6fe5 100644 --- a/ports/esp32/esp32_nvs.c +++ b/ports/esp32/esp32_nvs.c @@ -147,5 +147,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, esp32_nvs_make_new, print, esp32_nvs_print, - locals_dict, (mp_obj_dict_t *)&esp32_nvs_locals_dict + locals_dict, &esp32_nvs_locals_dict ); diff --git a/ports/esp32/esp32_partition.c b/ports/esp32/esp32_partition.c index 2e42e7a81903..6ce1e90b4c70 100644 --- a/ports/esp32/esp32_partition.c +++ b/ports/esp32/esp32_partition.c @@ -290,5 +290,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, esp32_partition_make_new, print, esp32_partition_print, - locals_dict, (mp_obj_dict_t *)&esp32_partition_locals_dict + locals_dict, &esp32_partition_locals_dict ); diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index 36f33df3f5d4..ee09ac520061 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -378,5 +378,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, esp32_rmt_make_new, print, esp32_rmt_print, - locals_dict, (mp_obj_dict_t *)&esp32_rmt_locals_dict + locals_dict, &esp32_rmt_locals_dict ); diff --git a/ports/esp32/esp32_ulp.c b/ports/esp32/esp32_ulp.c index 5eb0e5591e7e..5030f980675e 100644 --- a/ports/esp32/esp32_ulp.c +++ b/ports/esp32/esp32_ulp.c @@ -96,7 +96,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_ULP, MP_TYPE_FLAG_NONE, esp32_ulp_make_new, - locals_dict, (mp_obj_t)&esp32_ulp_locals_dict + locals_dict, &esp32_ulp_locals_dict ); #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c index 5cc2d8038491..c4e04159c0b9 100644 --- a/ports/esp32/machine_adc.c +++ b/ports/esp32/machine_adc.c @@ -262,5 +262,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, madc_make_new, print, madc_print, - locals_dict, (mp_obj_t)&madc_locals_dict + locals_dict, &madc_locals_dict ); diff --git a/ports/esp32/machine_adcblock.c b/ports/esp32/machine_adcblock.c index 770839e93e1b..ae3244f7fdb4 100644 --- a/ports/esp32/machine_adcblock.c +++ b/ports/esp32/machine_adcblock.c @@ -200,5 +200,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, madcblock_make_new, print, madcblock_print, - locals_dict, (mp_obj_dict_t *)&madcblock_locals_dict + locals_dict, &madcblock_locals_dict ); diff --git a/ports/esp32/machine_dac.c b/ports/esp32/machine_dac.c index c9b9c14e01e7..fbe33b0344a4 100644 --- a/ports/esp32/machine_dac.c +++ b/ports/esp32/machine_dac.c @@ -110,7 +110,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, mdac_make_new, print, mdac_print, - locals_dict, (mp_obj_t)&mdac_locals_dict + locals_dict, &mdac_locals_dict ); #endif // MICROPY_PY_MACHINE_DAC diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 71583ef60e90..51ea31ac1b3d 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -552,5 +552,5 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hw_spi_make_new, print, machine_hw_spi_print, protocol, &machine_hw_spi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index 9e5be606dbf9..895dc3a39874 100644 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -199,5 +199,5 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hw_i2c_make_new, print, machine_hw_i2c_print, protocol, &machine_hw_i2c_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index d30fb5d836e7..b853f418ada3 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -838,7 +838,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + locals_dict, &machine_i2s_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_MAX]); diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index 1a1a3a0f8d17..fd523a38edac 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -537,7 +537,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, machine_pin_print, call, machine_pin_call, protocol, &pin_pin_p, - locals_dict, (mp_obj_t)&machine_pin_locals_dict + locals_dict, &machine_pin_locals_dict ); /******************************************************************************/ @@ -730,7 +730,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, call, machine_pin_irq_call, - locals_dict, (mp_obj_dict_t *)&machine_pin_irq_locals_dict + locals_dict, &machine_pin_irq_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_t machine_pin_irq_handler[40]); diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index 6634bf5b03b9..19b83703fd43 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -178,5 +178,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_RTC, MP_TYPE_FLAG_NONE, machine_rtc_make_new, - locals_dict, (mp_obj_t)&machine_rtc_locals_dict + locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/esp32/machine_sdcard.c b/ports/esp32/machine_sdcard.c index 2d5663d476e8..0b6159157d98 100644 --- a/ports/esp32/machine_sdcard.c +++ b/ports/esp32/machine_sdcard.c @@ -404,7 +404,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_SDCard, MP_TYPE_FLAG_NONE, machine_sdcard_make_new, - locals_dict, (mp_obj_dict_t *)&machine_sdcard_locals_dict + locals_dict, &machine_sdcard_locals_dict ); #endif // MICROPY_HW_ENABLE_SDCARD diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 3b1295095593..2fd40fa2afc1 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -283,7 +283,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_timer_make_new, print, machine_timer_print, - locals_dict, (mp_obj_t)&machine_timer_locals_dict + locals_dict, &machine_timer_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _machine_timer_obj_t *machine_timer_obj_head); diff --git a/ports/esp32/machine_touchpad.c b/ports/esp32/machine_touchpad.c index c5e3483b74a0..deba818dd1c8 100644 --- a/ports/esp32/machine_touchpad.c +++ b/ports/esp32/machine_touchpad.c @@ -139,7 +139,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_TouchPad, MP_TYPE_FLAG_NONE, mtp_make_new, - locals_dict, (mp_obj_t)&mtp_locals_dict + locals_dict, &mtp_locals_dict ); #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 9df16ae41983..6e091b8838a2 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -539,5 +539,5 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + locals_dict, &machine_uart_locals_dict ); diff --git a/ports/esp32/machine_wdt.c b/ports/esp32/machine_wdt.c index c2898c7fe158..bda9c6975e15 100644 --- a/ports/esp32/machine_wdt.c +++ b/ports/esp32/machine_wdt.c @@ -88,5 +88,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WDT, MP_TYPE_FLAG_NONE, machine_wdt_make_new, - locals_dict, (mp_obj_t)&machine_wdt_locals_dict + locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/esp32/modsocket.c b/ports/esp32/modsocket.c index a2dcb3946cea..e7e6f3c26e28 100644 --- a/ports/esp32/modsocket.c +++ b/ports/esp32/modsocket.c @@ -791,7 +791,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, socket_make_new, protocol, &socket_stream_p, - locals_dict, (mp_obj_t)&socket_locals_dict + locals_dict, &socket_locals_dict ); STATIC mp_obj_t esp_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c index fc50e13c48ed..3c5aea5fb8a4 100644 --- a/ports/esp32/network_lan.c +++ b/ports/esp32/network_lan.c @@ -307,7 +307,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_LAN, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&lan_if_locals_dict + locals_dict, &lan_if_locals_dict ); #endif diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c index d6368d9f2038..df07515c7d41 100644 --- a/ports/esp32/network_ppp.c +++ b/ports/esp32/network_ppp.c @@ -283,5 +283,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_PPP, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&ppp_if_locals_dict + locals_dict, &ppp_if_locals_dict ); diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index 6ca5f9a9bafe..0f1f5de14937 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -620,7 +620,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&wlan_if_locals_dict + locals_dict, &wlan_if_locals_dict ); STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; diff --git a/ports/esp8266/machine_adc.c b/ports/esp8266/machine_adc.c index bface7f7e155..b1e7b3843527 100644 --- a/ports/esp8266/machine_adc.c +++ b/ports/esp8266/machine_adc.c @@ -95,5 +95,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_adc_make_new, print, machine_adc_print, - locals_dict, (mp_obj_dict_t *)&machine_adc_locals_dict + locals_dict, &machine_adc_locals_dict ); diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c index c0d4a677e3ef..3f449a1de91e 100644 --- a/ports/esp8266/machine_hspi.c +++ b/ports/esp8266/machine_hspi.c @@ -182,7 +182,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hspi_make_new, print, machine_hspi_print, protocol, &machine_hspi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); #endif // MICROPY_PY_MACHINE_SPI diff --git a/ports/esp8266/machine_pin.c b/ports/esp8266/machine_pin.c index 8b759766cd6f..32ffca873dfa 100644 --- a/ports/esp8266/machine_pin.c +++ b/ports/esp8266/machine_pin.c @@ -458,7 +458,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, pyb_pin_print, call, pyb_pin_call, protocol, &pin_pin_p, - locals_dict, (mp_obj_dict_t *)&pyb_pin_locals_dict + locals_dict, &pyb_pin_locals_dict ); /******************************************************************************/ @@ -516,7 +516,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, call, pin_irq_call, - locals_dict, (mp_obj_dict_t *)&pin_irq_locals_dict + locals_dict, &pin_irq_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_irq_handler[16]); diff --git a/ports/esp8266/machine_rtc.c b/ports/esp8266/machine_rtc.c index 4235b325ef7a..cc6b79a031be 100644 --- a/ports/esp8266/machine_rtc.c +++ b/ports/esp8266/machine_rtc.c @@ -267,5 +267,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_RTC, MP_TYPE_FLAG_NONE, pyb_rtc_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_rtc_locals_dict + locals_dict, &pyb_rtc_locals_dict ); diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index 82f5189388ca..c737f854c34f 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -352,7 +352,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t *)&pyb_uart_locals_dict + locals_dict, &pyb_uart_locals_dict ); MP_REGISTER_ROOT_POINTER(byte * uart0_rxbuf); diff --git a/ports/esp8266/machine_wdt.c b/ports/esp8266/machine_wdt.c index d8c32ddd1a1f..26d5c9fa76f1 100644 --- a/ports/esp8266/machine_wdt.c +++ b/ports/esp8266/machine_wdt.c @@ -74,5 +74,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WDT, MP_TYPE_FLAG_NONE, machine_wdt_make_new, - locals_dict, (mp_obj_dict_t *)&machine_wdt_locals_dict + locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index 2bb2c7bd7695..eb41e30f66b1 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -343,7 +343,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, esp_timer_make_new, print, esp_timer_print, - locals_dict, (mp_obj_dict_t *)&esp_timer_locals_dict + locals_dict, &esp_timer_locals_dict ); // this bit is unused in the Xtensa PS register diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index f78bf5da52eb..45a5a2be5412 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -515,7 +515,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&wlan_if_locals_dict + locals_dict, &wlan_if_locals_dict ); STATIC mp_obj_t esp_phy_mode(size_t n_args, const mp_obj_t *args) { diff --git a/ports/mimxrt/machine_adc.c b/ports/mimxrt/machine_adc.c index cbac6b5734d2..7a19d1225ee7 100644 --- a/ports/mimxrt/machine_adc.c +++ b/ports/mimxrt/machine_adc.c @@ -123,7 +123,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, adc_obj_make_new, print, adc_obj_print, - locals_dict, (mp_obj_dict_t *)&adc_locals_dict + locals_dict, &adc_locals_dict ); void machine_adc_init(void) { diff --git a/ports/mimxrt/machine_i2c.c b/ports/mimxrt/machine_i2c.c index b8b6b7bc6334..62dfd8204c08 100644 --- a/ports/mimxrt/machine_i2c.c +++ b/ports/mimxrt/machine_i2c.c @@ -204,5 +204,5 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2c_make_new, print, machine_i2c_print, protocol, &machine_i2c_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); diff --git a/ports/mimxrt/machine_i2s.c b/ports/mimxrt/machine_i2s.c index 68bf3a820f59..13380b4ee6b0 100644 --- a/ports/mimxrt/machine_i2s.c +++ b/ports/mimxrt/machine_i2s.c @@ -1222,7 +1222,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + locals_dict, &machine_i2s_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_I2S_NUM]); diff --git a/ports/mimxrt/machine_led.c b/ports/mimxrt/machine_led.c index d766c8f3237a..9fd98ef71043 100644 --- a/ports/mimxrt/machine_led.c +++ b/ports/mimxrt/machine_led.c @@ -86,7 +86,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, led_obj_make_new, print, led_obj_print, - locals_dict, (mp_obj_dict_t *)&led_locals_dict + locals_dict, &led_locals_dict ); #endif diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 7ec66d0eac95..261e3e414803 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -63,7 +63,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_cpu, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_t)&machine_pin_cpu_pins_locals_dict + locals_dict, &machine_pin_cpu_pins_locals_dict ); MP_DEFINE_CONST_OBJ_TYPE( @@ -71,7 +71,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_board, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_t)&machine_pin_board_pins_locals_dict + locals_dict, &machine_pin_board_pins_locals_dict ); STATIC const mp_irq_methods_t machine_pin_irq_methods; @@ -428,7 +428,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, machine_pin_obj_print, call, machine_pin_obj_call, protocol, &machine_pin_obj_protocol, - locals_dict, (mp_obj_dict_t *)&machine_pin_locals_dict + locals_dict, &machine_pin_locals_dict ); // FIXME: Create actual pin_af type!!! @@ -438,7 +438,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, mp_pin_make_new, print, machine_pin_obj_print, - locals_dict, (mp_obj_dict_t *)&machine_pin_locals_dict + locals_dict, &machine_pin_locals_dict ); STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { diff --git a/ports/mimxrt/machine_rtc.c b/ports/mimxrt/machine_rtc.c index 5211027bdf80..2e1a09dedbe6 100644 --- a/ports/mimxrt/machine_rtc.c +++ b/ports/mimxrt/machine_rtc.c @@ -171,5 +171,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_RTC, MP_TYPE_FLAG_NONE, machine_rtc_make_new, - locals_dict, (mp_obj_t)&machine_rtc_locals_dict + locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/mimxrt/machine_sdcard.c b/ports/mimxrt/machine_sdcard.c index b7bdceef47ed..22f7e7c232a8 100644 --- a/ports/mimxrt/machine_sdcard.c +++ b/ports/mimxrt/machine_sdcard.c @@ -213,7 +213,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_SDCard, MP_TYPE_FLAG_NONE, sdcard_obj_make_new, - locals_dict, (mp_obj_dict_t *)&sdcard_locals_dict + locals_dict, &sdcard_locals_dict ); void machine_sdcard_init0(void) { diff --git a/ports/mimxrt/machine_spi.c b/ports/mimxrt/machine_spi.c index ff3cf4fb2551..93b75e931eb4 100644 --- a/ports/mimxrt/machine_spi.c +++ b/ports/mimxrt/machine_spi.c @@ -258,5 +258,5 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_spi_make_new, print, machine_spi_print, protocol, &machine_spi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); diff --git a/ports/mimxrt/machine_timer.c b/ports/mimxrt/machine_timer.c index 9612388486e3..a6b61982f7ec 100644 --- a/ports/mimxrt/machine_timer.c +++ b/ports/mimxrt/machine_timer.c @@ -217,7 +217,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_timer_make_new, print, machine_timer_print, - locals_dict, (mp_obj_dict_t *)&machine_timer_locals_dict + locals_dict, &machine_timer_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _machine_timer_obj_t *timer_table[MICROPY_HW_PIT_NUM_CHANNELS]); diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index 4bb518eab25e..9d4873274a8f 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -478,5 +478,5 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + locals_dict, &machine_uart_locals_dict ); diff --git a/ports/mimxrt/machine_wdt.c b/ports/mimxrt/machine_wdt.c index cde80f085b99..e0b5c74b5426 100644 --- a/ports/mimxrt/machine_wdt.c +++ b/ports/mimxrt/machine_wdt.c @@ -104,5 +104,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WDT, MP_TYPE_FLAG_NONE, machine_wdt_make_new, - locals_dict, (mp_obj_dict_t *)&machine_wdt_locals_dict + locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index 1a7d6cca8da0..bd03c853d597 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -220,5 +220,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Flash, MP_TYPE_FLAG_NONE, mimxrt_flash_make_new, - locals_dict, (mp_obj_dict_t *)&mimxrt_flash_locals_dict + locals_dict, &mimxrt_flash_locals_dict ); diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index 08c3c9e729f5..e15894294b68 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -226,7 +226,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, network_lan_make_new, print, network_lan_print, - locals_dict, (mp_obj_dict_t *)&network_lan_locals_dict + locals_dict, &network_lan_locals_dict ); diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c index 084cb09524da..5cb25ea1ced4 100644 --- a/ports/nrf/boards/microbit/modules/microbitdisplay.c +++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c @@ -547,7 +547,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_MicroBitDisplay, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t*)µbit_display_locals_dict + locals_dict, µbit_display_locals_dict ); microbit_display_obj_t microbit_display_obj = { diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c index 95b17bb6d339..4870b6738f6c 100644 --- a/ports/nrf/boards/microbit/modules/microbitimage.c +++ b/ports/nrf/boards/microbit/modules/microbitimage.c @@ -685,7 +685,7 @@ MP_DEFINE_CONST_OBJ_TYPE( microbit_image_make_new, print, microbit_image_print, binary_op, image_binary_op, - locals_dict, (mp_obj_dict_t*)µbit_image_locals_dict + locals_dict, µbit_image_locals_dict ); typedef struct _scrolling_string_t { diff --git a/ports/nrf/modules/board/led.c b/ports/nrf/modules/board/led.c index 5eef8f046402..577c2b62843f 100644 --- a/ports/nrf/modules/board/led.c +++ b/ports/nrf/modules/board/led.c @@ -200,7 +200,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, led_obj_make_new, print, led_obj_print, - locals_dict, (mp_obj_dict_t*)&led_locals_dict + locals_dict, &led_locals_dict ); #else diff --git a/ports/nrf/modules/machine/adc.c b/ports/nrf/modules/machine/adc.c index 5814dcaa392c..84db8d259f2a 100644 --- a/ports/nrf/modules/machine/adc.c +++ b/ports/nrf/modules/machine/adc.c @@ -299,7 +299,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_ADC, MP_TYPE_FLAG_NONE, machine_adc_make_new, - locals_dict, (mp_obj_dict_t*)&machine_adc_locals_dict, + locals_dict, &machine_adc_locals_dict, print, machine_adc_print ); diff --git a/ports/nrf/modules/machine/i2c.c b/ports/nrf/modules/machine/i2c.c index 8468684428a7..7cb55d078821 100644 --- a/ports/nrf/modules/machine/i2c.c +++ b/ports/nrf/modules/machine/i2c.c @@ -168,7 +168,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_i2c_make_new, print, machine_hard_i2c_print, protocol, &machine_hard_i2c_p, - locals_dict, (mp_obj_dict_t*)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); #endif // MICROPY_PY_MACHINE_I2C diff --git a/ports/nrf/modules/machine/pin.c b/ports/nrf/modules/machine/pin.c index 835f6cf2bd32..4f283e5dba14 100644 --- a/ports/nrf/modules/machine/pin.c +++ b/ports/nrf/modules/machine/pin.c @@ -603,7 +603,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_make_new, print, pin_print, call, pin_call, - locals_dict, (mp_obj_dict_t*)&pin_locals_dict + locals_dict, &pin_locals_dict ); /// \moduleref machine @@ -678,7 +678,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pin_af_obj_print, - locals_dict, (mp_obj_dict_t*)&pin_af_locals_dict + locals_dict, &pin_af_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_class_mapper); diff --git a/ports/nrf/modules/machine/pwm.c b/ports/nrf/modules/machine/pwm.c index d0ac0e9450c3..54e643ec55ff 100644 --- a/ports/nrf/modules/machine/pwm.c +++ b/ports/nrf/modules/machine/pwm.c @@ -345,7 +345,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_pwm_make_new, print, machine_pwm_print, - locals_dict, (mp_obj_dict_t*)&machine_pwm_locals_dict + locals_dict, &machine_pwm_locals_dict ); #endif // MICROPY_PY_MACHINE_HW_PWM diff --git a/ports/nrf/modules/machine/rtcounter.c b/ports/nrf/modules/machine/rtcounter.c index 3c48c4bb1fb2..cafe08b6c684 100644 --- a/ports/nrf/modules/machine/rtcounter.c +++ b/ports/nrf/modules/machine/rtcounter.c @@ -268,7 +268,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_rtc_make_new, print, rtc_print, - locals_dict, (mp_obj_dict_t*)&machine_rtc_locals_dict + locals_dict, &machine_rtc_locals_dict ); #endif // MICROPY_PY_MACHINE_RTCOUNTER diff --git a/ports/nrf/modules/machine/spi.c b/ports/nrf/modules/machine/spi.c index 22b0ff56e59a..d5613a464324 100644 --- a/ports/nrf/modules/machine/spi.c +++ b/ports/nrf/modules/machine/spi.c @@ -434,7 +434,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_spi_make_new, print, machine_hard_spi_print, protocol, &machine_hard_spi_p, - locals_dict, (mp_obj_dict_t*)&machine_spi_locals_dict + locals_dict, &machine_spi_locals_dict ); #endif // MICROPY_PY_MACHINE_HW_SPI diff --git a/ports/nrf/modules/machine/temp.c b/ports/nrf/modules/machine/temp.c index 1e21f11253fd..00d6329b6498 100644 --- a/ports/nrf/modules/machine/temp.c +++ b/ports/nrf/modules/machine/temp.c @@ -117,7 +117,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Temp, MP_TYPE_FLAG_NONE, machine_temp_make_new, - locals_dict, (mp_obj_dict_t*)&machine_temp_locals_dict, + locals_dict, &machine_temp_locals_dict, print, machine_temp_print ); diff --git a/ports/nrf/modules/machine/timer.c b/ports/nrf/modules/machine/timer.c index 3724881aa813..f7f6101726a6 100644 --- a/ports/nrf/modules/machine/timer.c +++ b/ports/nrf/modules/machine/timer.c @@ -240,7 +240,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_timer_make_new, print, timer_print, - locals_dict, (mp_obj_dict_t*)&machine_timer_locals_dict + locals_dict, &machine_timer_locals_dict ); #endif // MICROPY_PY_MACHINE_TIMER diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index 5c9ba83ab662..fc0bd682b4b7 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -379,7 +379,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t*)&machine_hard_uart_locals_dict + locals_dict, &machine_hard_uart_locals_dict ); #endif // MICROPY_PY_MACHINE_UART diff --git a/ports/nrf/modules/nrf/flashbdev.c b/ports/nrf/modules/nrf/flashbdev.c index b67e86d0d0df..84a3dd2520b4 100644 --- a/ports/nrf/modules/nrf/flashbdev.c +++ b/ports/nrf/modules/nrf/flashbdev.c @@ -189,7 +189,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, nrf_flashbdev_make_new, print, nrf_flashbdev_print, - locals_dict, (mp_obj_dict_t *)&nrf_flashbdev_locals_dict + locals_dict, &nrf_flashbdev_locals_dict ); void flashbdev_init(void) { diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c index 5544ac6aefed..2be7dab9d3f7 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c +++ b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c @@ -215,7 +215,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_characteristic_make_new, print, ubluepy_characteristic_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_characteristic_locals_dict + locals_dict, &ubluepy_characteristic_locals_dict ); #endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c index e4637c8cbce2..c6c399924573 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ b/ports/nrf/modules/ubluepy/ubluepy_constants.c @@ -74,7 +74,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_ad_types, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t*)&ubluepy_constants_ad_types_locals_dict + locals_dict, &ubluepy_constants_ad_types_locals_dict ); STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { @@ -97,7 +97,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_constants, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t*)&ubluepy_constants_locals_dict + locals_dict, &ubluepy_constants_locals_dict ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_delegate.c b/ports/nrf/modules/ubluepy/ubluepy_delegate.c index 71648767e61d..dd19f70be445 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_delegate.c +++ b/ports/nrf/modules/ubluepy/ubluepy_delegate.c @@ -83,7 +83,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_delegate_make_new, print, ubluepy_delegate_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_delegate_locals_dict + locals_dict, &ubluepy_delegate_locals_dict ); #endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c index 07035460ae4d..d942d9822306 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c +++ b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c @@ -76,7 +76,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_descriptor_make_new, print, ubluepy_descriptor_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_descriptor_locals_dict + locals_dict, &ubluepy_descriptor_locals_dict ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 9c346a885b2c..9f638b45d735 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -488,7 +488,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_peripheral_make_new, print, ubluepy_peripheral_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_peripheral_locals_dict + locals_dict, &ubluepy_peripheral_locals_dict ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c index 64a81d215d37..5c74e2e92caf 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c @@ -142,7 +142,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, ubluepy_scan_entry_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_scan_entry_locals_dict + locals_dict, &ubluepy_scan_entry_locals_dict ); #endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_scanner.c b/ports/nrf/modules/ubluepy/ubluepy_scanner.c index c47044cf0c37..b56ec349d043 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scanner.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scanner.c @@ -120,7 +120,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_scanner_make_new, print, ubluepy_scanner_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_scanner_locals_dict + locals_dict, &ubluepy_scanner_locals_dict ); #endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c index 9d0d6e5b95f8..2bec6befd689 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ b/ports/nrf/modules/ubluepy/ubluepy_service.c @@ -177,7 +177,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_service_make_new, print, ubluepy_service_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_service_locals_dict + locals_dict, &ubluepy_service_locals_dict ); #endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c index 0414a2a2867f..0fd6e75e5b62 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c +++ b/ports/nrf/modules/ubluepy/ubluepy_uuid.c @@ -166,7 +166,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ubluepy_uuid_make_new, print, ubluepy_uuid_print, - locals_dict, (mp_obj_dict_t*)&ubluepy_uuid_locals_dict + locals_dict, &ubluepy_uuid_locals_dict ); #endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/uos/microbitfs.c b/ports/nrf/modules/uos/microbitfs.c index 63ac8c93213f..d1b320111607 100644 --- a/ports/nrf/modules/uos/microbitfs.c +++ b/ports/nrf/modules/uos/microbitfs.c @@ -632,7 +632,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, protocol, &textio_stream_p, - locals_dict, (mp_obj_dict_t*)&uos_mbfs_file_locals_dict + locals_dict, &uos_mbfs_file_locals_dict ); @@ -647,7 +647,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, protocol, &fileio_stream_p, - locals_dict, (mp_obj_dict_t*)&uos_mbfs_file_locals_dict + locals_dict, &uos_mbfs_file_locals_dict ); // From micro:bit fileobj.c diff --git a/ports/nrf/pin_named_pins.c b/ports/nrf/pin_named_pins.c index 87fed746e64e..84ec89f44aa6 100644 --- a/ports/nrf/pin_named_pins.c +++ b/ports/nrf/pin_named_pins.c @@ -42,7 +42,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pin_named_pins_obj_print, - locals_dict, (mp_obj_t)&pin_cpu_pins_locals_dict + locals_dict, &pin_cpu_pins_locals_dict ); MP_DEFINE_CONST_OBJ_TYPE( @@ -51,7 +51,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pin_named_pins_obj_print, - locals_dict, (mp_obj_t)&pin_board_pins_locals_dict + locals_dict, &pin_board_pins_locals_dict ); const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { diff --git a/ports/pic16bit/modpybled.c b/ports/pic16bit/modpybled.c index fd4e8cce9c92..2e5c2dcca3b1 100644 --- a/ports/pic16bit/modpybled.c +++ b/ports/pic16bit/modpybled.c @@ -90,5 +90,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_led_make_new, print, pyb_led_print, - locals_dict, (mp_obj_t)&pyb_led_locals_dict + locals_dict, &pyb_led_locals_dict ); diff --git a/ports/pic16bit/modpybswitch.c b/ports/pic16bit/modpybswitch.c index e1096b1daaad..f27cfb9b093a 100644 --- a/ports/pic16bit/modpybswitch.c +++ b/ports/pic16bit/modpybswitch.c @@ -78,5 +78,5 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_switch_make_new, print, pyb_switch_print, call, pyb_switch_call, - locals_dict, (mp_obj_t)&pyb_switch_locals_dict + locals_dict, &pyb_switch_locals_dict ); diff --git a/ports/renesas-ra/machine_i2c.c b/ports/renesas-ra/machine_i2c.c index eaca5ff4a85e..563ea8787e52 100644 --- a/ports/renesas-ra/machine_i2c.c +++ b/ports/renesas-ra/machine_i2c.c @@ -161,7 +161,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_I2C, MP_TYPE_FLAG_NONE, machine_i2c_make_new, - locals_dict, (void *)&mp_machine_i2c_locals_dict, + locals_dict, &mp_machine_i2c_locals_dict, print, machine_i2c_print, protocol, &machine_i2c_p ); diff --git a/ports/rp2/machine_adc.c b/ports/rp2/machine_adc.c index 549f8d5ecdc5..85562d5c0758 100644 --- a/ports/rp2/machine_adc.c +++ b/ports/rp2/machine_adc.c @@ -119,5 +119,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_adc_make_new, print, machine_adc_print, - locals_dict, (mp_obj_dict_t *)&machine_adc_locals_dict + locals_dict, &machine_adc_locals_dict ); diff --git a/ports/rp2/machine_i2c.c b/ports/rp2/machine_i2c.c index 91d8bb59b76c..5ab93f63581d 100644 --- a/ports/rp2/machine_i2c.c +++ b/ports/rp2/machine_i2c.c @@ -183,5 +183,5 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2c_make_new, print, machine_i2c_print, protocol, &machine_i2c_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c index 8446a59781bb..9d70a476f30b 100644 --- a/ports/rp2/machine_i2s.c +++ b/ports/rp2/machine_i2s.c @@ -1146,7 +1146,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + locals_dict, &machine_i2s_locals_dict ); MP_REGISTER_ROOT_POINTER(void *machine_i2s_obj[2]); diff --git a/ports/rp2/machine_pin.c b/ports/rp2/machine_pin.c index 38670f09abea..8ccfbca3ab42 100644 --- a/ports/rp2/machine_pin.c +++ b/ports/rp2/machine_pin.c @@ -649,7 +649,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, machine_pin_print, call, machine_pin_call, protocol, &pin_pin_p, - locals_dict, (mp_obj_t)&machine_pin_locals_dict + locals_dict, &machine_pin_locals_dict ); STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { diff --git a/ports/rp2/machine_rtc.c b/ports/rp2/machine_rtc.c index 73bdaee6c760..6b2c9ac71b65 100644 --- a/ports/rp2/machine_rtc.c +++ b/ports/rp2/machine_rtc.c @@ -120,5 +120,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_RTC, MP_TYPE_FLAG_NONE, machine_rtc_make_new, - locals_dict, (mp_obj_t)&machine_rtc_locals_dict + locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/rp2/machine_spi.c b/ports/rp2/machine_spi.c index f3ac8d7cf811..08c79712cf22 100644 --- a/ports/rp2/machine_spi.c +++ b/ports/rp2/machine_spi.c @@ -297,7 +297,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_spi_make_new, print, machine_spi_print, protocol, &machine_spi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t o) { diff --git a/ports/rp2/machine_timer.c b/ports/rp2/machine_timer.c index d3b60155294f..66f632329c72 100644 --- a/ports/rp2/machine_timer.c +++ b/ports/rp2/machine_timer.c @@ -162,5 +162,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_timer_make_new, print, machine_timer_print, - locals_dict, (mp_obj_dict_t *)&machine_timer_locals_dict + locals_dict, &machine_timer_locals_dict ); diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index df6228058be7..bb8bf51be651 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -588,7 +588,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + locals_dict, &machine_uart_locals_dict ); MP_REGISTER_ROOT_POINTER(void *rp2_uart_rx_buffer[2]); diff --git a/ports/rp2/machine_wdt.c b/ports/rp2/machine_wdt.c index e8c433306922..c224298d136b 100644 --- a/ports/rp2/machine_wdt.c +++ b/ports/rp2/machine_wdt.c @@ -82,5 +82,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WDT, MP_TYPE_FLAG_NONE, machine_wdt_make_new, - locals_dict, (mp_obj_dict_t *)&machine_wdt_locals_dict + locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c index 37a3412db5cf..df49c881c4a4 100644 --- a/ports/rp2/rp2_flash.c +++ b/ports/rp2/rp2_flash.c @@ -190,5 +190,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Flash, MP_TYPE_FLAG_NONE, rp2_flash_make_new, - locals_dict, (mp_obj_dict_t *)&rp2_flash_locals_dict + locals_dict, &rp2_flash_locals_dict ); diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index 9a195bdd8a64..cfba9cce5ae0 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -382,7 +382,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, rp2_pio_make_new, print, rp2_pio_print, - locals_dict, (mp_obj_dict_t *)&rp2_pio_locals_dict + locals_dict, &rp2_pio_locals_dict ); STATIC mp_uint_t rp2_pio_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { @@ -813,7 +813,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, rp2_state_machine_make_new, print, rp2_state_machine_print, - locals_dict, (mp_obj_dict_t *)&rp2_state_machine_locals_dict + locals_dict, &rp2_state_machine_locals_dict ); STATIC mp_uint_t rp2_state_machine_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index 76aae8ffc576..7a9b2299ae3b 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -169,5 +169,5 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_led_make_new, print, machine_led_print, call, machine_led_call, - locals_dict, (mp_obj_t)&machine_led_locals_dict + locals_dict, &machine_led_locals_dict ); diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index d47982e0e1c6..75e1a2356c4d 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -295,7 +295,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, machine_pin_print, call, machine_pin_call, protocol, &pin_pin_p, - locals_dict, (mp_obj_t)&machine_pin_locals_dict + locals_dict, &machine_pin_locals_dict ); /* diff --git a/ports/samd/samd_flash.c b/ports/samd/samd_flash.c index 6c74b59a263a..9d64768cfa02 100644 --- a/ports/samd/samd_flash.c +++ b/ports/samd/samd_flash.c @@ -186,5 +186,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Flash, MP_TYPE_FLAG_NONE, samd_flash_make_new, - locals_dict, (mp_obj_dict_t *)&samd_flash_locals_dict + locals_dict, &samd_flash_locals_dict ); diff --git a/ports/stm32/accel.c b/ports/stm32/accel.c index 276ce37d3ad4..05fd1898bc11 100644 --- a/ports/stm32/accel.c +++ b/ports/stm32/accel.c @@ -286,7 +286,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Accel, MP_TYPE_FLAG_NONE, pyb_accel_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_accel_locals_dict + locals_dict, &pyb_accel_locals_dict ); #endif // MICROPY_HW_HAS_MMA7660 || MICROPY_HW_HAS_KXTJ3 diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index 7e627d088f74..e0759439d1ec 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -709,7 +709,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, adc_make_new, print, adc_print, - locals_dict, (mp_obj_dict_t *)&adc_locals_dict + locals_dict, &adc_locals_dict ); /******************************************************************************/ @@ -917,7 +917,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_ADCAll, MP_TYPE_FLAG_NONE, adc_all_make_new, - locals_dict, (mp_obj_dict_t *)&adc_all_locals_dict + locals_dict, &adc_all_locals_dict ); #endif // MICROPY_HW_ENABLE_ADC diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index da50b30fef13..ac8d76090ee0 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -508,7 +508,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_dac_make_new, print, pyb_dac_print, - locals_dict, (mp_obj_dict_t *)&pyb_dac_locals_dict + locals_dict, &pyb_dac_locals_dict ); #endif // MICROPY_HW_ENABLE_DAC diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index 4d2dc5d23be9..0f28610cc3e7 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -665,7 +665,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, extint_make_new, print, extint_obj_print, - locals_dict, (mp_obj_dict_t *)&extint_locals_dict + locals_dict, &extint_locals_dict ); void extint_init0(void) { diff --git a/ports/stm32/lcd.c b/ports/stm32/lcd.c index a951ea766844..5017a68fe548 100644 --- a/ports/stm32/lcd.c +++ b/ports/stm32/lcd.c @@ -530,7 +530,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_LCD, MP_TYPE_FLAG_NONE, pyb_lcd_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_lcd_locals_dict + locals_dict, &pyb_lcd_locals_dict ); #endif // MICROPY_HW_HAS_LCD diff --git a/ports/stm32/led.c b/ports/stm32/led.c index 6745ef60b8d1..6e3229ab3218 100644 --- a/ports/stm32/led.c +++ b/ports/stm32/led.c @@ -387,7 +387,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, led_obj_make_new, print, led_obj_print, - locals_dict, (mp_obj_dict_t *)&led_locals_dict + locals_dict, &led_locals_dict ); #else diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index 682bae3a6d13..3659073d06bf 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -498,7 +498,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_adc_make_new, print, machine_adc_print, - locals_dict, (mp_obj_dict_t *)&machine_adc_locals_dict + locals_dict, &machine_adc_locals_dict ); #endif diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 89970f234d19..7927daac1bdd 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -243,7 +243,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_i2c_make_new, print, machine_hard_i2c_print, protocol, &machine_hard_i2c_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); #endif // MICROPY_HW_ENABLE_HW_I2C diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c index 7dc6439f25c0..93a465d07ca8 100644 --- a/ports/stm32/machine_i2s.c +++ b/ports/stm32/machine_i2s.c @@ -1123,7 +1123,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_i2s_locals_dict + locals_dict, &machine_i2s_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_MAX_I2S]); diff --git a/ports/stm32/machine_spi.c b/ports/stm32/machine_spi.c index 87561c2b7b1d..d64ff2af8f76 100644 --- a/ports/stm32/machine_spi.c +++ b/ports/stm32/machine_spi.c @@ -142,5 +142,5 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_spi_make_new, print, machine_hard_spi_print, protocol, &machine_hard_spi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c index bd9dbe609849..2e0120ea8191 100644 --- a/ports/stm32/machine_timer.c +++ b/ports/stm32/machine_timer.c @@ -142,5 +142,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, machine_timer_make_new, print, machine_timer_print, - locals_dict, (mp_obj_dict_t *)&machine_timer_locals_dict + locals_dict, &machine_timer_locals_dict ); diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index 4d25a0274cdd..5851d8cf352d 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -669,5 +669,5 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t *)&pyb_uart_locals_dict + locals_dict, &pyb_uart_locals_dict ); diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c index f9c7d80b78e9..25a955508853 100644 --- a/ports/stm32/network_lan.c +++ b/ports/stm32/network_lan.c @@ -164,7 +164,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, network_lan_make_new, print, network_lan_print, - locals_dict, (mp_obj_dict_t *)&network_lan_locals_dict + locals_dict, &network_lan_locals_dict ); #endif // defined(MICROPY_HW_ETH_MDC) diff --git a/ports/stm32/pin.c b/ports/stm32/pin.c index 992046cd17e5..3c3cde026568 100644 --- a/ports/stm32/pin.c +++ b/ports/stm32/pin.c @@ -600,7 +600,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, pin_print, call, pin_call, protocol, &pin_pin_p, - locals_dict, (mp_obj_dict_t *)&pin_locals_dict + locals_dict, &pin_locals_dict ); /// \moduleref pyb @@ -676,7 +676,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pin_af_obj_print, - locals_dict, (mp_obj_dict_t *)&pin_af_locals_dict + locals_dict, &pin_af_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_t pin_class_mapper); diff --git a/ports/stm32/pin_named_pins.c b/ports/stm32/pin_named_pins.c index 620888878c4a..1a35ec57875f 100644 --- a/ports/stm32/pin_named_pins.c +++ b/ports/stm32/pin_named_pins.c @@ -36,7 +36,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_cpu, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&pin_cpu_pins_locals_dict + locals_dict, &pin_cpu_pins_locals_dict ); MP_DEFINE_CONST_OBJ_TYPE( @@ -44,7 +44,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_board, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&pin_board_pins_locals_dict + locals_dict, &pin_board_pins_locals_dict ); const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { diff --git a/ports/stm32/pyb_can.c b/ports/stm32/pyb_can.c index 6fdfd2c8549e..a07fc921649c 100644 --- a/ports/stm32/pyb_can.c +++ b/ports/stm32/pyb_can.c @@ -1079,7 +1079,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_can_make_new, print, pyb_can_print, protocol, &can_stream_p, - locals_dict, (mp_obj_dict_t *)&pyb_can_locals_dict + locals_dict, &pyb_can_locals_dict ); MP_REGISTER_ROOT_POINTER(struct _pyb_can_obj_t *pyb_can_obj_all[MICROPY_HW_MAX_CAN]); diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index ee6983a143fd..9071d92944ee 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -1110,7 +1110,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_i2c_make_new, print, pyb_i2c_print, - locals_dict, (mp_obj_dict_t *)&pyb_i2c_locals_dict + locals_dict, &pyb_i2c_locals_dict ); #endif // MICROPY_PY_PYB_LEGACY && MICROPY_HW_ENABLE_HW_I2C diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c index b1425272feee..a225bd84e753 100644 --- a/ports/stm32/pyb_spi.c +++ b/ports/stm32/pyb_spi.c @@ -357,5 +357,5 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_spi_make_new, print, pyb_spi_print, protocol, &pyb_spi_p, - locals_dict, (mp_obj_dict_t *)&pyb_spi_locals_dict + locals_dict, &pyb_spi_locals_dict ); diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c index c7698db1430a..f501ec23b1b3 100644 --- a/ports/stm32/rtc.c +++ b/ports/stm32/rtc.c @@ -842,5 +842,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_RTC, MP_TYPE_FLAG_NONE, pyb_rtc_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_rtc_locals_dict + locals_dict, &pyb_rtc_locals_dict ); diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index b9cc051e7f13..cbf1ade5c5b7 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -877,7 +877,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_SDCard, MP_TYPE_FLAG_NONE, pyb_sdcard_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_sdcard_locals_dict + locals_dict, &pyb_sdcard_locals_dict ); #endif @@ -887,7 +887,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_MMCard, MP_TYPE_FLAG_NONE, pyb_mmcard_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_sdcard_locals_dict + locals_dict, &pyb_sdcard_locals_dict ); #endif diff --git a/ports/stm32/servo.c b/ports/stm32/servo.c index d552f5e6b5d3..1b0ca0a88224 100644 --- a/ports/stm32/servo.c +++ b/ports/stm32/servo.c @@ -342,7 +342,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_servo_make_new, print, pyb_servo_print, - locals_dict, (mp_obj_dict_t *)&pyb_servo_locals_dict + locals_dict, &pyb_servo_locals_dict ); #endif // MICROPY_HW_ENABLE_SERVO diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c index 92f705949338..a0154408dd5f 100644 --- a/ports/stm32/storage.c +++ b/ports/stm32/storage.c @@ -459,7 +459,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_flash_make_new, print, pyb_flash_print, - locals_dict, (mp_obj_dict_t *)&pyb_flash_locals_dict + locals_dict, &pyb_flash_locals_dict ); void pyb_flash_init_vfs(fs_user_mount_t *vfs) { diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index abf4c1f3fc4c..91c88df1b372 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -1477,7 +1477,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_timer_make_new, print, pyb_timer_print, - locals_dict, (mp_obj_dict_t *)&pyb_timer_locals_dict + locals_dict, &pyb_timer_locals_dict ); /// \moduleref pyb @@ -1617,7 +1617,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pyb_timer_channel_print, - locals_dict, (mp_obj_dict_t *)&pyb_timer_channel_locals_dict + locals_dict, &pyb_timer_channel_locals_dict ); STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_obj_t callback) { diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 7c36765c28c1..df755fe984c3 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -945,7 +945,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &pyb_usb_vcp_stream_p, - locals_dict, (mp_obj_dict_t *)&pyb_usb_vcp_locals_dict + locals_dict, &pyb_usb_vcp_locals_dict ); /******************************************************************************/ @@ -1084,7 +1084,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_usb_hid_make_new, protocol, &pyb_usb_hid_stream_p, - locals_dict, (mp_obj_dict_t *)&pyb_usb_hid_locals_dict + locals_dict, &pyb_usb_hid_locals_dict ); #endif // MICROPY_HW_USB_HID diff --git a/ports/stm32/usrsw.c b/ports/stm32/usrsw.c index 137f4dabfa5c..7d406c0ecd71 100644 --- a/ports/stm32/usrsw.c +++ b/ports/stm32/usrsw.c @@ -141,7 +141,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_switch_make_new, print, pyb_switch_print, call, pyb_switch_call, - locals_dict, (mp_obj_dict_t *)&pyb_switch_locals_dict + locals_dict, &pyb_switch_locals_dict ); MP_REGISTER_ROOT_POINTER(mp_obj_t pyb_switch_callback); diff --git a/ports/stm32/wdt.c b/ports/stm32/wdt.c index e3b8e2e0ae22..09780ea9d3cc 100644 --- a/ports/stm32/wdt.c +++ b/ports/stm32/wdt.c @@ -107,5 +107,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_WDT, MP_TYPE_FLAG_NONE, pyb_wdt_make_new, - locals_dict, (mp_obj_dict_t *)&pyb_wdt_locals_dict + locals_dict, &pyb_wdt_locals_dict ); diff --git a/ports/teensy/led.c b/ports/teensy/led.c index ca548431feca..dd4c65da39e1 100644 --- a/ports/teensy/led.c +++ b/ports/teensy/led.c @@ -140,5 +140,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, led_obj_make_new, print, led_obj_print, - locals_dict, (mp_obj_t)&led_locals_dict + locals_dict, &led_locals_dict ); diff --git a/ports/teensy/timer.c b/ports/teensy/timer.c index 4df24743356c..a0f490d925fb 100644 --- a/ports/teensy/timer.c +++ b/ports/teensy/timer.c @@ -752,7 +752,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_timer_make_new, print, pyb_timer_print, - locals_dict, (mp_obj_t)&pyb_timer_locals_dict + locals_dict, &pyb_timer_locals_dict ); /// \moduleref pyb @@ -896,7 +896,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, pyb_timer_channel_print, - locals_dict, (mp_obj_t)&pyb_timer_channel_locals_dict + locals_dict, &pyb_timer_channel_locals_dict ); STATIC bool ftm_handle_irq_callback(pyb_timer_obj_t *self, mp_uint_t channel, mp_obj_t callback) { diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c index 8957d9270946..db5b8e2f4433 100644 --- a/ports/teensy/uart.c +++ b/ports/teensy/uart.c @@ -489,5 +489,5 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, pyb_uart_make_new, print, pyb_uart_print, - locals_dict, (mp_obj_t)&pyb_uart_locals_dict + locals_dict, &pyb_uart_locals_dict ); diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index b4567417a22a..7b4c0c0bf48e 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -112,7 +112,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, protocol, &fileio_stream_p, - locals_dict, (mp_obj_dict_t *)&rawfile_locals_dict + locals_dict, &rawfile_locals_dict ); // stream read returns non-blocking error @@ -142,7 +142,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, protocol, &textio_stream_p2, - locals_dict, (mp_obj_dict_t *)&rawfile_locals_dict2 + locals_dict, &rawfile_locals_dict2 ); // str/bytes objects without a valid hash diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 98f0a1aa0ff6..98fd8936b1aa 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -427,7 +427,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, ffimod_make_new, print, ffimod_print, - locals_dict, (mp_obj_dict_t *)&ffimod_locals_dict + locals_dict, &ffimod_locals_dict ); // FFI function @@ -565,7 +565,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, fficallback_print, - locals_dict, (mp_obj_dict_t *)&fficallback_locals_dict + locals_dict, &fficallback_locals_dict ); // FFI variable @@ -603,7 +603,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, print, ffivar_print, - locals_dict, (mp_obj_dict_t *)&ffivar_locals_dict + locals_dict, &ffivar_locals_dict ); // Generic opaque storage object (unused) diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 72f95b645b25..02368e453716 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -182,7 +182,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( print, jclass_print, attr, jclass_attr, call, jclass_call, - locals_dict, (mp_obj_dict_t *)&jclass_locals_dict + locals_dict, &jclass_locals_dict ); STATIC mp_obj_t new_jclass(jclass jc) { @@ -332,7 +332,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( attr, jobject_attr, subscr, jobject_subscr, getiter, subscr_getiter, - // .locals_dict = (mp_obj_dict_t*)&jobject_locals_dict, + // .locals_dict = &jobject_locals_dict, ); STATIC mp_obj_t new_jobject(jobject jo) { @@ -579,7 +579,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( print, jmethod_print, call, jmethod_call, // .attr = jobject_attr, - // .locals_dict = (mp_obj_dict_t*)&jobject_locals_dict, + // .locals_dict = &jobject_locals_dict, ); #ifdef __ANDROID__ diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index d8a8d1d8c38b..baed88761c46 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -318,7 +318,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_NULL_MAKE_NEW, getiter, mp_identity_getiter, iternext, poll_iternext, - locals_dict, (void *)&poll_locals_dict + locals_dict, &poll_locals_dict ); STATIC mp_obj_t select_poll(size_t n_args, const mp_obj_t *args) { diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 7e4476cbd0ad..21260f0b2ada 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -525,7 +525,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, NULL, iternext, NULL, protocol, &usocket_stream_p, - locals_dict, (mp_obj_dict_t *)&usocket_locals_dict + locals_dict, &usocket_locals_dict ); #define BINADDR_MAX_LEN sizeof(struct in6_addr) diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c index 60a1924d803d..a844eceb50c1 100644 --- a/ports/zephyr/machine_i2c.c +++ b/ports/zephyr/machine_i2c.c @@ -133,7 +133,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_i2c_make_new, print, machine_hard_i2c_print, protocol, &machine_hard_i2c_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_i2c_locals_dict + locals_dict, &mp_machine_i2c_locals_dict ); #endif // MICROPY_PY_MACHINE_I2C diff --git a/ports/zephyr/machine_pin.c b/ports/zephyr/machine_pin.c index 48303edd8167..3114ac36fd00 100644 --- a/ports/zephyr/machine_pin.c +++ b/ports/zephyr/machine_pin.c @@ -293,7 +293,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, machine_pin_print, call, machine_pin_call, protocol, &machine_pin_pin_p, - locals_dict, (mp_obj_t)&machine_pin_locals_dict + locals_dict, &machine_pin_locals_dict ); STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { diff --git a/ports/zephyr/machine_spi.c b/ports/zephyr/machine_spi.c index 6d9bf896b06d..d990ed9c150f 100644 --- a/ports/zephyr/machine_spi.c +++ b/ports/zephyr/machine_spi.c @@ -204,7 +204,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_spi_make_new, print, machine_hard_spi_print, protocol, &machine_hard_spi_p, - locals_dict, (mp_obj_dict_t *)&mp_machine_spi_locals_dict + locals_dict, &mp_machine_spi_locals_dict ); #endif // MICROPY_PY_MACHINE_SPI diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c index 3f5df7465791..9580d3790781 100644 --- a/ports/zephyr/machine_uart.c +++ b/ports/zephyr/machine_uart.c @@ -163,5 +163,5 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, - locals_dict, (mp_obj_dict_t *)&machine_uart_locals_dict + locals_dict, &machine_uart_locals_dict ); diff --git a/ports/zephyr/modusocket.c b/ports/zephyr/modusocket.c index a7bef74ca6de..77f839fdd510 100644 --- a/ports/zephyr/modusocket.c +++ b/ports/zephyr/modusocket.c @@ -360,7 +360,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( socket_make_new, print, socket_print, protocol, &socket_stream_p, - locals_dict, (mp_obj_t)&socket_locals_dict + locals_dict, &socket_locals_dict ); // diff --git a/ports/zephyr/modzsensor.c b/ports/zephyr/modzsensor.c index 7c0b0193d326..beb4d6ad7903 100644 --- a/ports/zephyr/modzsensor.c +++ b/ports/zephyr/modzsensor.c @@ -110,7 +110,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Sensor, MP_TYPE_FLAG_NONE, sensor_make_new, - locals_dict, (void *)&sensor_locals_dict + locals_dict, &sensor_locals_dict ); STATIC const mp_rom_map_elem_t mp_module_zsensor_globals_table[] = { diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c index ded7caa65763..6ab8271d3476 100644 --- a/ports/zephyr/zephyr_storage.c +++ b/ports/zephyr/zephyr_storage.c @@ -134,7 +134,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, zephyr_disk_access_make_new, print, zephyr_disk_access_print, - locals_dict, (mp_obj_dict_t *)&zephyr_disk_access_locals_dict + locals_dict, &zephyr_disk_access_locals_dict ); #endif // CONFIG_DISK_ACCESS @@ -256,6 +256,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, zephyr_flash_area_make_new, print, zephyr_flash_area_print, - locals_dict, (mp_obj_dict_t *)&zephyr_flash_area_locals_dict + locals_dict, &zephyr_flash_area_locals_dict ); #endif // CONFIG_FLASH_MAP diff --git a/py/modio.c b/py/modio.c index 093cb1f7e78d..a1e04e4cac54 100644 --- a/py/modio.c +++ b/py/modio.c @@ -198,7 +198,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, bufwriter_make_new, protocol, &bufwriter_stream_p, - locals_dict, (mp_obj_dict_t *)&bufwriter_locals_dict + locals_dict, &bufwriter_locals_dict ); #endif // MICROPY_PY_IO_BUFFEREDWRITER diff --git a/py/modthread.c b/py/modthread.c index 0a154474252d..3116fe6bd9db 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -121,7 +121,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_lock, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, - locals_dict, (mp_obj_dict_t *)&thread_lock_locals_dict + locals_dict, &thread_lock_locals_dict ); /****************************************************************/ diff --git a/py/objarray.c b/py/objarray.c index 8d0fe7f58503..1cb163c4b97a 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -582,7 +582,7 @@ MP_DEFINE_CONST_OBJ_TYPE( binary_op, array_binary_op, subscr, array_subscr, buffer, array_get_buffer, - locals_dict, (mp_obj_dict_t *)&mp_obj_array_locals_dict + locals_dict, &mp_obj_array_locals_dict ); #endif @@ -598,7 +598,7 @@ MP_DEFINE_CONST_OBJ_TYPE( binary_op, array_binary_op, subscr, array_subscr, buffer, array_get_buffer, - locals_dict, (mp_obj_dict_t *)&mp_obj_bytearray_locals_dict + locals_dict, &mp_obj_bytearray_locals_dict ); #endif @@ -610,7 +610,7 @@ MP_DEFINE_CONST_OBJ_TYPE( #endif #if MICROPY_PY_BUILTINS_BYTES_HEX -#define MEMORYVIEW_TYPE_LOCALS_DICT locals_dict, (mp_obj_dict_t *)&mp_obj_memoryview_locals_dict, +#define MEMORYVIEW_TYPE_LOCALS_DICT locals_dict, &mp_obj_memoryview_locals_dict, #else #define MEMORYVIEW_TYPE_LOCALS_DICT #endif diff --git a/py/objdeque.c b/py/objdeque.c index 22770317ab31..1a8f76ca110b 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -161,7 +161,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, deque_make_new, unary_op, deque_unary_op, - locals_dict, (mp_obj_dict_t *)&deque_locals_dict + locals_dict, &deque_locals_dict ); #endif // MICROPY_PY_COLLECTIONS_DEQUE diff --git a/py/objdict.c b/py/objdict.c index 6e217d5c9a71..c65b14caad6c 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -599,7 +599,7 @@ MP_DEFINE_CONST_OBJ_TYPE( binary_op, dict_binary_op, subscr, dict_subscr, getiter, dict_getiter, - locals_dict, (mp_obj_dict_t *)&dict_locals_dict + locals_dict, &dict_locals_dict ); #if MICROPY_PY_COLLECTIONS_ORDEREDDICT @@ -614,7 +614,7 @@ MP_DEFINE_CONST_OBJ_TYPE( subscr, dict_subscr, getiter, dict_getiter, parent, &mp_type_dict, - locals_dict, (mp_obj_dict_t *)&dict_locals_dict + locals_dict, &dict_locals_dict ); #endif diff --git a/py/objgenerator.c b/py/objgenerator.c index 299f25e7bb63..a960c237002f 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -376,5 +376,5 @@ MP_DEFINE_CONST_OBJ_TYPE( unary_op, mp_generic_unary_op, getiter, mp_identity_getiter, iternext, gen_instance_iternext, - locals_dict, (mp_obj_dict_t *)&gen_instance_locals_dict + locals_dict, &gen_instance_locals_dict ); diff --git a/py/objint.c b/py/objint.c index d7a3f9eb9d18..f06bc441f15d 100644 --- a/py/objint.c +++ b/py/objint.c @@ -465,5 +465,5 @@ MP_DEFINE_CONST_OBJ_TYPE( print, mp_obj_int_print, unary_op, mp_obj_int_unary_op, binary_op, mp_obj_int_binary_op, - locals_dict, (mp_obj_dict_t *)&int_locals_dict + locals_dict, &int_locals_dict ); diff --git a/py/objlist.c b/py/objlist.c index 8c7921b9891b..5f9e99cc79b2 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -462,7 +462,7 @@ MP_DEFINE_CONST_OBJ_TYPE( binary_op, list_binary_op, subscr, list_subscr, getiter, list_getiter, - locals_dict, (mp_obj_dict_t *)&list_locals_dict + locals_dict, &list_locals_dict ); diff --git a/py/objobject.c b/py/objobject.c index 868a85b32ab0..ffad61070727 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -112,7 +112,7 @@ STATIC MP_DEFINE_CONST_DICT(object_locals_dict, object_locals_dict_table); #endif #if MICROPY_CPYTHON_COMPAT -#define OBJECT_TYPE_LOCALS_DICT , locals_dict, (mp_obj_dict_t *)&object_locals_dict +#define OBJECT_TYPE_LOCALS_DICT , locals_dict, &object_locals_dict #else #define OBJECT_TYPE_LOCALS_DICT #endif diff --git a/py/objpolyiter.c b/py/objpolyiter.c index 326153182bca..5bc397f6ec3b 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -85,6 +85,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_NULL_MAKE_NEW, getiter, mp_identity_getiter, iternext, polymorph_it_iternext, - locals_dict, (mp_obj_dict_t *)&mp_obj_polymorph_iter_locals_dict + locals_dict, &mp_obj_polymorph_iter_locals_dict ); #endif diff --git a/py/objproperty.c b/py/objproperty.c index 42c357f33050..ce3b572591d2 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -95,7 +95,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_property, MP_TYPE_FLAG_NONE, property_make_new, - locals_dict, (mp_obj_dict_t *)&property_locals_dict + locals_dict, &property_locals_dict ); const mp_obj_t *mp_obj_property_get(mp_obj_t self_in) { diff --git a/py/objset.c b/py/objset.c index 8fc744a14047..6f21bf15dfb5 100644 --- a/py/objset.c +++ b/py/objset.c @@ -548,7 +548,7 @@ MP_DEFINE_CONST_OBJ_TYPE( unary_op, set_unary_op, binary_op, set_binary_op, getiter, set_getiter, - locals_dict, (mp_obj_dict_t *)&set_locals_dict + locals_dict, &set_locals_dict ); #if MICROPY_PY_BUILTINS_FROZENSET @@ -574,7 +574,7 @@ MP_DEFINE_CONST_OBJ_TYPE( unary_op, set_unary_op, binary_op, set_binary_op, getiter, set_getiter, - locals_dict, (mp_obj_dict_t *)&frozenset_locals_dict + locals_dict, &frozenset_locals_dict ); #endif diff --git a/py/objslice.c b/py/objslice.c index 7baca1fbe668..d1dbb24586d9 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -95,7 +95,7 @@ STATIC MP_DEFINE_CONST_DICT(slice_locals_dict, slice_locals_dict_table); #if MICROPY_PY_BUILTINS_SLICE_ATTRS #define SLICE_TYPE_ATTR_OR_LOCALS_DICT attr, slice_attr, #elif MICROPY_PY_BUILTINS_SLICE_INDICES -#define SLICE_TYPE_ATTR_OR_LOCALS_DICT locals_dict, (mp_obj_dict_t *)&slice_locals_dict, +#define SLICE_TYPE_ATTR_OR_LOCALS_DICT locals_dict, &slice_locals_dict, #else #define SLICE_TYPE_ATTR_OR_LOCALS_DICT #endif diff --git a/py/objstr.c b/py/objstr.c index 77ca269d423b..d425055559f8 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2153,7 +2153,7 @@ MP_DEFINE_CONST_OBJ_TYPE( subscr, bytes_subscr, getiter, mp_obj_new_str_iterator, buffer, mp_obj_str_get_buffer, - locals_dict, (mp_obj_dict_t *)&mp_obj_str_locals_dict + locals_dict, &mp_obj_str_locals_dict ); #endif // !MICROPY_PY_BUILTINS_STR_UNICODE @@ -2168,7 +2168,7 @@ MP_DEFINE_CONST_OBJ_TYPE( subscr, bytes_subscr, getiter, mp_obj_new_bytes_iterator, buffer, mp_obj_str_get_buffer, - locals_dict, (mp_obj_dict_t *)&mp_obj_bytes_locals_dict + locals_dict, &mp_obj_bytes_locals_dict ); // The zero-length bytes object, with data that includes a null-terminating byte diff --git a/py/objstringio.c b/py/objstringio.c index d781ccc789d2..77547f88cf6c 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -253,7 +253,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &stringio_stream_p, - locals_dict, (mp_obj_dict_t *)&stringio_locals_dict + locals_dict, &stringio_locals_dict ); #if MICROPY_PY_IO_BYTESIO @@ -272,7 +272,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &bytesio_stream_p, - locals_dict, (mp_obj_dict_t *)&stringio_locals_dict + locals_dict, &stringio_locals_dict ); #endif diff --git a/py/objstrunicode.c b/py/objstrunicode.c index afef1498e98e..15c59e4e9572 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -240,7 +240,7 @@ MP_DEFINE_CONST_OBJ_TYPE( subscr, str_subscr, getiter, mp_obj_new_str_iterator, buffer, mp_obj_str_get_buffer, - locals_dict, (mp_obj_dict_t *)&mp_obj_str_locals_dict + locals_dict, &mp_obj_str_locals_dict ); /******************************************************************************/ diff --git a/py/objtuple.c b/py/objtuple.c index b2ea6e380eb1..a684b13e6f25 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -234,7 +234,7 @@ MP_DEFINE_CONST_OBJ_TYPE( binary_op, mp_obj_tuple_binary_op, subscr, mp_obj_tuple_subscr, getiter, mp_obj_tuple_getiter, - locals_dict, (mp_obj_dict_t *)&tuple_locals_dict + locals_dict, &tuple_locals_dict ); // the zero-length tuple diff --git a/shared/runtime/mpirq.c b/shared/runtime/mpirq.c index 763da6e0e444..889fa7a9a82e 100644 --- a/shared/runtime/mpirq.c +++ b/shared/runtime/mpirq.c @@ -131,7 +131,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, call, mp_irq_call, - locals_dict, (mp_obj_dict_t *)&mp_irq_locals_dict + locals_dict, &mp_irq_locals_dict ); #endif // MICROPY_ENABLE_SCHEDULER diff --git a/shared/runtime/sys_stdio_mphal.c b/shared/runtime/sys_stdio_mphal.c index f1290853da73..6d43425e298f 100644 --- a/shared/runtime/sys_stdio_mphal.c +++ b/shared/runtime/sys_stdio_mphal.c @@ -132,7 +132,7 @@ MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &stdio_obj_stream_p, - locals_dict, (mp_obj_dict_t *)&stdio_locals_dict + locals_dict, &stdio_locals_dict ); const sys_stdio_obj_t mp_sys_stdin_obj = {{&stdio_obj_type}, .fd = STDIO_FD_IN}; @@ -168,7 +168,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( getiter, mp_identity_getiter, iternext, mp_stream_unbuffered_iter, protocol, &stdio_buffer_obj_stream_p, - locals_dict, (mp_obj_dict_t *)&stdio_locals_dict + locals_dict, &stdio_locals_dict ); STATIC const sys_stdio_obj_t stdio_buffer_obj = {{&stdio_buffer_obj_type}, .fd = 0}; // fd unused From 5ddf671944465411f90bd0968550b719d0dbdb80 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Jul 2021 15:02:15 +1000 Subject: [PATCH 1745/4290] py/objexcept: Make MP_DEFINE_EXCEPTION use MP_DEFINE_CONST_OBJ_TYPE. Signed-off-by: Jim Mussared --- py/objexcept.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/py/objexcept.h b/py/objexcept.h index 384456bb51a9..5d56d67d7314 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -41,13 +41,10 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); #define MP_DEFINE_EXCEPTION(exc_name, base_name) \ - const mp_obj_type_t mp_type_##exc_name = { \ - { &mp_type_type }, \ - .name = MP_QSTR_##exc_name, \ - .print = mp_obj_exception_print, \ - .make_new = mp_obj_exception_make_new, \ - .attr = mp_obj_exception_attr, \ - .parent = &mp_type_##base_name, \ - }; + MP_DEFINE_CONST_OBJ_TYPE(mp_type_##exc_name, MP_QSTR_##exc_name, MP_TYPE_FLAG_NONE, mp_obj_exception_make_new, \ + print, mp_obj_exception_print, \ + attr, mp_obj_exception_attr, \ + parent, &mp_type_##base_name \ + ); #endif // MICROPY_INCLUDED_PY_OBJEXCEPT_H From e8355eb16357b0bd234a9bcab1c9e8b72fcdbabc Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 22 Apr 2022 13:05:56 +1000 Subject: [PATCH 1746/4290] py/obj: Add "full" and "empty" non-variable-length mp_obj_type_t. This will always have the maximum/minimum size of a mp_obj_type_t representation and can be used as a member in other structs. Signed-off-by: Jim Mussared --- examples/natmod/btree/btree_c.c | 2 +- examples/natmod/framebuf/framebuf.c | 2 +- examples/natmod/ure/ure.c | 4 ++-- examples/natmod/uzlib/uzlib.c | 2 +- extmod/modbtree.c | 2 +- extmod/modframebuf.c | 2 +- extmod/modnetwork.h | 3 ++- extmod/modure.c | 10 +++++----- extmod/network_ninaw10.c | 2 +- extmod/network_wiznet5k.c | 2 +- ports/cc3200/mods/modnetwork.h | 3 ++- ports/cc3200/mods/modwlan.c | 2 +- py/obj.h | 15 +++++++++++++-- py/objnamedtuple.h | 5 ++++- py/objtype.c | 5 ++++- 15 files changed, 40 insertions(+), 21 deletions(-) diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c index 5e8a34ac4009..e342b7d90320 100644 --- a/examples/natmod/btree/btree_c.c +++ b/examples/natmod/btree/btree_c.c @@ -94,7 +94,7 @@ int mp_stream_posix_fsync(void *stream) { return res; } -mp_obj_type_t btree_type; +mp_obj_full_type_t btree_type; #include "extmod/modbtree.c" diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c index 2eff61c817d2..98b44987b342 100644 --- a/examples/natmod/framebuf/framebuf.c +++ b/examples/natmod/framebuf/framebuf.c @@ -8,7 +8,7 @@ void *memset(void *s, int c, size_t n) { } #endif -mp_obj_type_t mp_type_framebuf; +mp_obj_full_type_t mp_type_framebuf; #include "extmod/modframebuf.c" diff --git a/examples/natmod/ure/ure.c b/examples/natmod/ure/ure.c index 175b93e395ef..d9e11760a70c 100644 --- a/examples/natmod/ure/ure.c +++ b/examples/natmod/ure/ure.c @@ -32,8 +32,8 @@ void *memmove(void *dest, const void *src, size_t n) { return mp_fun_table.memmove_(dest, src, n); } -mp_obj_type_t match_type; -mp_obj_type_t re_type; +mp_obj_full_type_t match_type; +mp_obj_full_type_t re_type; #include "extmod/modure.c" diff --git a/examples/natmod/uzlib/uzlib.c b/examples/natmod/uzlib/uzlib.c index 99b3691761ea..24ab15d6f144 100644 --- a/examples/natmod/uzlib/uzlib.c +++ b/examples/natmod/uzlib/uzlib.c @@ -8,7 +8,7 @@ void *memset(void *s, int c, size_t n) { } #endif -mp_obj_type_t decompio_type; +mp_obj_full_type_t decompio_type; #include "extmod/moduzlib.c" diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 15cb6341637a..60c6885e6b2c 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -67,7 +67,7 @@ void __dbpanic(DB *db) { } STATIC mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) { - mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, &btree_type); + mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, (mp_obj_type_t *)&btree_type); o->stream = stream; o->db = db; o->start_key = mp_const_none; diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index f29eab272f0e..5347be564366 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -841,7 +841,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( // this factory function is provided for backwards compatibility with old FrameBuffer1 class STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args_in) { - mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, &mp_type_framebuf); + mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, (mp_obj_type_t *)&mp_type_framebuf); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE); diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h index 3481cc6dcc57..55ee4eb4d3e3 100644 --- a/extmod/modnetwork.h +++ b/extmod/modnetwork.h @@ -62,7 +62,8 @@ mp_obj_t mod_network_nic_ifconfig(struct netif *netif, size_t n_args, const mp_o struct _mod_network_socket_obj_t; typedef struct _mod_network_nic_type_t { - mp_obj_type_t base; + // Ensure that this struct is big enough to hold any type size. + mp_obj_full_type_t base; // API for non-socket operations int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out); diff --git a/extmod/modure.c b/extmod/modure.c index 43959924053b..c0114c14fd57 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -198,7 +198,7 @@ STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { (void)n_args; mp_obj_re_t *self; - if (mp_obj_is_type(args[0], &re_type)) { + if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) { self = MP_OBJ_TO_PTR(args[0]); } else { self = MP_OBJ_TO_PTR(mod_re_compile(1, args)); @@ -217,7 +217,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { return mp_const_none; } - match->base.type = &match_type; + match->base.type = (mp_obj_type_t *)&match_type; match->num_matches = caps_num / 2; // caps_num counts start and end pointers match->str = args[1]; return MP_OBJ_FROM_PTR(match); @@ -282,7 +282,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split); STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { mp_obj_re_t *self; - if (mp_obj_is_type(args[0], &re_type)) { + if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) { self = MP_OBJ_TO_PTR(args[0]); } else { self = MP_OBJ_TO_PTR(mod_re_compile(1, args)); @@ -305,7 +305,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { vstr_t vstr_return; vstr_return.buf = NULL; // We'll init the vstr after the first match mp_obj_match_t *match = mp_local_alloc(sizeof(mp_obj_match_t) + caps_num * sizeof(char *)); - match->base.type = &match_type; + match->base.type = (mp_obj_type_t *)&match_type; match->num_matches = caps_num / 2; // caps_num counts start and end pointers match->str = where; @@ -430,7 +430,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { if (size == -1) { goto error; } - mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type); + mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, (mp_obj_type_t *)&re_type); #if MICROPY_PY_URE_DEBUG int flags = 0; if (n_args > 1) { diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c index 0906176d20b0..806819648d2e 100644 --- a/extmod/network_ninaw10.c +++ b/extmod/network_ninaw10.c @@ -774,7 +774,7 @@ static const mp_rom_map_elem_t nina_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(nina_locals_dict, nina_locals_dict_table); -STATIC MP_DEFINE_CONST_OBJ_TYPE( +STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE( mod_network_nic_type_nina_base, MP_QSTR_nina, MP_TYPE_FLAG_NONE, diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 951a2966c93f..1d7318827c89 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -1024,7 +1024,7 @@ MP_DEFINE_CONST_OBJ_TYPE( locals_dict, &wiznet5k_locals_dict ); #else // WIZNET5K_PROVIDED_STACK -STATIC MP_DEFINE_CONST_OBJ_TYPE( +STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE( mod_network_nic_type_wiznet5k_base, MP_QSTR_WIZNET5K, MP_TYPE_FLAG_NONE, diff --git a/ports/cc3200/mods/modnetwork.h b/ports/cc3200/mods/modnetwork.h index 6ec90a2bac18..c15a6467f278 100644 --- a/ports/cc3200/mods/modnetwork.h +++ b/ports/cc3200/mods/modnetwork.h @@ -36,7 +36,8 @@ DEFINE TYPES ******************************************************************************/ typedef struct _mod_network_nic_type_t { - mp_obj_type_t base; + // Ensure that this struct is big enough to hold any type size. + mp_obj_full_type_t base; } mod_network_nic_type_t; typedef struct _mod_network_socket_base_t { diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c index 1c99f075e902..1e82b07e0874 100644 --- a/ports/cc3200/mods/modwlan.c +++ b/ports/cc3200/mods/modwlan.c @@ -1285,7 +1285,7 @@ STATIC const mp_rom_map_elem_t wlan_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table); -STATIC MP_DEFINE_CONST_OBJ_TYPE( +STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE( mod_network_nic_type_wlan_base, MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, diff --git a/py/obj.h b/py/obj.h index 4ab7e0dc09c1..9c0f41dc3d73 100644 --- a/py/obj.h +++ b/py/obj.h @@ -562,6 +562,9 @@ typedef mp_int_t (*mp_buffer_fun_t)(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); +// This struct will be updated to become a variable sized struct. In order to +// use this as a member, or allocate dynamically, use the mp_obj_empty_type_t +// or mp_obj_full_type_t structs below (which must be kept in sync). struct _mp_obj_type_t { // A type is an object so must start with this entry, which points to mp_type_type. mp_obj_base_t base; @@ -632,6 +635,13 @@ struct _mp_obj_type_t { struct _mp_obj_dict_t *locals_dict; }; +// Non-variable sized versions of mp_obj_type_t to be used as a member +// in other structs or for dynamic allocation. The fields are exactly +// as in mp_obj_type_t, but with a fixed size for the flexible array +// members. +typedef mp_obj_type_t mp_obj_empty_type_t; +typedef mp_obj_type_t mp_obj_full_type_t; + #define MP_TYPE_NULL_MAKE_NEW (NULL) // Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments. @@ -657,14 +667,15 @@ struct _mp_obj_type_t { // of the 30th argument (30 is 13*2 + 4). #define MP_DEFINE_CONST_OBJ_TYPE_NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, N, ...) MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N -// This macro is used to define a object type in ROM. +// These macros are used to define a object type in ROM. // Invoke as MP_DEFINE_CONST_OBJ_TYPE(_typename, _name, _flags, _make_new [, slot, func]*) -// It uses the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_* +// They use the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_* // macro to use based on the number of arguments. It works by shifting the // numeric values 12, 11, ... 0 by the number of arguments, such that the // 30th argument ends up being the number to use. The _INV values are // placeholders because the slot arguments come in pairs. #define MP_DEFINE_CONST_OBJ_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_type_t, __VA_ARGS__)) +#define MP_DEFINE_CONST_OBJ_FULL_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_full_type_t, __VA_ARGS__)) // Constant types, globally accessible extern const mp_obj_type_t mp_type_type; diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index d32af35afec4..9f23351d5a36 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -29,7 +29,10 @@ #include "py/objtuple.h" typedef struct _mp_obj_namedtuple_type_t { - mp_obj_type_t base; + // Must use the full-size version to avoid this being a variable sized member. + // This means that named tuples use slightly more RAM than necessary, but + // no worse than if we didn't have slots/split representation. + mp_obj_full_type_t base; size_t n_fields; qstr fields[]; } mp_obj_namedtuple_type_t; diff --git a/py/objtype.c b/py/objtype.c index 77fe8e22e384..cc5a5e580254 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1148,7 +1148,10 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) #endif } - mp_obj_type_t *o = m_new0(mp_obj_type_t, 1); + // Allocate a full-sized mp_obj_full_type_t instance (i.e. all slots / extended fields). + // Given that Python types use almost all the slots anyway, this doesn't cost anything + // extra. + mp_obj_type_t *o = (mp_obj_type_t *)m_new0(mp_obj_full_type_t, 1); o->base.type = &mp_type_type; o->flags = base_flags; o->name = name; From a52cd5b07d6d6e2502fff2bbfb9e5b96562452a4 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Jul 2021 17:14:16 +1000 Subject: [PATCH 1747/4290] py/obj: Add accessors for type slots and use everywhere. This is a no-op, but sets the stage for changing the mp_obj_type_t representation. Signed-off-by: Jim Mussared --- drivers/ninaw10/nina_wifi_bsp.c | 2 +- examples/natmod/btree/btree_c.c | 20 +-- examples/natmod/framebuf/framebuf.c | 4 +- examples/natmod/ure/ure.c | 8 +- examples/natmod/uzlib/uzlib.c | 6 +- extmod/machine_i2c.c | 22 +-- extmod/machine_signal.c | 2 +- extmod/machine_spi.c | 6 +- extmod/network_wiznet5k.c | 2 +- extmod/vfs.c | 5 +- extmod/virtpin.c | 4 +- .../nrf/modules/ubluepy/ubluepy_scan_entry.c | 2 +- ports/rp2/mpbthciport.c | 6 +- ports/unix/modffi.c | 4 +- py/builtinhelp.c | 4 +- py/dynruntime.h | 2 +- py/modbuiltins.c | 2 +- py/obj.c | 28 ++-- py/obj.h | 12 +- py/objarray.c | 2 +- py/objnamedtuple.c | 14 +- py/objtuple.c | 4 +- py/objtype.c | 136 +++++++++--------- py/opmethods.c | 12 +- py/runtime.c | 59 ++++---- py/stream.c | 25 ++-- py/stream.h | 2 +- 27 files changed, 207 insertions(+), 188 deletions(-) diff --git a/drivers/ninaw10/nina_wifi_bsp.c b/drivers/ninaw10/nina_wifi_bsp.c index a65ef7fd8644..d5b1308536af 100644 --- a/drivers/ninaw10/nina_wifi_bsp.c +++ b/drivers/ninaw10/nina_wifi_bsp.c @@ -137,7 +137,7 @@ int nina_bsp_spi_slave_deselect(void) { int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) { mp_obj_t mp_wifi_spi = MP_STATE_PORT(mp_wifi_spi); - ((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer(mp_wifi_spi, size, tx_buf, rx_buf); + ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, protocol))->transfer(mp_wifi_spi, size, tx_buf, rx_buf); #if NINA_DEBUG for (int i = 0; i < size; i++) { if (tx_buf) { diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c index e342b7d90320..af7535a68f7f 100644 --- a/examples/natmod/btree/btree_c.c +++ b/examples/natmod/btree/btree_c.c @@ -51,7 +51,7 @@ int *__errno (void) ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); if (out_sz == MP_STREAM_ERROR) { return -1; @@ -62,7 +62,7 @@ ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); if (out_sz == MP_STREAM_ERROR) { return -1; @@ -73,7 +73,7 @@ ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { const mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); struct mp_stream_seek_t seek_s; seek_s.offset = offset; seek_s.whence = whence; @@ -86,7 +86,7 @@ off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { int mp_stream_posix_fsync(void *stream) { mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno); if (res == MP_STREAM_ERROR) { return -1; @@ -124,11 +124,11 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a btree_type.base.type = (void*)&mp_fun_table.type_type; btree_type.name = MP_QSTR_btree; - btree_type.print = btree_print; - btree_type.getiter = btree_getiter; - btree_type.iternext = btree_iternext; - btree_type.binary_op = btree_binary_op; - btree_type.subscr = btree_subscr; + MP_OBJ_TYPE_SET_SLOT(&btree_type, print, btree_print, 0); + MP_OBJ_TYPE_SET_SLOT(&btree_type, getiter, btree_getiter, 1); + MP_OBJ_TYPE_SET_SLOT(&btree_type, iternext, btree_iternext, 2); + MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 3); + MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 4); btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) }; btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) }; btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) }; @@ -137,7 +137,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) }; btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) }; btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) }; - btree_type.locals_dict = (void*)&btree_locals_dict; + MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 5); mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj)); mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL)); diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c index 98b44987b342..4c557294719d 100644 --- a/examples/natmod/framebuf/framebuf.c +++ b/examples/natmod/framebuf/framebuf.c @@ -21,7 +21,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a mp_type_framebuf.base.type = (void*)&mp_type_type; mp_type_framebuf.name = MP_QSTR_FrameBuffer; mp_type_framebuf.make_new = framebuf_make_new; - mp_type_framebuf.buffer = framebuf_get_buffer; + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, buffer, framebuf_get_buffer, 0); framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; @@ -33,7 +33,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; framebuf_locals_dict_table[10] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; - mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict; + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, locals_dict, (void*)&framebuf_locals_dict, 1); mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj)); diff --git a/examples/natmod/ure/ure.c b/examples/natmod/ure/ure.c index d9e11760a70c..d4bd680abd42 100644 --- a/examples/natmod/ure/ure.c +++ b/examples/natmod/ure/ure.c @@ -54,21 +54,21 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a match_type.base.type = (void*)&mp_fun_table.type_type; match_type.name = MP_QSTR_match; - match_type.print = match_print; + MP_OBJ_TYPE_SET_SLOT(&match_type, print, match_print, 0); match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) }; match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) }; match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) }; match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) }; match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) }; - match_type.locals_dict = (void*)&match_locals_dict; + MP_OBJ_TYPE_SET_SLOT(&match_type, locals_dict, (void*)&match_locals_dict, 1); re_type.base.type = (void*)&mp_fun_table.type_type; re_type.name = MP_QSTR_ure; - re_type.print = re_print; + MP_OBJ_TYPE_SET_SLOT(&re_type, print, re_print, 0); re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) }; re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) }; re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) }; - re_type.locals_dict = (void*)&re_locals_dict; + MP_OBJ_TYPE_SET_SLOT(&re_type, locals_dict, (void*)&re_locals_dict, 1); mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj)); mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj)); diff --git a/examples/natmod/uzlib/uzlib.c b/examples/natmod/uzlib/uzlib.c index 24ab15d6f144..469452e8f843 100644 --- a/examples/natmod/uzlib/uzlib.c +++ b/examples/natmod/uzlib/uzlib.c @@ -20,12 +20,12 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a decompio_type.base.type = mp_fun_table.type_type; decompio_type.name = MP_QSTR_DecompIO; - decompio_type.make_new = decompio_make_new; - decompio_type.protocol = &decompio_stream_p; + decompio_type.make_new = &decompio_make_new; + MP_OBJ_TYPE_SET_SLOT(&decompio_type, protocol, &decompio_stream_p, 0); decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) }; decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) }; decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) }; - decompio_type.locals_dict = (void*)&decompio_locals_dict; + MP_OBJ_TYPE_SET_SLOT(&decompio_type, locals_dict, (void*)&decompio_locals_dict, 1); mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib)); mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj)); diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index 378bf8fc914b..bb7ade6fcf57 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -273,7 +273,7 @@ int mp_machine_i2c_transfer_adaptor(mp_obj_base_t *self, uint16_t addr, size_t n } } - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); int ret = i2c_p->transfer_single(self, addr, len, buf, flags); if (n > 1) { @@ -292,14 +292,14 @@ int mp_machine_i2c_transfer_adaptor(mp_obj_base_t *self, uint16_t addr, size_t n } STATIC int mp_machine_i2c_readfrom(mp_obj_base_t *self, uint16_t addr, uint8_t *dest, size_t len, bool stop) { - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); mp_machine_i2c_buf_t buf = {.len = len, .buf = dest}; unsigned int flags = MP_MACHINE_I2C_FLAG_READ | (stop ? MP_MACHINE_I2C_FLAG_STOP : 0); return i2c_p->transfer(self, addr, 1, &buf, flags); } STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self, uint16_t addr, const uint8_t *src, size_t len, bool stop) { - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); mp_machine_i2c_buf_t buf = {.len = len, .buf = (uint8_t *)src}; unsigned int flags = stop ? MP_MACHINE_I2C_FLAG_STOP : 0; return i2c_p->transfer(self, addr, 1, &buf, flags); @@ -310,7 +310,7 @@ STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self, uint16_t addr, const uint STATIC mp_obj_t machine_i2c_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); if (i2c_p->init == NULL) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); } @@ -338,7 +338,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_scan_obj, machine_i2c_scan); STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) { mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in); - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); if (i2c_p->start == NULL) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); } @@ -352,7 +352,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_start_obj, machine_i2c_start); STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) { mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in); - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); if (i2c_p->stop == NULL) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); } @@ -366,7 +366,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_stop_obj, machine_i2c_stop); STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) { mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); if (i2c_p->read == NULL) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); } @@ -390,7 +390,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readinto_obj, 2, 3, machine_i2c_ STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) { mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in); - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); if (i2c_p->write == NULL) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); } @@ -486,7 +486,7 @@ STATIC mp_obj_t machine_i2c_writevto(size_t n_args, const mp_obj_t *args) { } // Do the I2C transfer - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); int ret = i2c_p->transfer(self, addr, nbufs, bufs, stop ? MP_MACHINE_I2C_FLAG_STOP : 0); mp_local_free(bufs); @@ -519,7 +519,7 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a #if MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 // The I2C transfer function may support the MP_MACHINE_I2C_FLAG_WRITE1 option - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); if (i2c_p->transfer_supports_write1) { // Create partial write and read buffers mp_machine_i2c_buf_t bufs[2] = { @@ -556,7 +556,7 @@ STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t }; // Do I2C transfer - mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol); return i2c_p->transfer(self, addr, 2, bufs, MP_MACHINE_I2C_FLAG_STOP); } diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c index f665ffaa494e..49ee6dfb4abc 100644 --- a/extmod/machine_signal.c +++ b/extmod/machine_signal.c @@ -51,7 +51,7 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t if (n_args > 0 && mp_obj_is_obj(args[0])) { mp_obj_base_t *pin_base = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); - pin_p = (mp_pin_p_t *)pin_base->type->protocol; + pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT_OR_NULL(pin_base->type, protocol); } if (pin_p == NULL) { diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index c7fc5877b1b0..54f1964e2193 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -43,7 +43,7 @@ STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); - mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; + mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); spi_p->init(s, n_args - 1, args + 1, kw_args); return mp_const_none; } @@ -51,7 +51,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_spi_init_obj, 1, machine_spi_init); STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) { mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self); - mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; + mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); if (spi_p->deinit != NULL) { spi_p->deinit(s); } @@ -61,7 +61,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit); STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) { mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self); - mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; + mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); spi_p->transfer(s, len, src, dest); } diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 1d7318827c89..82f836f69184 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -744,7 +744,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k; wiznet5k_obj.cris_state = 0; wiznet5k_obj.spi = spi; - wiznet5k_obj.spi_transfer = ((mp_machine_spi_p_t *)spi->type->protocol)->transfer; + wiznet5k_obj.spi_transfer = ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(spi->type, protocol))->transfer; wiznet5k_obj.cs = cs; wiznet5k_obj.rst = rst; #if WIZNET5K_WITH_LWIP_STACK diff --git a/extmod/vfs.c b/extmod/vfs.c index 0ef20e928108..00450e100559 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -132,8 +132,9 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) { } // If the mounted object has the VFS protocol, call its import_stat helper - const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol; - if (proto != NULL) { + const mp_obj_type_t *type = mp_obj_get_type(vfs->obj); + if (MP_OBJ_TYPE_HAS_SLOT(type, protocol)) { + const mp_vfs_proto_t *proto = MP_OBJ_TYPE_GET_SLOT(type, protocol); return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out); } diff --git a/extmod/virtpin.c b/extmod/virtpin.c index 71a11232d433..cd0b9f92f830 100644 --- a/extmod/virtpin.c +++ b/extmod/virtpin.c @@ -28,12 +28,12 @@ int mp_virtual_pin_read(mp_obj_t pin) { mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin); - mp_pin_p_t *pin_p = (mp_pin_p_t *)s->type->protocol; + mp_pin_p_t *pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL); } void mp_virtual_pin_write(mp_obj_t pin, int value) { mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin); - mp_pin_p_t *pin_p = (mp_pin_p_t *)s->type->protocol; + mp_pin_p_t *pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL); } diff --git a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c index 5c74e2e92caf..89ca65d18c80 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c @@ -91,7 +91,7 @@ STATIC mp_obj_t scan_entry_get_scan_data(mp_obj_t self_in) { mp_obj_t description = mp_const_none; - mp_map_t *constant_map = mp_obj_dict_get_map(ubluepy_constants_ad_types_type.locals_dict); + mp_map_t *constant_map = mp_obj_dict_get_map(MP_OBJ_TYPE_GET_SLOT(&ubluepy_constants_ad_types_type, locals_dict)); mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table); uint16_t num_of_elements = constant_map->used; diff --git a/ports/rp2/mpbthciport.c b/ports/rp2/mpbthciport.c index 91c908b164fc..e37167a974de 100644 --- a/ports/rp2/mpbthciport.c +++ b/ports/rp2/mpbthciport.c @@ -128,7 +128,7 @@ int mp_bluetooth_hci_uart_set_baudrate(uint32_t baudrate) { int mp_bluetooth_hci_uart_any(void) { int errcode = 0; - const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; + const mp_stream_p_t *proto = (mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, protocol); mp_uint_t ret = proto->ioctl(mp_bthci_uart, MP_STREAM_POLL, MP_STREAM_POLL_RD, &errcode); if (errcode != 0) { @@ -142,7 +142,7 @@ int mp_bluetooth_hci_uart_write(const uint8_t *buf, size_t len) { debug_printf("mp_bluetooth_hci_uart_write\n"); int errcode = 0; - const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; + const mp_stream_p_t *proto = (mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, protocol); mp_bluetooth_hci_controller_wakeup(); @@ -159,7 +159,7 @@ int mp_bluetooth_hci_uart_readchar(void) { if (mp_bluetooth_hci_uart_any()) { int errcode = 0; uint8_t buf = 0; - const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; + const mp_stream_p_t *proto = (mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, protocol); if (proto->read(mp_bthci_uart, (void *)&buf, 1, &errcode) < 0) { error_printf("mp_bluetooth_hci_uart_readchar: failed to read UART %d\n", errcode); return -1; diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 98fd8936b1aa..04152f1ad41f 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -506,10 +506,10 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const } else if (mp_obj_is_str(a)) { const char *s = mp_obj_str_get_str(a); values[i].ffi = (ffi_arg)(intptr_t)s; - } else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer != NULL) { + } else if (MP_OBJ_TYPE_HAS_SLOT(((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type, buffer)) { mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a); mp_buffer_info_t bufinfo; - int ret = o->type->buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? + int ret = MP_OBJ_TYPE_GET_SLOT(o->type, buffer)(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? if (ret != 0) { goto error; } diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 94f8beaff23c..93d94a389d26 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -143,8 +143,8 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { if (type == &mp_type_type) { type = MP_OBJ_TO_PTR(obj); } - if (type->locals_dict != NULL) { - map = &type->locals_dict->map; + if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) { + map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map; } } if (map != NULL) { diff --git a/py/dynruntime.h b/py/dynruntime.h index fb748eb93fe7..be573bde2ad4 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -150,7 +150,7 @@ static inline mp_obj_t mp_obj_cast_to_native_base_dyn(mp_obj_t self_in, mp_const if (MP_OBJ_FROM_PTR(self_type) == native_type) { return self_in; - } else if (self_type->parent != native_type) { + } else if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(self_type, parent) != native_type) { // The self_in object is not a direct descendant of native_type, so fail the cast. // This is a very simple version of mp_obj_is_subclass_fast that could be improved. return MP_OBJ_NULL; diff --git a/py/modbuiltins.c b/py/modbuiltins.c index f74db95cf5a5..152323b5ca96 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -455,7 +455,7 @@ STATIC mp_obj_t mp_builtin___repl_print__(mp_obj_t o) { #if MICROPY_CAN_OVERRIDE_BUILTINS // Set "_" special variable mp_obj_t dest[2] = {MP_OBJ_SENTINEL, o}; - mp_type_module.attr(MP_OBJ_FROM_PTR(&mp_module_builtins), MP_QSTR__, dest); + MP_OBJ_TYPE_GET_SLOT(&mp_type_module, attr)(MP_OBJ_FROM_PTR(&mp_module_builtins), MP_QSTR__, dest); #endif } return mp_const_none; diff --git a/py/obj.c b/py/obj.c index eeadd3eeddda..359c73b9c212 100644 --- a/py/obj.c +++ b/py/obj.c @@ -116,8 +116,8 @@ void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } #endif const mp_obj_type_t *type = mp_obj_get_type(o_in); - if (type->print != NULL) { - type->print((mp_print_t *)print, o_in, kind); + if (MP_OBJ_TYPE_HAS_SLOT(type, print)) { + MP_OBJ_TYPE_GET_SLOT(type, print)((mp_print_t *)print, o_in, kind); } else { mp_printf(print, "<%q>", type->name); } @@ -170,8 +170,8 @@ bool mp_obj_is_true(mp_obj_t arg) { } } else { const mp_obj_type_t *type = mp_obj_get_type(arg); - if (type->unary_op != NULL) { - mp_obj_t result = type->unary_op(MP_UNARY_OP_BOOL, arg); + if (MP_OBJ_TYPE_HAS_SLOT(type, unary_op)) { + mp_obj_t result = MP_OBJ_TYPE_GET_SLOT(type, unary_op)(MP_UNARY_OP_BOOL, arg); if (result != MP_OBJ_NULL) { return result == mp_const_true; } @@ -189,7 +189,7 @@ bool mp_obj_is_true(mp_obj_t arg) { } bool mp_obj_is_callable(mp_obj_t o_in) { - const mp_call_fun_t call = mp_obj_get_type(o_in)->call; + const mp_call_fun_t call = MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o_in), call); if (call != mp_obj_instance_call) { return call != NULL; } @@ -256,19 +256,19 @@ mp_obj_t mp_obj_equal_not_equal(mp_binary_op_t op, mp_obj_t o1, mp_obj_t o2) { const mp_obj_type_t *type = mp_obj_get_type(o1); // If a full equality test is not needed and the other object is a different // type then we don't need to bother trying the comparison. - if (type->binary_op != NULL && + if (MP_OBJ_TYPE_HAS_SLOT(type, binary_op) && ((type->flags & MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) || mp_obj_get_type(o2) == type)) { // CPython is asymmetric: it will try __eq__ if there's no __ne__ but not the // other way around. If the class doesn't need a full test we can skip __ne__. if (op == MP_BINARY_OP_NOT_EQUAL && (type->flags & MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)) { - mp_obj_t r = type->binary_op(MP_BINARY_OP_NOT_EQUAL, o1, o2); + mp_obj_t r = MP_OBJ_TYPE_GET_SLOT(type, binary_op)(MP_BINARY_OP_NOT_EQUAL, o1, o2); if (r != MP_OBJ_NULL) { return r; } } // Try calling __eq__. - mp_obj_t r = type->binary_op(MP_BINARY_OP_EQUAL, o1, o2); + mp_obj_t r = MP_OBJ_TYPE_GET_SLOT(type, binary_op)(MP_BINARY_OP_EQUAL, o1, o2); if (r != MP_OBJ_NULL) { if (op == MP_BINARY_OP_EQUAL) { return r; @@ -524,8 +524,8 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { return MP_OBJ_NEW_SMALL_INT(l); } else { const mp_obj_type_t *type = mp_obj_get_type(o_in); - if (type->unary_op != NULL) { - return type->unary_op(MP_UNARY_OP_LEN, o_in); + if (MP_OBJ_TYPE_HAS_SLOT(type, unary_op)) { + return MP_OBJ_TYPE_GET_SLOT(type, unary_op)(MP_UNARY_OP_LEN, o_in); } else { return MP_OBJ_NULL; } @@ -534,8 +534,8 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { const mp_obj_type_t *type = mp_obj_get_type(base); - if (type->subscr != NULL) { - mp_obj_t ret = type->subscr(base, index, value); + if (MP_OBJ_TYPE_HAS_SLOT(type, subscr)) { + mp_obj_t ret = MP_OBJ_TYPE_GET_SLOT(type, subscr)(base, index, value); if (ret != MP_OBJ_NULL) { return ret; } @@ -579,10 +579,10 @@ mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) { bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { const mp_obj_type_t *type = mp_obj_get_type(obj); - if (type->buffer == NULL) { + if (!MP_OBJ_TYPE_HAS_SLOT(type, buffer)) { return false; } - int ret = type->buffer(obj, bufinfo, flags); + int ret = MP_OBJ_TYPE_GET_SLOT(type, buffer)(obj, bufinfo, flags); if (ret != 0) { return false; } diff --git a/py/obj.h b/py/obj.h index 9c0f41dc3d73..37e6f0052428 100644 --- a/py/obj.h +++ b/py/obj.h @@ -660,6 +660,16 @@ typedef mp_obj_type_t mp_obj_full_type_t; #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11 } #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11, .f12 = v12 } +// Always safe, checks if the type can and does have this slot. +#define MP_OBJ_TYPE_HAS_SLOT(t, f) ((t)->f) +// Requires you know that this type can have this slot. +#define MP_OBJ_TYPE_GET_SLOT(t, f) ((t)->f) +// Always safe, returns NULL if the type cannot have this slot. +#define MP_OBJ_TYPE_GET_SLOT_OR_NULL(t, f) ((t)->f) +#define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->f = v) +#define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, f)) +#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(void **)((char *)(t) + (offset)) != NULL) + // Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x @@ -822,7 +832,7 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); #endif #define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_exact_type(o, &mp_type_int)) #define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_exact_type(o, &mp_type_str)) -#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) +#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, binary_op) == mp_obj_str_binary_op)) #define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new) #define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) diff --git a/py/objarray.c b/py/objarray.c index 1cb163c4b97a..762a4105c5f5 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -443,7 +443,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value size_t src_len; void *src_items; size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL); - if (mp_obj_is_obj(value) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) { + if (mp_obj_is_obj(value) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type, subscr) == array_subscr) { // value is array, bytearray or memoryview mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value); if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) { diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index b2129935067c..cc55aec0b97c 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -157,14 +157,14 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t o->base.base.type = &mp_type_type; o->base.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple o->base.name = name; - o->base.print = namedtuple_print; o->base.make_new = namedtuple_make_new; - o->base.unary_op = mp_obj_tuple_unary_op; - o->base.binary_op = mp_obj_tuple_binary_op; - o->base.attr = namedtuple_attr; - o->base.subscr = mp_obj_tuple_subscr; - o->base.getiter = mp_obj_tuple_getiter; - o->base.parent = &mp_type_tuple; + MP_OBJ_TYPE_SET_SLOT(&o->base, print, namedtuple_print, 0); + MP_OBJ_TYPE_SET_SLOT(&o->base, unary_op, mp_obj_tuple_unary_op, 1); + MP_OBJ_TYPE_SET_SLOT(&o->base, binary_op, mp_obj_tuple_binary_op, 2); + MP_OBJ_TYPE_SET_SLOT(&o->base, attr, namedtuple_attr, 3); + MP_OBJ_TYPE_SET_SLOT(&o->base, subscr, mp_obj_tuple_subscr, 4); + MP_OBJ_TYPE_SET_SLOT(&o->base, getiter, mp_obj_tuple_getiter, 5); + MP_OBJ_TYPE_SET_SLOT(&o->base, parent, &mp_type_tuple, 6); return MP_OBJ_FROM_PTR(o); } diff --git a/py/objtuple.c b/py/objtuple.c index a684b13e6f25..01b2fa14885a 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -32,7 +32,7 @@ #include "py/runtime.h" // type check is done on getiter method to allow tuple, namedtuple, attrtuple -#define mp_obj_is_tuple_compatible(o) (mp_obj_get_type(o)->getiter == mp_obj_tuple_getiter) +#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), getiter) == mp_obj_tuple_getiter) /******************************************************************************/ /* tuple */ @@ -111,7 +111,7 @@ STATIC mp_obj_t tuple_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t anothe mp_check_self(mp_obj_is_tuple_compatible(self_in)); const mp_obj_type_t *another_type = mp_obj_get_type(another_in); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); - if (another_type->getiter != mp_obj_tuple_getiter) { + if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(another_type, getiter) != mp_obj_tuple_getiter) { // Slow path for user subclasses another_in = mp_obj_cast_to_native_base(another_in, MP_OBJ_FROM_PTR(&mp_type_tuple)); if (another_in == MP_OBJ_NULL) { diff --git a/py/objtype.c b/py/objtype.c index cc5a5e580254..968d6eb3ac32 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -59,13 +59,13 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t // Native types don't have parents (at least not from our perspective) so end. *last_native_base = type; return count + 1; - } else if (type->parent == NULL) { + } else if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) { // No parents so end search here. return count; #if MICROPY_MULTIPLE_INHERITANCE - } else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) { + } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) { // Multiple parents, search through them all recursively. - const mp_obj_tuple_t *parent_tuple = type->parent; + const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent); const mp_obj_t *item = parent_tuple->items; const mp_obj_t *top = item + parent_tuple->len; for (; item < top; ++item) { @@ -77,7 +77,7 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t #endif } else { // A single parent, use iteration to continue the search. - type = type->parent; + type = MP_OBJ_TYPE_GET_SLOT(type, parent); } } } @@ -118,7 +118,7 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_ // will keep lookup->dest[0]'s value (should be MP_OBJ_NULL on invocation) if attribute // is not found // will set lookup->dest[0] to MP_OBJ_SENTINEL if special method was found in a native -// type base via slot id (as specified by lookup->meth_offset). As there can be only one +// type base via slot id (as specified by lookup->slot_offset). As there can be only one // native base, it's known that it applies to instance->subobj[0]. In most cases, we also // don't need to know which type it was - because instance->subobj[0] is of that type. // The only exception is when object is not yet constructed, then we need to know base @@ -127,7 +127,7 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_ struct class_lookup_data { mp_obj_instance_t *obj; qstr attr; - size_t meth_offset; + size_t slot_offset; mp_obj_t *dest; bool is_type; }; @@ -141,19 +141,19 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t // This avoids extra method_name => slot lookup. On the other hand, // this should not be applied to class types, as will result in extra // lookup either. - if (lookup->meth_offset != 0 && mp_obj_is_native_type(type)) { - if (*(void **)((char *)type + lookup->meth_offset) != NULL) { + if (lookup->slot_offset != 0 && mp_obj_is_native_type(type)) { + if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset)) { DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n", - lookup->meth_offset, qstr_str(lookup->attr)); + lookup->slot_offset, qstr_str(lookup->attr)); lookup->dest[0] = MP_OBJ_SENTINEL; return; } } - if (type->locals_dict != NULL) { + if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) { // search locals_dict (the set of methods/attributes) - assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(type->locals_dict))); // MicroPython restriction, for now - mp_map_t *locals_map = &type->locals_dict->map; + assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(type, locals_dict)))); // MicroPython restriction, for now + mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map; mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(lookup->attr), MP_MAP_LOOKUP); if (elem != NULL) { if (lookup->is_type) { @@ -197,12 +197,12 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t // attribute not found, keep searching base classes - if (type->parent == NULL) { + if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) { DEBUG_printf("mp_obj_class_lookup: No more parents\n"); return; #if MICROPY_MULTIPLE_INHERITANCE - } else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) { - const mp_obj_tuple_t *parent_tuple = type->parent; + } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) { + const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent); const mp_obj_t *item = parent_tuple->items; const mp_obj_t *top = item + parent_tuple->len - 1; for (; item < top; ++item) { @@ -223,7 +223,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t type = (mp_obj_type_t *)MP_OBJ_TO_PTR(*item); #endif } else { - type = type->parent; + type = MP_OBJ_TYPE_GET_SLOT(type, parent); } if (type == &mp_type_object) { // Not a "real" type @@ -239,7 +239,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k struct class_lookup_data lookup = { .obj = self, .attr = meth, - .meth_offset = offsetof(mp_obj_type_t, print), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(print), .dest = member, .is_type = false, }; @@ -247,7 +247,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k if (member[0] == MP_OBJ_NULL && kind == PRINT_STR) { // If there's no __str__, fall back to __repr__ lookup.attr = MP_QSTR___repr__; - lookup.meth_offset = 0; + lookup.slot_offset = 0; mp_obj_class_lookup(&lookup, self->base.type); } @@ -282,7 +282,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size struct class_lookup_data lookup = { .obj = NULL, .attr = MP_QSTR___new__, - .meth_offset = offsetof(mp_obj_type_t, make_new), + .slot_offset = offsetof(mp_obj_type_t, make_new), .dest = init_fn, .is_type = false, }; @@ -332,7 +332,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size init_fn[0] = init_fn[1] = MP_OBJ_NULL; lookup.obj = o; lookup.attr = MP_QSTR___init__; - lookup.meth_offset = 0; + lookup.slot_offset = 0; mp_obj_class_lookup(&lookup, self); if (init_fn[0] != MP_OBJ_NULL) { mp_obj_t init_ret; @@ -414,7 +414,7 @@ STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) { struct class_lookup_data lookup = { .obj = self, .attr = op_name, - .meth_offset = offsetof(mp_obj_type_t, unary_op), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(unary_op), .dest = member, .is_type = false, }; @@ -542,7 +542,7 @@ retry:; struct class_lookup_data lookup = { .obj = lhs, .attr = op_name, - .meth_offset = offsetof(mp_obj_type_t, binary_op), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(binary_op), .dest = dest, .is_type = false, }; @@ -608,7 +608,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des struct class_lookup_data lookup = { .obj = self, .attr = attr, - .meth_offset = 0, + .slot_offset = 0, .dest = dest, .is_type = false, }; @@ -693,7 +693,7 @@ STATIC bool mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t val struct class_lookup_data lookup = { .obj = self, .attr = attr, - .meth_offset = 0, + .slot_offset = 0, .dest = member, .is_type = false, }; @@ -815,7 +815,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value mp_obj_t member[4] = {MP_OBJ_NULL, MP_OBJ_NULL, index, value}; struct class_lookup_data lookup = { .obj = self, - .meth_offset = offsetof(mp_obj_type_t, subscr), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(subscr), .dest = member, .is_type = false, }; @@ -850,7 +850,7 @@ STATIC mp_obj_t mp_obj_instance_get_call(mp_obj_t self_in, mp_obj_t *member) { struct class_lookup_data lookup = { .obj = self, .attr = MP_QSTR___call__, - .meth_offset = offsetof(mp_obj_type_t, call), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(call), .dest = member, .is_type = false, }; @@ -889,7 +889,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) struct class_lookup_data lookup = { .obj = self, .attr = MP_QSTR___iter__, - .meth_offset = offsetof(mp_obj_type_t, getiter), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(getiter), .dest = member, .is_type = false, }; @@ -901,7 +901,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) if (iter_buf == NULL) { iter_buf = m_new_obj(mp_obj_iter_buf_t); } - return type->getiter(self->subobj[0], iter_buf); + return MP_OBJ_TYPE_GET_SLOT(type, getiter)(self->subobj[0], iter_buf); } else { return mp_call_method_n_kw(0, 0, member); } @@ -913,14 +913,14 @@ STATIC mp_int_t instance_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, struct class_lookup_data lookup = { .obj = self, .attr = MP_QSTR_, // don't actually look for a method - .meth_offset = offsetof(mp_obj_type_t, buffer), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(buffer), .dest = member, .is_type = false, }; mp_obj_class_lookup(&lookup, self->base.type); if (member[0] == MP_OBJ_SENTINEL) { const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]); - return type->buffer(self->subobj[0], bufinfo, flags); + return MP_OBJ_TYPE_GET_SLOT(type, buffer)(self->subobj[0], bufinfo, flags); } else { return 1; // object does not support buffer protocol } @@ -1021,7 +1021,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (attr == MP_QSTR___dict__) { // Returns a read-only dict of the class attributes. // If the internal locals is not fixed, a copy will be created. - const mp_obj_dict_t *dict = self->locals_dict; + const mp_obj_dict_t *dict = MP_OBJ_TYPE_GET_SLOT_OR_NULL(self, locals_dict); if (!dict) { dict = &mp_const_empty_dict_obj; } @@ -1040,7 +1040,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[0] = mp_const_empty_tuple; return; } - mp_obj_t parent_obj = self->parent ? MP_OBJ_FROM_PTR(self->parent) : MP_OBJ_FROM_PTR(&mp_type_object); + mp_obj_t parent_obj = MP_OBJ_TYPE_HAS_SLOT(self, parent) ? MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, parent)) : MP_OBJ_FROM_PTR(&mp_type_object); #if MICROPY_MULTIPLE_INHERITANCE if (mp_obj_is_type(parent_obj, &mp_type_tuple)) { dest[0] = parent_obj; @@ -1054,7 +1054,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { struct class_lookup_data lookup = { .obj = (mp_obj_instance_t *)self, .attr = attr, - .meth_offset = 0, + .slot_offset = 0, .dest = dest, .is_type = true, }; @@ -1062,9 +1062,9 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } else { // delete/store attribute - if (self->locals_dict != NULL) { - assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(self->locals_dict))); // MicroPython restriction, for now - mp_map_t *locals_map = &self->locals_dict->map; + if (MP_OBJ_TYPE_HAS_SLOT(self, locals_dict)) { + assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, locals_dict)))); // MicroPython restriction, for now + mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(self, locals_dict)->map; if (locals_map->is_fixed) { // can't apply delete/store to a fixed map return; @@ -1155,43 +1155,44 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) o->base.type = &mp_type_type; o->flags = base_flags; o->name = name; - o->print = instance_print; o->make_new = mp_obj_instance_make_new; - o->call = mp_obj_instance_call; - o->unary_op = instance_unary_op; - o->binary_op = instance_binary_op; - o->attr = mp_obj_instance_attr; - o->subscr = instance_subscr; - o->getiter = mp_obj_instance_getiter; - // o->iternext = ; not implemented - o->buffer = instance_get_buffer; + MP_OBJ_TYPE_SET_SLOT(o, print, instance_print, 0); + MP_OBJ_TYPE_SET_SLOT(o, call, mp_obj_instance_call, 1); + MP_OBJ_TYPE_SET_SLOT(o, unary_op, instance_unary_op, 2); + MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 3); + MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 4); + MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 5); + MP_OBJ_TYPE_SET_SLOT(o, getiter, mp_obj_instance_getiter, 6); + // MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented) + MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7); if (bases_len > 0) { // Inherit protocol from a base class. This allows to define an // abstract base class which would translate C-level protocol to // Python method calls, and any subclass inheriting from it will // support this feature. - o->protocol = ((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0]))->protocol; + MP_OBJ_TYPE_SET_SLOT(o, protocol, MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0])), protocol), 8); if (bases_len >= 2) { #if MICROPY_MULTIPLE_INHERITANCE - o->parent = MP_OBJ_TO_PTR(bases_tuple); + MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_tuple), 9); #else mp_raise_NotImplementedError(MP_ERROR_TEXT("multiple inheritance not supported")); #endif } else { - o->parent = MP_OBJ_TO_PTR(bases_items[0]); + MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_items[0]), 9); } } - o->locals_dict = MP_OBJ_TO_PTR(locals_dict); + mp_obj_dict_t *locals_ptr = MP_OBJ_TO_PTR(locals_dict); + MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 10); #if ENABLE_SPECIAL_ACCESSORS // Check if the class has any special accessor methods if (!(o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) { - for (size_t i = 0; i < o->locals_dict->map.alloc; i++) { - if (mp_map_slot_is_filled(&o->locals_dict->map, i)) { - const mp_map_elem_t *elem = &o->locals_dict->map.table[i]; + for (size_t i = 0; i < locals_ptr->map.alloc; i++) { + if (mp_map_slot_is_filled(&locals_ptr->map, i)) { + const mp_map_elem_t *elem = &locals_ptr->map.table[i]; if (check_for_special_accessors(elem->key, elem->value)) { o->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS; break; @@ -1207,7 +1208,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict")); } - mp_map_t *locals_map = &o->locals_dict->map; + mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(o, locals_dict)->map; mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); if (elem != NULL) { // __new__ slot exists; check if it is a function @@ -1268,21 +1269,21 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { struct class_lookup_data lookup = { .obj = MP_OBJ_TO_PTR(self->obj), .attr = attr, - .meth_offset = 0, + .slot_offset = 0, .dest = dest, .is_type = false, }; - // Allow a call super().__init__() to reach any native base classes + // Allow a call super().__init__() to reach any native base classes. if (attr == MP_QSTR___init__) { - lookup.meth_offset = offsetof(mp_obj_type_t, make_new); + lookup.slot_offset = offsetof(mp_obj_type_t, make_new); } - if (type->parent == NULL) { + if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) { // no parents, do nothing #if MICROPY_MULTIPLE_INHERITANCE - } else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) { - const mp_obj_tuple_t *parent_tuple = type->parent; + } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) { + const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent); size_t len = parent_tuple->len; const mp_obj_t *items = parent_tuple->items; for (size_t i = 0; i < len; i++) { @@ -1292,14 +1293,15 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { // and we don't want to lookup native methods in object. continue; } + mp_obj_class_lookup(&lookup, (mp_obj_type_t *)MP_OBJ_TO_PTR(items[i])); if (dest[0] != MP_OBJ_NULL) { break; } } #endif - } else if (type->parent != &mp_type_object) { - mp_obj_class_lookup(&lookup, type->parent); + } else if (MP_OBJ_TYPE_GET_SLOT(type, parent) != &mp_type_object) { + mp_obj_class_lookup(&lookup, MP_OBJ_TYPE_GET_SLOT(type, parent)); } if (dest[0] != MP_OBJ_NULL) { @@ -1311,9 +1313,9 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { return; } - // Reset meth_offset so we don't look up any native methods in object, + // Reset slot_offset so we don't look up any native methods in object, // because object never takes up the native base-class slot. - lookup.meth_offset = 0; + lookup.slot_offset = 0; mp_obj_class_lookup(&lookup, &mp_type_object); } @@ -1352,13 +1354,13 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) { const mp_obj_type_t *self = MP_OBJ_TO_PTR(object); - if (self->parent == NULL) { + if (!MP_OBJ_TYPE_HAS_SLOT(self, parent)) { // type has no parents return false; #if MICROPY_MULTIPLE_INHERITANCE - } else if (((mp_obj_base_t *)self->parent)->type == &mp_type_tuple) { + } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(self, parent))->type == &mp_type_tuple) { // get the base objects (they should be type objects) - const mp_obj_tuple_t *parent_tuple = self->parent; + const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(self, parent); const mp_obj_t *item = parent_tuple->items; const mp_obj_t *top = item + parent_tuple->len - 1; @@ -1374,7 +1376,7 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) { #endif } else { // type has 1 parent - object = MP_OBJ_FROM_PTR(self->parent); + object = MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, parent)); } } } diff --git a/py/opmethods.c b/py/opmethods.c index 595cc088ba93..c3931fd35846 100644 --- a/py/opmethods.c +++ b/py/opmethods.c @@ -29,24 +29,28 @@ STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) { const mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, MP_OBJ_SENTINEL); + // Note: assumes type must have subscr (only used by dict). + return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_SENTINEL); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem); STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) { const mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, value_in); + // Note: assumes type must have subscr (only used by dict). + return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, value_in); } MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem); STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) { const mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, MP_OBJ_NULL); + // Note: assumes type must have subscr (only used by dict). + return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_NULL); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_delitem_obj, op_delitem); STATIC mp_obj_t op_contains(mp_obj_t lhs_in, mp_obj_t rhs_in) { const mp_obj_type_t *type = mp_obj_get_type(lhs_in); - return type->binary_op(MP_BINARY_OP_CONTAINS, lhs_in, rhs_in); + // Note: assumes type must have binary_op (only used by set/frozenset). + return MP_OBJ_TYPE_GET_SLOT(type, binary_op)(MP_BINARY_OP_CONTAINS, lhs_in, rhs_in); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_contains_obj, op_contains); diff --git a/py/runtime.c b/py/runtime.c index 27b4f05f0460..d0e504a3d096 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -307,8 +307,8 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { return MP_OBJ_NEW_SMALL_INT(h); } else { const mp_obj_type_t *type = mp_obj_get_type(arg); - if (type->unary_op != NULL) { - mp_obj_t result = type->unary_op(op, arg); + if (MP_OBJ_TYPE_HAS_SLOT(type, unary_op)) { + mp_obj_t result = MP_OBJ_TYPE_GET_SLOT(type, unary_op)(op, arg); if (result != MP_OBJ_NULL) { return result; } @@ -613,8 +613,8 @@ mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs const mp_obj_type_t *type; generic_binary_op: type = mp_obj_get_type(lhs); - if (type->binary_op != NULL) { - mp_obj_t result = type->binary_op(op, lhs, rhs); + if (MP_OBJ_TYPE_HAS_SLOT(type, binary_op)) { + mp_obj_t result = MP_OBJ_TYPE_GET_SLOT(type, binary_op)(op, lhs, rhs); if (result != MP_OBJ_NULL) { return result; } @@ -689,8 +689,8 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons const mp_obj_type_t *type = mp_obj_get_type(fun_in); // do the call - if (type->call != NULL) { - return type->call(fun_in, n_args, n_kw, args); + if (MP_OBJ_TYPE_HAS_SLOT(type, call)) { + return MP_OBJ_TYPE_GET_SLOT(type, call)(fun_in, n_args, n_kw, args); } #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE @@ -1167,14 +1167,14 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { } #endif - if (attr == MP_QSTR___next__ && type->iternext != NULL) { + if (attr == MP_QSTR___next__ && MP_OBJ_TYPE_HAS_SLOT(type, iternext)) { dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj); dest[1] = obj; return; } - if (type->attr != NULL) { + if (MP_OBJ_TYPE_HAS_SLOT(type, attr)) { // this type can do its own load, so call it - type->attr(obj, attr, dest); + MP_OBJ_TYPE_GET_SLOT(type, attr)(obj, attr, dest); // If type->attr has set dest[1] = MP_OBJ_SENTINEL, we should proceed // with lookups below (i.e. in locals_dict). If not, return right away. if (dest[1] != MP_OBJ_SENTINEL) { @@ -1183,11 +1183,11 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { // Clear the fail flag set by type->attr so it's like it never ran. dest[1] = MP_OBJ_NULL; } - if (type->locals_dict != NULL) { + if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) { // generic method lookup // this is a lookup in the object (ie not class or type) - assert(type->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now - mp_map_t *locals_map = &type->locals_dict->map; + assert(MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->base.type == &mp_type_dict); // MicroPython restriction, for now + mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map; mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { mp_convert_member_lookup(obj, type, elem->value, dest); @@ -1239,9 +1239,9 @@ void mp_load_method_protected(mp_obj_t obj, qstr attr, mp_obj_t *dest, bool catc void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { DEBUG_OP_printf("store attr %p.%s <- %p\n", base, qstr_str(attr), value); const mp_obj_type_t *type = mp_obj_get_type(base); - if (type->attr != NULL) { + if (MP_OBJ_TYPE_HAS_SLOT(type, attr)) { mp_obj_t dest[2] = {MP_OBJ_SENTINEL, value}; - type->attr(base, attr, dest); + MP_OBJ_TYPE_GET_SLOT(type, attr)(base, attr, dest); if (dest[0] == MP_OBJ_NULL) { // success return; @@ -1260,20 +1260,21 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { assert(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in); - // Check for native getiter which is the identity. We handle this case explicitly - // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used. - if (type->getiter == mp_identity_getiter) { - return o_in; - } - // check for native getiter (corresponds to __iter__) - if (type->getiter != NULL) { - if (iter_buf == NULL && type->getiter != mp_obj_instance_getiter) { + if (MP_OBJ_TYPE_HAS_SLOT(type, getiter)) { + // Check for native getiter which is the identity. We handle this case explicitly + // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used. + if (MP_OBJ_TYPE_GET_SLOT(type, getiter) == mp_identity_getiter) { + return o_in; + } + + // check for native getiter (corresponds to __iter__) + if (iter_buf == NULL && MP_OBJ_TYPE_GET_SLOT(type, getiter) != mp_obj_instance_getiter) { // if caller did not provide a buffer then allocate one on the heap // mp_obj_instance_getiter is special, it will allocate only if needed iter_buf = m_new_obj(mp_obj_iter_buf_t); } - mp_obj_t iter = type->getiter(o_in, iter_buf); + mp_obj_t iter = MP_OBJ_TYPE_GET_SLOT(type, getiter)(o_in, iter_buf); if (iter != MP_OBJ_NULL) { return iter; } @@ -1305,9 +1306,9 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { // may also raise StopIteration() mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { const mp_obj_type_t *type = mp_obj_get_type(o_in); - if (type->iternext != NULL) { + if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; - return type->iternext(o_in); + return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in); } else { // check for __next__ method mp_obj_t dest[2]; @@ -1331,9 +1332,9 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { mp_obj_t mp_iternext(mp_obj_t o_in) { MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext const mp_obj_type_t *type = mp_obj_get_type(o_in); - if (type->iternext != NULL) { + if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; - return type->iternext(o_in); + return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in); } else { // check for __next__ method mp_obj_t dest[2]; @@ -1371,9 +1372,9 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val); } - if (type->iternext != NULL && send_value == mp_const_none) { + if (MP_OBJ_TYPE_HAS_SLOT(type, iternext) && send_value == mp_const_none) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; - mp_obj_t ret = type->iternext(self_in); + mp_obj_t ret = MP_OBJ_TYPE_GET_SLOT(type, iternext)(self_in); *ret_val = ret; if (ret != MP_OBJ_STOP_ITERATION) { return MP_VM_RETURN_YIELD; diff --git a/py/stream.c b/py/stream.c index 87bed38f6778..36325e7d414a 100644 --- a/py/stream.c +++ b/py/stream.c @@ -84,15 +84,16 @@ mp_uint_t mp_stream_rw(mp_obj_t stream, void *buf_, mp_uint_t size, int *errcode const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) { const mp_obj_type_t *type = mp_obj_get_type(self_in); - const mp_stream_p_t *stream_p = type->protocol; - if (stream_p == NULL - || ((flags & MP_STREAM_OP_READ) && stream_p->read == NULL) - || ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL) - || ((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) { - // CPython: io.UnsupportedOperation, OSError subclass - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("stream operation not supported")); + if (MP_OBJ_TYPE_HAS_SLOT(type, protocol)) { + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(type, protocol); + if (!((flags & MP_STREAM_OP_READ) && stream_p->read == NULL) + && !((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL) + && !((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) { + return stream_p; + } } - return stream_p; + // CPython: io.UnsupportedOperation, OSError subclass + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("stream operation not supported")); } STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte flags) { @@ -517,7 +518,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj, 2, 3, stream_ioctl); ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { mp_obj_base_t *o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &errno); if (out_sz == MP_STREAM_ERROR) { return -1; @@ -528,7 +529,7 @@ ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { mp_obj_base_t *o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &errno); if (out_sz == MP_STREAM_ERROR) { return -1; @@ -539,7 +540,7 @@ ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { const mp_obj_base_t *o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); struct mp_stream_seek_t seek_s; seek_s.offset = offset; seek_s.whence = whence; @@ -552,7 +553,7 @@ off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { int mp_stream_posix_fsync(void *stream) { mp_obj_base_t *o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &errno); if (res == MP_STREAM_ERROR) { return -1; diff --git a/py/stream.h b/py/stream.h index 45f36ef5a6f3..4bc329b3e790 100644 --- a/py/stream.h +++ b/py/stream.h @@ -95,7 +95,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj); // Object is assumed to have a non-NULL stream protocol with valid r/w/ioctl methods static inline const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) { - return (const mp_stream_p_t *)((const mp_obj_base_t *)MP_OBJ_TO_PTR(self))->type->protocol; + return (const mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(((const mp_obj_base_t *)MP_OBJ_TO_PTR(self))->type, protocol); } const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags); From 3ac8b5851e5f4dade465d52b91ed2ccc17851263 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 15 Jul 2021 15:04:40 +1000 Subject: [PATCH 1748/4290] py/obj: Add slot-index mp_obj_type_t representation. The existings mp_obj_type_t uses a sparse representation for slots for the capability methods of the type (eg print, make_new). This commit adds a compact slot-index representation. The basic idea is that where the mp_obj_type_t struct used to have 12 pointer fields, it now has 12 uint8_t indices, and a variable-length array of pointers. So in the best case (no fields used) it saves 12x4-12=36 bytes (on a 32-bit machine) and in the common case (three fields used) it saves 9x4-12=24 bytes. Overall with all associated changes, this slot-index representation reduces code size by 1000 to 3000 bytes on bare-metal ports. Performance is marginally better on a few tests (eg about 1% better on misc_pystone.py and misc_raytrace.py on PYBv1.1), but overall marginally worse by a percent or so. See issue #7542 for further analysis and discussion. Signed-off-by: Jim Mussared --- py/mpconfig.h | 7 +++ py/obj.h | 121 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 125 insertions(+), 3 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index 698d264d2e80..0045fa1985b0 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -145,6 +145,13 @@ #define MICROPY_OBJ_IMMEDIATE_OBJS (MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D) #endif +#define MICROPY_OBJ_TYPE_REPR_FULL (0) +#define MICROPY_OBJ_TYPE_REPR_SLOT_INDEX (1) + +#ifndef MICROPY_OBJ_TYPE_REPR +#define MICROPY_OBJ_TYPE_REPR (MICROPY_OBJ_TYPE_REPR_FULL) +#endif + /*****************************************************************************/ /* Memory allocation policy */ diff --git a/py/obj.h b/py/obj.h index 37e6f0052428..c17e0e5f1899 100644 --- a/py/obj.h +++ b/py/obj.h @@ -575,12 +575,13 @@ struct _mp_obj_type_t { // The name of this type, a qstr. uint16_t name; - // Corresponds to __repr__ and __str__ special methods. - mp_print_fun_t print; - // Corresponds to __new__ and __init__ special methods, to make an instance of the type. mp_make_new_fun_t make_new; + #if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL + // Corresponds to __repr__ and __str__ special methods. + mp_print_fun_t print; + // Corresponds to __call__ special method, ie T(...). mp_call_fun_t call; @@ -633,17 +634,87 @@ struct _mp_obj_type_t { // A dict mapping qstrs to objects local methods/constants/etc. struct _mp_obj_dict_t *locals_dict; + + #elif MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX + + // Ideally these would be only 4 bits, but the extra overhead of + // accessing them adds more code, and we also need to be able to + // take the address of them for mp_obj_class_lookup. + uint8_t slot_index_print; + uint8_t slot_index_call; + uint8_t slot_index_unary_op; + uint8_t slot_index_binary_op; + uint8_t slot_index_attr; + uint8_t slot_index_subscr; + uint8_t slot_index_getiter; + uint8_t slot_index_iternext; + uint8_t slot_index_buffer; + uint8_t slot_index_protocol; + uint8_t slot_index_parent; + uint8_t slot_index_locals_dict; + + const void *slots[]; + + #endif }; // Non-variable sized versions of mp_obj_type_t to be used as a member // in other structs or for dynamic allocation. The fields are exactly // as in mp_obj_type_t, but with a fixed size for the flexible array // members. +#if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL typedef mp_obj_type_t mp_obj_empty_type_t; typedef mp_obj_type_t mp_obj_full_type_t; +#else +typedef struct _mp_obj_empty_type_t { + mp_obj_base_t base; + uint16_t flags; + uint16_t name; + mp_make_new_fun_t make_new; + + uint8_t slot_index_print; + uint8_t slot_index_call; + uint8_t slot_index_unary_op; + uint8_t slot_index_binary_op; + uint8_t slot_index_attr; + uint8_t slot_index_subscr; + uint8_t slot_index_getiter; + uint8_t slot_index_iternext; + uint8_t slot_index_buffer; + uint8_t slot_index_protocol; + uint8_t slot_index_parent; + uint8_t slot_index_locals_dict; + + // No slots member. +} mp_obj_empty_type_t; + +typedef struct _mp_obj_full_type_t { + mp_obj_base_t base; + uint16_t flags; + uint16_t name; + mp_make_new_fun_t make_new; + + uint8_t slot_index_print; + uint8_t slot_index_call; + uint8_t slot_index_unary_op; + uint8_t slot_index_binary_op; + uint8_t slot_index_attr; + uint8_t slot_index_subscr; + uint8_t slot_index_getiter; + uint8_t slot_index_iternext; + uint8_t slot_index_buffer; + uint8_t slot_index_protocol; + uint8_t slot_index_parent; + uint8_t slot_index_locals_dict; + + // Explicitly add 12 slots. + const void *slots[12]; +} mp_obj_full_type_t; +#endif #define MP_TYPE_NULL_MAKE_NEW (NULL) +#if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL // Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments. // Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE. #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0(_struct_type, _typename, _name, _flags, _make_new) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new } @@ -670,6 +741,50 @@ typedef mp_obj_type_t mp_obj_full_type_t; #define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, f)) #define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(void **)((char *)(t) + (offset)) != NULL) +#elif MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX + +#define _MP_OBJ_TYPE_SLOT_TYPE_print (mp_print_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_call (mp_call_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_unary_op (mp_unary_op_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_binary_op (mp_binary_op_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_attr (mp_attr_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_subscr (mp_subscr_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_getiter (mp_getiter_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_iternext (mp_fun_1_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_buffer (mp_buffer_fun_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_protocol (const void *) +#define _MP_OBJ_TYPE_SLOT_TYPE_parent (const void *) +#define _MP_OBJ_TYPE_SLOT_TYPE_locals_dict (struct _mp_obj_dict_t *) + +// Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments. +// Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE. +// Generated with: +// for i in range(13): +// print(f"#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_{i}(_struct_type, _typename, _name, _flags, _make_new{''.join(f', f{j+1}, v{j+1}' for j in range(i))}) const _struct_type _typename = {{ .base = {{ &mp_type_type }}, .name = _name, .flags = _flags, .make_new = _make_new{''.join(f', .slot_index_##f{j+1} = {j+1}' for j in range(i))}{', .slots = { ' + ''.join(f'v{j+1}, ' for j in range(i)) + '}' if i else '' } }}") +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0(_struct_type, _typename, _name, _flags, _make_new) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_1(_struct_type, _typename, _name, _flags, _make_new, f1, v1) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slots = { v1, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_2(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slots = { v1, v2, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_3(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slots = { v1, v2, v3, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_4(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slots = { v1, v2, v3, v4, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_5(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slots = { v1, v2, v3, v4, v5, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_6(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slots = { v1, v2, v3, v4, v5, v6, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slots = { v1, v2, v3, v4, v5, v6, v7, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_8(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_9(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_10(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slot_index_##f12 = 12, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, } } + +#define MP_OBJ_TYPE_HAS_SLOT(t, f) ((t)->slot_index_##f) +#define MP_OBJ_TYPE_GET_SLOT(t, f) (_MP_OBJ_TYPE_SLOT_TYPE_##f(t)->slots[(t)->slot_index_##f - 1]) +#define MP_OBJ_TYPE_GET_SLOT_OR_NULL(t, f) (_MP_OBJ_TYPE_SLOT_TYPE_##f(MP_OBJ_TYPE_HAS_SLOT(t, f) ? MP_OBJ_TYPE_GET_SLOT(t, f) : NULL)) +#define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->slot_index_##f = (n) + 1, (t)->slots[(t)->slot_index_##f - 1] = (void *)v) +#define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, slot_index_##f)) +// For everything except make_new, the offset is to the uint8_t index. For make_new, we need to check the pointer. +#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(uint8_t *)((char *)(t) + (offset)) != 0 || (offset == offsetof(mp_obj_type_t, make_new) && t->make_new)) + +#endif + // Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x From cb0ffdd2bf25dcac3c230bdc1168d492aabaf573 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 22 Jun 2022 11:24:41 +1000 Subject: [PATCH 1749/4290] py/obj: Remove basic mp_obj_type_t sparse representation. This makes the slots-based representation the only option. Signed-off-by: Jim Mussared --- py/mpconfig.h | 7 ----- py/obj.h | 85 +++++++++++---------------------------------------- 2 files changed, 17 insertions(+), 75 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index 0045fa1985b0..698d264d2e80 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -145,13 +145,6 @@ #define MICROPY_OBJ_IMMEDIATE_OBJS (MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D) #endif -#define MICROPY_OBJ_TYPE_REPR_FULL (0) -#define MICROPY_OBJ_TYPE_REPR_SLOT_INDEX (1) - -#ifndef MICROPY_OBJ_TYPE_REPR -#define MICROPY_OBJ_TYPE_REPR (MICROPY_OBJ_TYPE_REPR_FULL) -#endif - /*****************************************************************************/ /* Memory allocation policy */ diff --git a/py/obj.h b/py/obj.h index c17e0e5f1899..878fa673487a 100644 --- a/py/obj.h +++ b/py/obj.h @@ -578,17 +578,22 @@ struct _mp_obj_type_t { // Corresponds to __new__ and __init__ special methods, to make an instance of the type. mp_make_new_fun_t make_new; - #if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL + // Slots: For the rest of the fields, the slot index points to the + // relevant function in the variable-length "slots" field. Ideally these + // would be only 4 bits, but the extra overhead of accessing them adds + // more code, and we also need to be able to take the address of them for + // mp_obj_class_lookup. + // Corresponds to __repr__ and __str__ special methods. - mp_print_fun_t print; + uint8_t slot_index_print; // Corresponds to __call__ special method, ie T(...). - mp_call_fun_t call; + uint8_t slot_index_call; // Implements unary and binary operations. // Can return MP_OBJ_NULL if the operation is not supported. - mp_unary_op_fun_t unary_op; - mp_binary_op_fun_t binary_op; + uint8_t slot_index_unary_op; + uint8_t slot_index_binary_op; // Implements load, store and delete attribute. // @@ -602,70 +607,46 @@ struct _mp_obj_type_t { // dest[0,1] = {MP_OBJ_SENTINEL, object} means store // return: for fail, do nothing // for success set dest[0] = MP_OBJ_NULL - mp_attr_fun_t attr; + uint8_t slot_index_attr; // Implements load, store and delete subscripting: // - value = MP_OBJ_SENTINEL means load // - value = MP_OBJ_NULL means delete // - all other values mean store the value // Can return MP_OBJ_NULL if operation not supported. - mp_subscr_fun_t subscr; + uint8_t slot_index_subscr; // Corresponds to __iter__ special method. // Can use the given mp_obj_iter_buf_t to store iterator object, // otherwise can return a pointer to an object on the heap. - mp_getiter_fun_t getiter; + uint8_t slot_index_getiter; // Corresponds to __next__ special method. May return MP_OBJ_STOP_ITERATION // as an optimisation instead of raising StopIteration() with no args. - mp_fun_1_t iternext; + uint8_t slot_index_iternext; // Implements the buffer protocol if supported by this type. - mp_buffer_fun_t buffer; + uint8_t slot_index_buffer; // One of disjoint protocols (interfaces), like mp_stream_p_t, etc. - const void *protocol; + uint8_t slot_index_protocol; // A pointer to the parents of this type: // - 0 parents: pointer is NULL (object is implicitly the single parent) // - 1 parent: a pointer to the type of that parent // - 2 or more parents: pointer to a tuple object containing the parent types - const void *parent; + uint8_t slot_index_parent; // A dict mapping qstrs to objects local methods/constants/etc. - struct _mp_obj_dict_t *locals_dict; - - #elif MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX - - // Ideally these would be only 4 bits, but the extra overhead of - // accessing them adds more code, and we also need to be able to - // take the address of them for mp_obj_class_lookup. - uint8_t slot_index_print; - uint8_t slot_index_call; - uint8_t slot_index_unary_op; - uint8_t slot_index_binary_op; - uint8_t slot_index_attr; - uint8_t slot_index_subscr; - uint8_t slot_index_getiter; - uint8_t slot_index_iternext; - uint8_t slot_index_buffer; - uint8_t slot_index_protocol; - uint8_t slot_index_parent; uint8_t slot_index_locals_dict; const void *slots[]; - - #endif }; // Non-variable sized versions of mp_obj_type_t to be used as a member // in other structs or for dynamic allocation. The fields are exactly // as in mp_obj_type_t, but with a fixed size for the flexible array // members. -#if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL -typedef mp_obj_type_t mp_obj_empty_type_t; -typedef mp_obj_type_t mp_obj_full_type_t; -#else typedef struct _mp_obj_empty_type_t { mp_obj_base_t base; uint16_t flags; @@ -710,39 +691,9 @@ typedef struct _mp_obj_full_type_t { // Explicitly add 12 slots. const void *slots[12]; } mp_obj_full_type_t; -#endif #define MP_TYPE_NULL_MAKE_NEW (NULL) -#if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL -// Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments. -// Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE. -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0(_struct_type, _typename, _name, _flags, _make_new) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_1(_struct_type, _typename, _name, _flags, _make_new, f1, v1) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_2(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_3(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_4(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_5(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_6(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_8(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_9(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_10(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11 } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11, .f12 = v12 } - -// Always safe, checks if the type can and does have this slot. -#define MP_OBJ_TYPE_HAS_SLOT(t, f) ((t)->f) -// Requires you know that this type can have this slot. -#define MP_OBJ_TYPE_GET_SLOT(t, f) ((t)->f) -// Always safe, returns NULL if the type cannot have this slot. -#define MP_OBJ_TYPE_GET_SLOT_OR_NULL(t, f) ((t)->f) -#define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->f = v) -#define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, f)) -#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(void **)((char *)(t) + (offset)) != NULL) - -#elif MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX - #define _MP_OBJ_TYPE_SLOT_TYPE_print (mp_print_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_call (mp_call_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_unary_op (mp_unary_op_fun_t) @@ -783,8 +734,6 @@ typedef struct _mp_obj_full_type_t { // For everything except make_new, the offset is to the uint8_t index. For make_new, we need to check the pointer. #define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(uint8_t *)((char *)(t) + (offset)) != 0 || (offset == offsetof(mp_obj_type_t, make_new) && t->make_new)) -#endif - // Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x From 165388e4eb5db1207f4d839abe77d417d4c3f7c3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 13 Sep 2022 23:56:52 +1000 Subject: [PATCH 1750/4290] py/objtype: Optimise slot RAM usage for instance types. In all cases other than where you have a native base with a protocol, it now fits into 4 GC blocks (like it did before the slots representation). Signed-off-by: Jim Mussared --- py/misc.h | 1 + py/objnamedtuple.c | 3 +-- py/objtype.c | 33 ++++++++++++++++++++------------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/py/misc.h b/py/misc.h index 134325f8946f..7350d2f9b0c0 100644 --- a/py/misc.h +++ b/py/misc.h @@ -72,6 +72,7 @@ typedef unsigned int uint; #define m_new_obj(type) (m_new(type, 1)) #define m_new_obj_maybe(type) (m_new_maybe(type, 1)) #define m_new_obj_var(obj_type, var_type, var_num) ((obj_type *)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num))) +#define m_new_obj_var0(obj_type, var_type, var_num) ((obj_type *)m_malloc0(sizeof(obj_type) + sizeof(var_type) * (var_num))) #define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type *)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num))) #if MICROPY_ENABLE_FINALISER #define m_new_obj_with_finaliser(type) ((type *)(m_malloc_with_finaliser(sizeof(type)))) diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index cc55aec0b97c..566652161774 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -143,8 +143,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, } mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields) { - mp_obj_namedtuple_type_t *o = m_new_obj_var(mp_obj_namedtuple_type_t, qstr, n_fields); - memset(&o->base, 0, sizeof(o->base)); + mp_obj_namedtuple_type_t *o = m_new_obj_var0(mp_obj_namedtuple_type_t, qstr, n_fields); o->n_fields = n_fields; for (size_t i = 0; i < n_fields; i++) { o->fields[i] = mp_obj_str_get_qstr(fields[i]); diff --git a/py/objtype.c b/py/objtype.c index 968d6eb3ac32..5b4e375bcc48 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1148,10 +1148,15 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) #endif } - // Allocate a full-sized mp_obj_full_type_t instance (i.e. all slots / extended fields). - // Given that Python types use almost all the slots anyway, this doesn't cost anything - // extra. - mp_obj_type_t *o = (mp_obj_type_t *)m_new0(mp_obj_full_type_t, 1); + const void *base_protocol = NULL; + if (bases_len > 0) { + base_protocol = MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0])), protocol); + } + + // Allocate a variable-sized mp_obj_type_t with as many slots as we need + // (currently 9, plus 1 for base, plus 1 for base-protocol). + // Note: 11 slots pushes it from 4 to 5 GC blocks. + mp_obj_type_t *o = m_new_obj_var0(mp_obj_type_t, void *, 9 + (bases_len ? 1 : 0) + (base_protocol ? 1 : 0)); o->base.type = &mp_type_type; o->flags = base_flags; o->name = name; @@ -1166,13 +1171,10 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented) MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7); - if (bases_len > 0) { - // Inherit protocol from a base class. This allows to define an - // abstract base class which would translate C-level protocol to - // Python method calls, and any subclass inheriting from it will - // support this feature. - MP_OBJ_TYPE_SET_SLOT(o, protocol, MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0])), protocol), 8); + mp_obj_dict_t *locals_ptr = MP_OBJ_TO_PTR(locals_dict); + MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 8); + if (bases_len > 0) { if (bases_len >= 2) { #if MICROPY_MULTIPLE_INHERITANCE MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_tuple), 9); @@ -1182,10 +1184,15 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) } else { MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_items[0]), 9); } - } - mp_obj_dict_t *locals_ptr = MP_OBJ_TO_PTR(locals_dict); - MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 10); + // Inherit protocol from a base class. This allows to define an + // abstract base class which would translate C-level protocol to + // Python method calls, and any subclass inheriting from it will + // support this feature. + if (base_protocol) { + MP_OBJ_TYPE_SET_SLOT(o, protocol, base_protocol, 10); + } + } #if ENABLE_SPECIAL_ACCESSORS // Check if the class has any special accessor methods From 3c6127dfcfc63a2b48c31f751d1ae2c385874c8a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 14 Sep 2022 00:39:48 +1000 Subject: [PATCH 1751/4290] py/objnamedtuple: Optimise slot RAM usage for namedtuple. Rather than reserving a full 12-slot mp_obj_type_t, reserve enough room for seven and cast as necessary. Signed-off-by: Jim Mussared --- py/objnamedtuple.c | 25 +++++++++++++------------ py/objnamedtuple.h | 7 +++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 566652161774..52536be8b4e9 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -104,7 +104,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("%q() takes %d positional arguments but %d were given"), - type->base.name, num_fields, n_args + n_kw); + ((mp_obj_type_t *)&type->base)->name, num_fields, n_args + n_kw); #endif } @@ -153,17 +153,18 @@ mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t * STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t *fields) { mp_obj_namedtuple_type_t *o = mp_obj_new_namedtuple_base(n_fields, fields); - o->base.base.type = &mp_type_type; - o->base.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple - o->base.name = name; - o->base.make_new = namedtuple_make_new; - MP_OBJ_TYPE_SET_SLOT(&o->base, print, namedtuple_print, 0); - MP_OBJ_TYPE_SET_SLOT(&o->base, unary_op, mp_obj_tuple_unary_op, 1); - MP_OBJ_TYPE_SET_SLOT(&o->base, binary_op, mp_obj_tuple_binary_op, 2); - MP_OBJ_TYPE_SET_SLOT(&o->base, attr, namedtuple_attr, 3); - MP_OBJ_TYPE_SET_SLOT(&o->base, subscr, mp_obj_tuple_subscr, 4); - MP_OBJ_TYPE_SET_SLOT(&o->base, getiter, mp_obj_tuple_getiter, 5); - MP_OBJ_TYPE_SET_SLOT(&o->base, parent, &mp_type_tuple, 6); + mp_obj_type_t *type = (mp_obj_type_t *)&o->base; + type->base.type = &mp_type_type; + type->flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple + type->name = name; + type->make_new = namedtuple_make_new; + MP_OBJ_TYPE_SET_SLOT(type, print, namedtuple_print, 0); + MP_OBJ_TYPE_SET_SLOT(type, unary_op, mp_obj_tuple_unary_op, 1); + MP_OBJ_TYPE_SET_SLOT(type, binary_op, mp_obj_tuple_binary_op, 2); + MP_OBJ_TYPE_SET_SLOT(type, attr, namedtuple_attr, 3); + MP_OBJ_TYPE_SET_SLOT(type, subscr, mp_obj_tuple_subscr, 4); + MP_OBJ_TYPE_SET_SLOT(type, getiter, mp_obj_tuple_getiter, 5); + MP_OBJ_TYPE_SET_SLOT(type, parent, &mp_type_tuple, 6); return MP_OBJ_FROM_PTR(o); } diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index 9f23351d5a36..db4a3d87d87f 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -29,10 +29,9 @@ #include "py/objtuple.h" typedef struct _mp_obj_namedtuple_type_t { - // Must use the full-size version to avoid this being a variable sized member. - // This means that named tuples use slightly more RAM than necessary, but - // no worse than if we didn't have slots/split representation. - mp_obj_full_type_t base; + // This is a mp_obj_type_t with seven slots. + mp_obj_empty_type_t base; + void *slots[7]; size_t n_fields; qstr fields[]; } mp_obj_namedtuple_type_t; From 6da41b59007c9e9a2443ae17278d32210034a63f Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 16 Sep 2022 23:57:38 +1000 Subject: [PATCH 1752/4290] py/obj: Merge getiter and iternext mp_obj_type_t slots. The goal here is to remove a slot (making way to turn make_new into a slot) as well as reduce code size by the ~40 references to mp_identity_getiter and mp_stream_unbuffered_iter. This introduces two new type flags: - MP_TYPE_FLAG_ITER_IS_ITERNEXT: This means that the "iter" slot in the type is "iternext", and should use the identity getiter. - MP_TYPE_FLAG_ITER_IS_CUSTOM: This means that the "iter" slot is a pointer to a mp_getiter_iternext_custom_t instance, which then defines both getiter and iternext. And a third flag that is the OR of both, MP_TYPE_FLAG_ITER_IS_STREAM: This means that the type should use the identity getiter, and mp_stream_unbuffered_iter as iternext. Finally, MP_TYPE_FLAG_ITER_IS_GETITER is defined as a no-op flag to give the default case where "iter" is "getiter". Signed-off-by: Jim Mussared --- examples/natmod/btree/btree_c.c | 14 +++-- extmod/modbtree.c | 10 +++- extmod/moduasyncio.c | 10 +++- extmod/moduselect.c | 5 +- extmod/modussl_axtls.c | 2 - extmod/modussl_mbedtls.c | 2 - extmod/vfs_fat_file.c | 8 +-- extmod/vfs_lfsx_file.c | 8 +-- extmod/vfs_posix_file.c | 8 +-- ports/cc3200/mods/modussl.c | 3 - ports/cc3200/mods/pybuart.c | 4 +- ports/esp32/machine_i2s.c | 4 +- ports/esp32/machine_uart.c | 4 +- ports/esp8266/machine_uart.c | 4 +- ports/mimxrt/machine_i2s.c | 4 +- ports/mimxrt/machine_uart.c | 4 +- ports/nrf/boards/microbit/modules/iters.c | 5 +- .../boards/microbit/modules/microbitimage.c | 20 +++---- ports/nrf/modules/machine/uart.c | 4 +- ports/renesas-ra/machine_uart.c | 4 +- ports/rp2/machine_i2s.c | 4 +- ports/rp2/machine_uart.c | 4 +- ports/stm32/machine_i2s.c | 4 +- ports/stm32/machine_uart.c | 4 +- ports/stm32/usb.c | 4 +- ports/unix/modjni.c | 4 +- ports/unix/moduselect.c | 5 +- ports/unix/modusocket.c | 2 - ports/zephyr/machine_uart.c | 4 +- py/obj.c | 8 +-- py/obj.h | 56 ++++++++++++------- py/objarray.c | 17 +++--- py/objattrtuple.c | 4 +- py/objdict.c | 17 +++--- py/objenumerate.c | 5 +- py/objfilter.c | 5 +- py/objgenerator.c | 5 +- py/objgetitemiter.c | 5 +- py/objlist.c | 4 +- py/objmap.c | 5 +- py/objnamedtuple.c | 2 +- py/objpolyiter.c | 10 ++-- py/objrange.c | 7 +-- py/objreversed.c | 5 +- py/objset.c | 8 +-- py/objstr.c | 4 +- py/objstringio.c | 8 +-- py/objstrunicode.c | 4 +- py/objtuple.c | 8 +-- py/objtype.c | 23 +++++--- py/objzip.c | 5 +- py/runtime.c | 52 +++++++++++------ shared/runtime/sys_stdio_mphal.c | 8 +-- tests/basics/io_stringio_base.py | 24 ++++++++ 54 files changed, 234 insertions(+), 227 deletions(-) create mode 100644 tests/basics/io_stringio_base.py diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c index af7535a68f7f..c897f2e9a385 100644 --- a/examples/natmod/btree/btree_c.c +++ b/examples/natmod/btree/btree_c.c @@ -95,6 +95,7 @@ int mp_stream_posix_fsync(void *stream) { } mp_obj_full_type_t btree_type; +mp_getiter_iternext_custom_t btree_getiter_iternext; #include "extmod/modbtree.c" @@ -122,13 +123,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_open_obj, 5, 5, btree_open); mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { MP_DYNRUNTIME_INIT_ENTRY + btree_getiter_iternext.getiter = btree_getiter; + btree_getiter_iternext.iternext = btree_iternext; + btree_type.base.type = (void*)&mp_fun_table.type_type; + btree_type.flags = MP_TYPE_FLAG_ITER_IS_CUSTOM; btree_type.name = MP_QSTR_btree; MP_OBJ_TYPE_SET_SLOT(&btree_type, print, btree_print, 0); - MP_OBJ_TYPE_SET_SLOT(&btree_type, getiter, btree_getiter, 1); - MP_OBJ_TYPE_SET_SLOT(&btree_type, iternext, btree_iternext, 2); - MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 3); - MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 4); + MP_OBJ_TYPE_SET_SLOT(&btree_type, iter, &btree_getiter_iternext, 1); + MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 2); + MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 3); btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) }; btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) }; btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) }; @@ -137,7 +141,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) }; btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) }; btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) }; - MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 5); + MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 4); mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj)); mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL)); diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 60c6885e6b2c..f21fe3ff9417 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -319,15 +319,19 @@ STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table); +STATIC const mp_getiter_iternext_custom_t btree_getiter_iternext = { + .getiter = btree_getiter, + .iternext = btree_iternext, +}; + STATIC MP_DEFINE_CONST_OBJ_TYPE( btree_type, MP_QSTR_btree, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_CUSTOM, MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module print, btree_print, - getiter, btree_getiter, - iternext, btree_iternext, + iter, &btree_getiter_iternext, binary_op, btree_binary_op, subscr, btree_subscr, locals_dict, &btree_locals_dict diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c index 546764209608..b0eb8b6509c8 100644 --- a/extmod/moduasyncio.c +++ b/extmod/moduasyncio.c @@ -287,14 +287,18 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) { return mp_const_none; } +STATIC const mp_getiter_iternext_custom_t task_getiter_iternext = { + .getiter = task_getiter, + .iternext = task_iternext, +}; + STATIC MP_DEFINE_CONST_OBJ_TYPE( task_type, MP_QSTR_Task, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_CUSTOM, task_make_new, attr, task_attr, - getiter, task_getiter, - iternext, task_iternext + iter, &task_getiter_iternext ); /******************************************************************************/ diff --git a/extmod/moduselect.c b/extmod/moduselect.c index 352b15d983d8..58bd1169a945 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -339,10 +339,9 @@ STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table); STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_poll, MP_QSTR_poll, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, poll_iternext, + iter, poll_iternext, locals_dict, &poll_locals_dict ); diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c index 78470ea6df04..a6d606d560eb 100644 --- a/extmod/modussl_axtls.c +++ b/extmod/modussl_axtls.c @@ -321,8 +321,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module print, ussl_socket_print, - getiter, NULL, - iternext, NULL, protocol, &ussl_socket_stream_p, locals_dict, &ussl_socket_locals_dict ); diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 76ca3ac719c9..50712980ba04 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -399,8 +399,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module print, socket_print, - getiter, NULL, - iternext, NULL, protocol, &ussl_socket_stream_p, locals_dict, &ussl_socket_locals_dict ); diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 00980459db8b..ca2e2b446f13 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -179,11 +179,9 @@ STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_fat_fileio, MP_QSTR_FileIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, file_obj_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &vfs_fat_fileio_stream_p, locals_dict, &vfs_fat_rawfile_locals_dict ); @@ -198,11 +196,9 @@ STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_fat_textio, MP_QSTR_TextIOWrapper, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, file_obj_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &vfs_fat_textio_stream_p, locals_dict, &vfs_fat_rawfile_locals_dict ); diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c index fda1b97b2a13..f97641b7b951 100644 --- a/extmod/vfs_lfsx_file.c +++ b/extmod/vfs_lfsx_file.c @@ -223,11 +223,9 @@ STATIC const mp_stream_p_t MP_VFS_LFSx(fileio_stream_p) = { MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_VFS_LFSx_(_fileio), MP_QSTR_FileIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, MP_VFS_LFSx(file_print), - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &MP_VFS_LFSx(fileio_stream_p), locals_dict, &MP_VFS_LFSx(file_locals_dict) ); @@ -242,11 +240,9 @@ STATIC const mp_stream_p_t MP_VFS_LFSx(textio_stream_p) = { MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_VFS_LFSx_(_textio), MP_QSTR_TextIOWrapper, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, MP_VFS_LFSx(file_print), - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &MP_VFS_LFSx(textio_stream_p), locals_dict, &MP_VFS_LFSx(file_locals_dict) ); diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index f0b5436fe1ea..729d914d3a11 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -252,11 +252,9 @@ STATIC const mp_stream_p_t vfs_posix_fileio_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_posix_fileio, MP_QSTR_FileIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, vfs_posix_file_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &vfs_posix_fileio_stream_p, locals_dict, &vfs_posix_rawfile_locals_dict ); @@ -271,11 +269,9 @@ STATIC const mp_stream_p_t vfs_posix_textio_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_posix_textio, MP_QSTR_TextIOWrapper, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, vfs_posix_file_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &vfs_posix_textio_stream_p, locals_dict, &vfs_posix_rawfile_locals_dict ); diff --git a/ports/cc3200/mods/modussl.c b/ports/cc3200/mods/modussl.c index abc9917c8134..118cbd06f8fa 100644 --- a/ports/cc3200/mods/modussl.c +++ b/ports/cc3200/mods/modussl.c @@ -64,9 +64,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ssl_socket_type, MP_QSTR_ussl, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, - getiter, NULL, - iternext, NULL, protocol, &socket_stream_p, locals_dict, &socket_locals_dict ); diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c index e7896c4ca5cf..f92f54473220 100644 --- a/ports/cc3200/mods/pybuart.c +++ b/ports/cc3200/mods/pybuart.c @@ -688,11 +688,9 @@ STATIC const mp_irq_methods_t uart_irq_methods = { MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, pyb_uart_make_new, print, pyb_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &pyb_uart_locals_dict ); diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index b853f418ada3..6e18394cc5e5 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -832,11 +832,9 @@ STATIC const mp_stream_p_t i2s_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_i2s_make_new, print, machine_i2s_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict ); diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 6e091b8838a2..1f404154fc5b 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -533,11 +533,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_uart_make_new, print, machine_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict ); diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index c737f854c34f..af6231c21903 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -346,11 +346,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, pyb_uart_make_new, print, pyb_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &pyb_uart_locals_dict ); diff --git a/ports/mimxrt/machine_i2s.c b/ports/mimxrt/machine_i2s.c index 13380b4ee6b0..b6c630138b76 100644 --- a/ports/mimxrt/machine_i2s.c +++ b/ports/mimxrt/machine_i2s.c @@ -1216,11 +1216,9 @@ STATIC const mp_stream_p_t i2s_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_i2s_make_new, print, machine_i2s_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict ); diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index 9d4873274a8f..e93d2478f3ff 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -472,11 +472,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_uart_make_new, print, machine_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict ); diff --git a/ports/nrf/boards/microbit/modules/iters.c b/ports/nrf/boards/microbit/modules/iters.c index 296fc1f51c52..2fe14866914f 100644 --- a/ports/nrf/boards/microbit/modules/iters.c +++ b/ports/nrf/boards/microbit/modules/iters.c @@ -46,10 +46,9 @@ static mp_obj_t microbit_repeat_iter_next(mp_obj_t iter_in) { MP_DEFINE_CONST_OBJ_TYPE( microbit_repeat_iterator_type, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, microbit_repeat_iter_next + iter, microbit_repeat_iter_next ); mp_obj_t microbit_repeat_iterator(mp_obj_t iterable) { diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c index 4870b6738f6c..b22c2e29acec 100644 --- a/ports/nrf/boards/microbit/modules/microbitimage.c +++ b/ports/nrf/boards/microbit/modules/microbitimage.c @@ -824,18 +824,16 @@ STATIC mp_obj_t microbit_scrolling_string_iter_next(mp_obj_t o_in) { MP_DEFINE_CONST_OBJ_TYPE( microbit_scrolling_string_type, MP_QSTR_ScrollingString, - MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, - getiter, get_microbit_scrolling_string_iter + MP_TYPE_FLAG_ITER_IS_GETITER, + iter, get_microbit_scrolling_string_iter ); MP_DEFINE_CONST_OBJ_TYPE( microbit_scrolling_string_iterator_type, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, microbit_scrolling_string_iter_next + iter, microbit_scrolling_string_iter_next ); /** Facade types to present a string as a sequence of images. @@ -877,11 +875,10 @@ static mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t MP_DEFINE_CONST_OBJ_TYPE( string_image_facade_type, MP_QSTR_Facade, - MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, + MP_TYPE_FLAG_ITER_IS_GETITER, unary_op, facade_unary_op, subscr, string_image_facade_subscr, - getiter, microbit_facade_iterator + iter, microbit_facade_iterator ); @@ -914,10 +911,9 @@ static mp_obj_t microbit_facade_iter_next(mp_obj_t iter_in) { MP_DEFINE_CONST_OBJ_TYPE( microbit_facade_iterator_type, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, microbit_facade_iter_next + iter, microbit_facade_iter_next ); mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf) { diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index fc0bd682b4b7..ca0fcf859a55 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -373,11 +373,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_hard_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_hard_uart_make_new, print, machine_hard_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &machine_hard_uart_locals_dict ); diff --git a/ports/renesas-ra/machine_uart.c b/ports/renesas-ra/machine_uart.c index 11f5d6825eb2..6fa84ca821e4 100644 --- a/ports/renesas-ra/machine_uart.c +++ b/ports/renesas-ra/machine_uart.c @@ -574,12 +574,10 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_uart_make_new, locals_dict, &machine_uart_locals_dict, print, machine_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p ); diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c index 9d70a476f30b..53ff7417d79a 100644 --- a/ports/rp2/machine_i2s.c +++ b/ports/rp2/machine_i2s.c @@ -1140,11 +1140,9 @@ STATIC const mp_stream_p_t i2s_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_i2s_make_new, print, machine_i2s_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict ); diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index bb8bf51be651..06f7e9aaaca2 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -582,11 +582,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_uart_make_new, print, machine_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict ); diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c index 93a465d07ca8..d68648bc348a 100644 --- a/ports/stm32/machine_i2s.c +++ b/ports/stm32/machine_i2s.c @@ -1117,11 +1117,9 @@ STATIC const mp_stream_p_t i2s_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_i2s_make_new, print, machine_i2s_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict ); diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index 5851d8cf352d..4ccff8c136ad 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -663,11 +663,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, pyb_uart_make_new, print, pyb_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &pyb_uart_locals_dict ); diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index df755fe984c3..e389ef68f2aa 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -939,11 +939,9 @@ STATIC const mp_stream_p_t pyb_usb_vcp_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( pyb_usb_vcp_type, MP_QSTR_USB_VCP, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, pyb_usb_vcp_make_new, print, pyb_usb_vcp_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &pyb_usb_vcp_stream_p, locals_dict, &pyb_usb_vcp_locals_dict ); diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 02368e453716..e6b874b235ec 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -325,13 +325,13 @@ STATIC mp_obj_t subscr_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { STATIC MP_DEFINE_CONST_OBJ_TYPE( jobject_type, MP_QSTR_jobject, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, MP_TYPE_NULL_MAKE_NEW, print, jobject_print, unary_op, jobject_unary_op, attr, jobject_attr, subscr, jobject_subscr, - getiter, subscr_getiter, + iter, subscr_getiter, // .locals_dict = &jobject_locals_dict, ); diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index baed88761c46..674841bf1871 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -314,10 +314,9 @@ STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table); STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_poll, MP_QSTR_poll, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, poll_iternext, + iter, poll_iternext, locals_dict, &poll_locals_dict ); diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 21260f0b2ada..dfbf15cd3efd 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -522,8 +522,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, socket_make_new, print, socket_print, - getiter, NULL, - iternext, NULL, protocol, &usocket_stream_p, locals_dict, &usocket_locals_dict ); diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c index 9580d3790781..867c5ae8863a 100644 --- a/ports/zephyr/machine_uart.c +++ b/ports/zephyr/machine_uart.c @@ -157,11 +157,9 @@ STATIC const mp_stream_p_t uart_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, machine_uart_make_new, print, machine_uart_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict ); diff --git a/py/obj.c b/py/obj.c index 359c73b9c212..eb17308fed88 100644 --- a/py/obj.c +++ b/py/obj.c @@ -572,10 +572,10 @@ mp_obj_t mp_identity(mp_obj_t self) { } MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); -mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) { - (void)iter_buf; - return self; -} +// mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) { +// (void)iter_buf; +// return self; +// } bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { const mp_obj_type_t *type = mp_obj_get_type(obj); diff --git a/py/obj.h b/py/obj.h index 878fa673487a..b1d722080c66 100644 --- a/py/obj.h +++ b/py/obj.h @@ -507,12 +507,20 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); // Flags for type behaviour (mp_obj_type_t.flags) // If MP_TYPE_FLAG_EQ_NOT_REFLEXIVE is clear then __eq__ is reflexive (A==A returns True). // If MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE is clear then the type can't be equal to an -// instance of any different class that also clears this flag. If this flag is set -// then the type may check for equality against a different type. +// instance of any different class that also clears this flag. If this flag is set +// then the type may check for equality against a different type. // If MP_TYPE_FLAG_EQ_HAS_NEQ_TEST is clear then the type only implements the __eq__ -// operator and not the __ne__ operator. If it's set then __ne__ may be implemented. +// operator and not the __ne__ operator. If it's set then __ne__ may be implemented. // If MP_TYPE_FLAG_BINDS_SELF is set then the type as a method binds self as the first arg. // If MP_TYPE_FLAG_BUILTIN_FUN is set then the type is a built-in function type. +// MP_TYPE_FLAG_ITER_IS_GETITER is a no-op flag that means the default behaviour for the +// iter slot and it's the getiter function. +// If MP_TYPE_FLAG_ITER_IS_ITERNEXT is set then the "iter" slot is the iternext +// function and getiter will be automatically implemented as "return self". +// If MP_TYPE_FLAG_ITER_IS_CUSTOM is set then the "iter" slot is a pointer to a +// mp_getiter_iternext_custom_t struct instance (with both .getiter and .iternext set). +// If MP_TYPE_FLAG_ITER_IS_STREAM is set then the type implicitly gets a "return self" +// getiter, and mp_stream_unbuffered_iter for iternext. #define MP_TYPE_FLAG_NONE (0x0000) #define MP_TYPE_FLAG_IS_SUBCLASSED (0x0001) #define MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002) @@ -521,6 +529,10 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); #define MP_TYPE_FLAG_EQ_HAS_NEQ_TEST (0x0010) #define MP_TYPE_FLAG_BINDS_SELF (0x0020) #define MP_TYPE_FLAG_BUILTIN_FUN (0x0040) +#define MP_TYPE_FLAG_ITER_IS_GETITER (0x0000) +#define MP_TYPE_FLAG_ITER_IS_ITERNEXT (0x0080) +#define MP_TYPE_FLAG_ITER_IS_CUSTOM (0x0100) +#define MP_TYPE_FLAG_ITER_IS_STREAM (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM) typedef enum { PRINT_STR = 0, @@ -548,6 +560,13 @@ typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t); typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest); typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf); +typedef mp_fun_1_t mp_iternext_fun_t; + +// For MP_TYPE_FLAG_ITER_IS_CUSTOM, the "getiter" slot points to an instance of this type. +typedef struct _mp_getiter_iternext_custom_t { + mp_getiter_fun_t getiter; + mp_iternext_fun_t iternext; +} mp_getiter_iternext_custom_t; // Buffer protocol typedef struct _mp_buffer_info_t { @@ -616,14 +635,17 @@ struct _mp_obj_type_t { // Can return MP_OBJ_NULL if operation not supported. uint8_t slot_index_subscr; - // Corresponds to __iter__ special method. - // Can use the given mp_obj_iter_buf_t to store iterator object, - // otherwise can return a pointer to an object on the heap. - uint8_t slot_index_getiter; - - // Corresponds to __next__ special method. May return MP_OBJ_STOP_ITERATION - // as an optimisation instead of raising StopIteration() with no args. - uint8_t slot_index_iternext; + // This slot's behaviour depends on the MP_TYPE_FLAG_ITER_IS_* flags above. + // - If MP_TYPE_FLAG_ITER_IS_GETITER flag is set, then this corresponds to the __iter__ + // special method (of type mp_getiter_fun_t). Can use the given mp_obj_iter_buf_t + // to store the iterator object, otherwise can return a pointer to an object on the heap. + // - If MP_TYPE_FLAG_ITER_IS_ITERNEXT is set, then this corresponds to __next__ special method. + // May return MP_OBJ_STOP_ITERATION as an optimisation instead of raising StopIteration() + // with no args. The type will implicitly implement getiter as "return self". + // - If MP_TYPE_FLAG_ITER_IS_CUSTOM is set, then this slot must point to an + // mp_getiter_iternext_custom_t instance with both the getiter and iternext fields set. + // - If MP_TYPE_FLAG_ITER_IS_STREAM is set, this this slot should be unset. + uint8_t slot_index_iter; // Implements the buffer protocol if supported by this type. uint8_t slot_index_buffer; @@ -659,8 +681,7 @@ typedef struct _mp_obj_empty_type_t { uint8_t slot_index_binary_op; uint8_t slot_index_attr; uint8_t slot_index_subscr; - uint8_t slot_index_getiter; - uint8_t slot_index_iternext; + uint8_t slot_index_iter; uint8_t slot_index_buffer; uint8_t slot_index_protocol; uint8_t slot_index_parent; @@ -681,15 +702,14 @@ typedef struct _mp_obj_full_type_t { uint8_t slot_index_binary_op; uint8_t slot_index_attr; uint8_t slot_index_subscr; - uint8_t slot_index_getiter; - uint8_t slot_index_iternext; + uint8_t slot_index_iter; uint8_t slot_index_buffer; uint8_t slot_index_protocol; uint8_t slot_index_parent; uint8_t slot_index_locals_dict; // Explicitly add 12 slots. - const void *slots[12]; + const void *slots[11]; } mp_obj_full_type_t; #define MP_TYPE_NULL_MAKE_NEW (NULL) @@ -700,8 +720,7 @@ typedef struct _mp_obj_full_type_t { #define _MP_OBJ_TYPE_SLOT_TYPE_binary_op (mp_binary_op_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_attr (mp_attr_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_subscr (mp_subscr_fun_t) -#define _MP_OBJ_TYPE_SLOT_TYPE_getiter (mp_getiter_fun_t) -#define _MP_OBJ_TYPE_SLOT_TYPE_iternext (mp_fun_1_t) +#define _MP_OBJ_TYPE_SLOT_TYPE_iter (const void *) #define _MP_OBJ_TYPE_SLOT_TYPE_buffer (mp_buffer_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_protocol (const void *) #define _MP_OBJ_TYPE_SLOT_TYPE_parent (const void *) @@ -1162,7 +1181,6 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun); mp_obj_t mp_identity(mp_obj_t self); MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj); -mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf); // module typedef struct _mp_obj_module_t { diff --git a/py/objarray.c b/py/objarray.c index 762a4105c5f5..0d1032929f48 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -574,10 +574,10 @@ STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_ui MP_DEFINE_CONST_OBJ_TYPE( mp_type_array, MP_QSTR_array, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, array_make_new, print, array_print, - getiter, array_iterator_new, + iter, array_iterator_new, unary_op, array_unary_op, binary_op, array_binary_op, subscr, array_subscr, @@ -590,10 +590,10 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_DEFINE_CONST_OBJ_TYPE( mp_type_bytearray, MP_QSTR_bytearray, - MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, bytearray_make_new, print, array_print, - getiter, array_iterator_new, + iter, array_iterator_new, unary_op, array_unary_op, binary_op, array_binary_op, subscr, array_subscr, @@ -618,9 +618,9 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_DEFINE_CONST_OBJ_TYPE( mp_type_memoryview, MP_QSTR_memoryview, - MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, memoryview_make_new, - getiter, array_iterator_new, + iter, array_iterator_new, unary_op, array_unary_op, binary_op, array_binary_op, MEMORYVIEW_TYPE_LOCALS_DICT @@ -676,10 +676,9 @@ STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_array_it, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, array_it_iternext + iter, array_it_iternext ); STATIC mp_obj_t array_iterator_new(mp_obj_t array_in, mp_obj_iter_buf_t *iter_buf) { diff --git a/py/objattrtuple.c b/py/objattrtuple.c index 0d41ee52354a..2e207f4cf0c4 100644 --- a/py/objattrtuple.c +++ b/py/objattrtuple.c @@ -83,7 +83,7 @@ mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *item MP_DEFINE_CONST_OBJ_TYPE( mp_type_attrtuple, MP_QSTR_tuple, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, MP_TYPE_NULL_MAKE_NEW, // reuse tuple to save on a qstr print, mp_obj_attrtuple_print, @@ -91,7 +91,7 @@ MP_DEFINE_CONST_OBJ_TYPE( binary_op, mp_obj_tuple_binary_op, attr, mp_obj_attrtuple_attr, subscr, mp_obj_tuple_subscr, - getiter, mp_obj_tuple_getiter + iter, mp_obj_tuple_getiter ); #endif // MICROPY_PY_ATTRTUPLE diff --git a/py/objdict.c b/py/objdict.c index c65b14caad6c..7755d7b786d4 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -464,10 +464,9 @@ STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict_view_it, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, dict_view_it_iternext + iter, dict_view_it_iternext ); STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in, mp_obj_iter_buf_t *iter_buf) { @@ -517,11 +516,11 @@ STATIC mp_obj_t dict_view_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict_view, MP_QSTR_dict_view, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, MP_TYPE_NULL_MAKE_NEW, print, dict_view_print, binary_op, dict_view_binary_op, - getiter, dict_view_getiter + iter, dict_view_getiter ); STATIC mp_obj_t mp_obj_new_dict_view(mp_obj_t dict, mp_dict_view_kind_t kind) { @@ -592,13 +591,13 @@ STATIC MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict, MP_QSTR_dict, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, mp_obj_dict_make_new, print, dict_print, unary_op, dict_unary_op, binary_op, dict_binary_op, subscr, dict_subscr, - getiter, dict_getiter, + iter, dict_getiter, locals_dict, &dict_locals_dict ); @@ -606,13 +605,13 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_DEFINE_CONST_OBJ_TYPE( mp_type_ordereddict, MP_QSTR_OrderedDict, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, mp_obj_dict_make_new, print, dict_print, unary_op, dict_unary_op, binary_op, dict_binary_op, subscr, dict_subscr, - getiter, dict_getiter, + iter, dict_getiter, parent, &mp_type_dict, locals_dict, &dict_locals_dict ); diff --git a/py/objenumerate.c b/py/objenumerate.c index f4f4ff6ae1d9..eea9e3e381ed 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -70,10 +70,9 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz MP_DEFINE_CONST_OBJ_TYPE( mp_type_enumerate, MP_QSTR_enumerate, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, enumerate_make_new, - iternext, enumerate_iternext, - getiter, mp_identity_getiter + iter, enumerate_iternext ); STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in) { diff --git a/py/objfilter.c b/py/objfilter.c index 2b57300af3df..bfe651f40d03 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -63,10 +63,9 @@ STATIC mp_obj_t filter_iternext(mp_obj_t self_in) { MP_DEFINE_CONST_OBJ_TYPE( mp_type_filter, MP_QSTR_filter, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, filter_make_new, - getiter, mp_identity_getiter, - iternext, filter_iternext + iter, filter_iternext ); #endif // MICROPY_PY_BUILTINS_FILTER diff --git a/py/objgenerator.c b/py/objgenerator.c index a960c237002f..d8515c13ce25 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -370,11 +370,10 @@ STATIC MP_DEFINE_CONST_DICT(gen_instance_locals_dict, gen_instance_locals_dict_t MP_DEFINE_CONST_OBJ_TYPE( mp_type_gen_instance, MP_QSTR_generator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, print, gen_instance_print, unary_op, mp_generic_unary_op, - getiter, mp_identity_getiter, - iternext, gen_instance_iternext, + iter, gen_instance_iternext, locals_dict, &gen_instance_locals_dict ); diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c index ed2dfbbe1f9e..134cbcd6299d 100644 --- a/py/objgetitemiter.c +++ b/py/objgetitemiter.c @@ -59,10 +59,9 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_it, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, it_iternext + iter, it_iternext ); // args are those returned from mp_load_method_maybe (ie either an attribute or a method) diff --git a/py/objlist.c b/py/objlist.c index 5f9e99cc79b2..8d18344ea8a7 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -455,13 +455,13 @@ STATIC MP_DEFINE_CONST_DICT(list_locals_dict, list_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_list, MP_QSTR_list, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, list_make_new, print, list_print, unary_op, list_unary_op, binary_op, list_binary_op, subscr, list_subscr, - getiter, list_getiter, + iter, list_getiter, locals_dict, &list_locals_dict ); diff --git a/py/objmap.c b/py/objmap.c index dc305e21b5cb..115832e387e5 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -66,8 +66,7 @@ STATIC mp_obj_t map_iternext(mp_obj_t self_in) { MP_DEFINE_CONST_OBJ_TYPE( mp_type_map, MP_QSTR_map, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, map_make_new, - getiter, mp_identity_getiter, - iternext, map_iternext + iter, map_iternext ); diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 52536be8b4e9..3b45d8f76f29 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -163,7 +163,7 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t MP_OBJ_TYPE_SET_SLOT(type, binary_op, mp_obj_tuple_binary_op, 2); MP_OBJ_TYPE_SET_SLOT(type, attr, namedtuple_attr, 3); MP_OBJ_TYPE_SET_SLOT(type, subscr, mp_obj_tuple_subscr, 4); - MP_OBJ_TYPE_SET_SLOT(type, getiter, mp_obj_tuple_getiter, 5); + MP_OBJ_TYPE_SET_SLOT(type, iter, mp_obj_tuple_getiter, 5); MP_OBJ_TYPE_SET_SLOT(type, parent, &mp_type_tuple, 6); return MP_OBJ_FROM_PTR(o); } diff --git a/py/objpolyiter.c b/py/objpolyiter.c index 5bc397f6ec3b..7a45b6b73fe6 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -48,10 +48,9 @@ STATIC mp_obj_t polymorph_it_iternext(mp_obj_t self_in) { MP_DEFINE_CONST_OBJ_TYPE( mp_type_polymorph_iter, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, polymorph_it_iternext + iter, polymorph_it_iternext ); #if MICROPY_ENABLE_FINALISER @@ -81,10 +80,9 @@ STATIC MP_DEFINE_CONST_DICT(mp_obj_polymorph_iter_locals_dict, mp_obj_polymorph_ MP_DEFINE_CONST_OBJ_TYPE( mp_type_polymorph_iter_with_finaliser, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, polymorph_it_iternext, + iter, polymorph_it_iternext, locals_dict, &mp_obj_polymorph_iter_locals_dict ); #endif diff --git a/py/objrange.c b/py/objrange.c index 3140504b2bb4..1ad8f6031f29 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -53,10 +53,9 @@ STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) { STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_range_it, MP_QSTR_iterator, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, MP_TYPE_NULL_MAKE_NEW, - getiter, mp_identity_getiter, - iternext, range_it_iternext + iter, range_it_iternext ); STATIC mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step, mp_obj_iter_buf_t *iter_buf) { @@ -232,5 +231,5 @@ MP_DEFINE_CONST_OBJ_TYPE( print, range_print, unary_op, range_unary_op, subscr, range_subscr, - getiter, range_getiter + iter, range_getiter ); diff --git a/py/objreversed.c b/py/objreversed.c index bc1f07ddecc4..e265266d3f12 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -71,10 +71,9 @@ STATIC mp_obj_t reversed_iternext(mp_obj_t self_in) { MP_DEFINE_CONST_OBJ_TYPE( mp_type_reversed, MP_QSTR_reversed, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, reversed_make_new, - getiter, mp_identity_getiter, - iternext, reversed_iternext + iter, reversed_iternext ); #endif // MICROPY_PY_BUILTINS_REVERSED diff --git a/py/objset.c b/py/objset.c index 6f21bf15dfb5..b827f49f40df 100644 --- a/py/objset.c +++ b/py/objset.c @@ -542,12 +542,12 @@ STATIC MP_DEFINE_CONST_DICT(set_locals_dict, set_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_set, MP_QSTR_set, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, set_make_new, print, set_print, unary_op, set_unary_op, binary_op, set_binary_op, - getiter, set_getiter, + iter, set_getiter, locals_dict, &set_locals_dict ); @@ -568,12 +568,12 @@ STATIC MP_DEFINE_CONST_DICT(frozenset_locals_dict, frozenset_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_frozenset, MP_QSTR_frozenset, - MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, set_make_new, print, set_print, unary_op, set_unary_op, binary_op, set_binary_op, - getiter, set_getiter, + iter, set_getiter, locals_dict, &frozenset_locals_dict ); #endif diff --git a/py/objstr.c b/py/objstr.c index d425055559f8..12f6e15d0498 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2151,7 +2151,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, str_print, binary_op, mp_obj_str_binary_op, subscr, bytes_subscr, - getiter, mp_obj_new_str_iterator, + iter, mp_obj_new_str_iterator, buffer, mp_obj_str_get_buffer, locals_dict, &mp_obj_str_locals_dict ); @@ -2166,7 +2166,7 @@ MP_DEFINE_CONST_OBJ_TYPE( print, str_print, binary_op, mp_obj_str_binary_op, subscr, bytes_subscr, - getiter, mp_obj_new_bytes_iterator, + iter, mp_obj_new_bytes_iterator, buffer, mp_obj_str_get_buffer, locals_dict, &mp_obj_bytes_locals_dict ); diff --git a/py/objstringio.c b/py/objstringio.c index 77547f88cf6c..4e19b83999aa 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -247,11 +247,9 @@ STATIC const mp_stream_p_t stringio_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( mp_type_stringio, MP_QSTR_StringIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, stringio_make_new, print, stringio_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &stringio_stream_p, locals_dict, &stringio_locals_dict ); @@ -266,11 +264,9 @@ STATIC const mp_stream_p_t bytesio_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( mp_type_bytesio, MP_QSTR_BytesIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, stringio_make_new, print, stringio_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &bytesio_stream_p, locals_dict, &stringio_locals_dict ); diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 15c59e4e9572..9b28841ecd17 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -232,13 +232,13 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { MP_DEFINE_CONST_OBJ_TYPE( mp_type_str, MP_QSTR_str, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, mp_obj_str_make_new, print, uni_print, unary_op, uni_unary_op, binary_op, mp_obj_str_binary_op, subscr, str_subscr, - getiter, mp_obj_new_str_iterator, + iter, mp_obj_new_str_iterator, buffer, mp_obj_str_get_buffer, locals_dict, &mp_obj_str_locals_dict ); diff --git a/py/objtuple.c b/py/objtuple.c index 01b2fa14885a..485d44c52a8d 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -32,7 +32,7 @@ #include "py/runtime.h" // type check is done on getiter method to allow tuple, namedtuple, attrtuple -#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), getiter) == mp_obj_tuple_getiter) +#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), iter) == mp_obj_tuple_getiter) /******************************************************************************/ /* tuple */ @@ -111,7 +111,7 @@ STATIC mp_obj_t tuple_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t anothe mp_check_self(mp_obj_is_tuple_compatible(self_in)); const mp_obj_type_t *another_type = mp_obj_get_type(another_in); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); - if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(another_type, getiter) != mp_obj_tuple_getiter) { + if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(another_type, iter) != mp_obj_tuple_getiter) { // Slow path for user subclasses another_in = mp_obj_cast_to_native_base(another_in, MP_OBJ_FROM_PTR(&mp_type_tuple)); if (another_in == MP_OBJ_NULL) { @@ -227,13 +227,13 @@ STATIC MP_DEFINE_CONST_DICT(tuple_locals_dict, tuple_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_tuple, MP_QSTR_tuple, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_GETITER, mp_obj_tuple_make_new, print, mp_obj_tuple_print, unary_op, mp_obj_tuple_unary_op, binary_op, mp_obj_tuple_binary_op, subscr, mp_obj_tuple_subscr, - getiter, mp_obj_tuple_getiter, + iter, mp_obj_tuple_getiter, locals_dict, &tuple_locals_dict ); diff --git a/py/objtype.c b/py/objtype.c index 5b4e375bcc48..183dce071ee9 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -142,7 +142,10 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t // this should not be applied to class types, as will result in extra // lookup either. if (lookup->slot_offset != 0 && mp_obj_is_native_type(type)) { - if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset)) { + // Check if there is a non-zero value in the specified slot index, + // with a special case for getiter where the slot won't be set + // for MP_TYPE_FLAG_ITER_IS_STREAM. + if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset) || (lookup->slot_offset == MP_OBJ_TYPE_OFFSETOF_SLOT(iter) && type->flags & MP_TYPE_FLAG_ITER_IS_STREAM)) { DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n", lookup->slot_offset, qstr_str(lookup->attr)); lookup->dest[0] = MP_OBJ_SENTINEL; @@ -889,7 +892,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) struct class_lookup_data lookup = { .obj = self, .attr = MP_QSTR___iter__, - .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(getiter), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(iter), .dest = member, .is_type = false, }; @@ -898,10 +901,14 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) return MP_OBJ_NULL; } else if (member[0] == MP_OBJ_SENTINEL) { const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]); - if (iter_buf == NULL) { - iter_buf = m_new_obj(mp_obj_iter_buf_t); + if (type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) { + return self->subobj[0]; + } else { + if (iter_buf == NULL) { + iter_buf = m_new_obj(mp_obj_iter_buf_t); + } + return ((mp_getiter_fun_t)MP_OBJ_TYPE_GET_SLOT(type, iter))(self->subobj[0], iter_buf); } - return MP_OBJ_TYPE_GET_SLOT(type, getiter)(self->subobj[0], iter_buf); } else { return mp_call_method_n_kw(0, 0, member); } @@ -1122,7 +1129,9 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // Basic validation of base classes uint16_t base_flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE - | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST; + | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE + | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST + | MP_TYPE_FLAG_ITER_IS_GETITER; size_t bases_len; mp_obj_t *bases_items; mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); @@ -1167,7 +1176,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 3); MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 4); MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 5); - MP_OBJ_TYPE_SET_SLOT(o, getiter, mp_obj_instance_getiter, 6); + MP_OBJ_TYPE_SET_SLOT(o, iter, mp_obj_instance_getiter, 6); // MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented) MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7); diff --git a/py/objzip.c b/py/objzip.c index 0ceafd97f240..34d73465ef2b 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -69,8 +69,7 @@ STATIC mp_obj_t zip_iternext(mp_obj_t self_in) { MP_DEFINE_CONST_OBJ_TYPE( mp_type_zip, MP_QSTR_zip, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, zip_make_new, - getiter, mp_identity_getiter, - iternext, zip_iternext + iter, zip_iternext ); diff --git a/py/runtime.c b/py/runtime.c index d0e504a3d096..ec628bfe14b4 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -61,6 +61,8 @@ const mp_obj_module_t mp_module___main__ = { MP_REGISTER_MODULE(MP_QSTR___main__, mp_module___main__); +#define TYPE_HAS_ITERNEXT(type) (type->flags & (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM | MP_TYPE_FLAG_ITER_IS_STREAM)) + void mp_init(void) { qstr_init(); @@ -1167,7 +1169,7 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { } #endif - if (attr == MP_QSTR___next__ && MP_OBJ_TYPE_HAS_SLOT(type, iternext)) { + if (attr == MP_QSTR___next__ && TYPE_HAS_ITERNEXT(type)) { dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj); dest[1] = obj; return; @@ -1260,21 +1262,26 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { assert(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in); + // Most types that use iternext just use the identity getiter. We handle this case explicitly + // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used. + if ((type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) == MP_TYPE_FLAG_ITER_IS_ITERNEXT || (type->flags & MP_TYPE_FLAG_ITER_IS_STREAM) == MP_TYPE_FLAG_ITER_IS_STREAM) { + return o_in; + } - if (MP_OBJ_TYPE_HAS_SLOT(type, getiter)) { - // Check for native getiter which is the identity. We handle this case explicitly - // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used. - if (MP_OBJ_TYPE_GET_SLOT(type, getiter) == mp_identity_getiter) { - return o_in; - } - + if (MP_OBJ_TYPE_HAS_SLOT(type, iter)) { // check for native getiter (corresponds to __iter__) - if (iter_buf == NULL && MP_OBJ_TYPE_GET_SLOT(type, getiter) != mp_obj_instance_getiter) { + if (iter_buf == NULL && MP_OBJ_TYPE_GET_SLOT(type, iter) != mp_obj_instance_getiter) { // if caller did not provide a buffer then allocate one on the heap // mp_obj_instance_getiter is special, it will allocate only if needed iter_buf = m_new_obj(mp_obj_iter_buf_t); } - mp_obj_t iter = MP_OBJ_TYPE_GET_SLOT(type, getiter)(o_in, iter_buf); + mp_getiter_fun_t getiter; + if (type->flags & MP_TYPE_FLAG_ITER_IS_CUSTOM) { + getiter = ((mp_getiter_iternext_custom_t *)MP_OBJ_TYPE_GET_SLOT(type, iter))->getiter; + } else { + getiter = (mp_getiter_fun_t)MP_OBJ_TYPE_GET_SLOT(type, iter); + } + mp_obj_t iter = getiter(o_in, iter_buf); if (iter != MP_OBJ_NULL) { return iter; } @@ -1302,13 +1309,26 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { } +STATIC mp_fun_1_t type_get_iternext(const mp_obj_type_t *type) { + if ((type->flags & MP_TYPE_FLAG_ITER_IS_STREAM) == MP_TYPE_FLAG_ITER_IS_STREAM) { + mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self); + return mp_stream_unbuffered_iter; + } else if (type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) { + return (mp_fun_1_t)MP_OBJ_TYPE_GET_SLOT(type, iter); + } else if (type->flags & MP_TYPE_FLAG_ITER_IS_CUSTOM) { + return ((mp_getiter_iternext_custom_t *)MP_OBJ_TYPE_GET_SLOT(type, iter))->iternext; + } else { + return NULL; + } +} + // may return MP_OBJ_STOP_ITERATION as an optimisation instead of raise StopIteration() // may also raise StopIteration() mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { const mp_obj_type_t *type = mp_obj_get_type(o_in); - if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) { + if (TYPE_HAS_ITERNEXT(type)) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; - return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in); + return type_get_iternext(type)(o_in); } else { // check for __next__ method mp_obj_t dest[2]; @@ -1332,9 +1352,9 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { mp_obj_t mp_iternext(mp_obj_t o_in) { MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext const mp_obj_type_t *type = mp_obj_get_type(o_in); - if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) { + if (TYPE_HAS_ITERNEXT(type)) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; - return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in); + return type_get_iternext(type)(o_in); } else { // check for __next__ method mp_obj_t dest[2]; @@ -1372,9 +1392,9 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val); } - if (MP_OBJ_TYPE_HAS_SLOT(type, iternext) && send_value == mp_const_none) { + if (TYPE_HAS_ITERNEXT(type) && send_value == mp_const_none) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; - mp_obj_t ret = MP_OBJ_TYPE_GET_SLOT(type, iternext)(self_in); + mp_obj_t ret = type_get_iternext(type)(self_in); *ret_val = ret; if (ret != MP_OBJ_STOP_ITERATION) { return MP_VM_RETURN_YIELD; diff --git a/shared/runtime/sys_stdio_mphal.c b/shared/runtime/sys_stdio_mphal.c index 6d43425e298f..325f93dde1d8 100644 --- a/shared/runtime/sys_stdio_mphal.c +++ b/shared/runtime/sys_stdio_mphal.c @@ -126,11 +126,9 @@ STATIC const mp_stream_p_t stdio_obj_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( stdio_obj_type, MP_QSTR_FileIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, stdio_obj_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &stdio_obj_stream_p, locals_dict, &stdio_locals_dict ); @@ -162,11 +160,9 @@ STATIC const mp_stream_p_t stdio_buffer_obj_stream_p = { STATIC MP_DEFINE_CONST_OBJ_TYPE( stdio_buffer_obj_type, MP_QSTR_FileIO, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_ITER_IS_STREAM, MP_TYPE_NULL_MAKE_NEW, print, stdio_obj_print, - getiter, mp_identity_getiter, - iternext, mp_stream_unbuffered_iter, protocol, &stdio_buffer_obj_stream_p, locals_dict, &stdio_locals_dict ); diff --git a/tests/basics/io_stringio_base.py b/tests/basics/io_stringio_base.py new file mode 100644 index 000000000000..dffc879074a7 --- /dev/null +++ b/tests/basics/io_stringio_base.py @@ -0,0 +1,24 @@ +# Checks that an instance type inheriting from a native base that uses +# MP_TYPE_FLAG_ITER_IS_STREAM will still have a getiter. + +try: + import uio as io +except ImportError: + import io + +a = io.StringIO() +a.write("hello\nworld\nmicro\npython\n") +a.seek(0) + +for line in a: + print(line) + +class X(io.StringIO): + pass + +b = X() +b.write("hello\nworld\nmicro\npython\n") +b.seek(0) + +for line in b: + print(line) From 94beeabd2ee179d587942046555833e022241f24 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 17 Sep 2022 00:31:23 +1000 Subject: [PATCH 1753/4290] py/obj: Convert make_new into a mp_obj_type_t slot. Instead of being an explicit field, it's now a slot like all the other methods. This is a marginal code size improvement because most types have a make_new (100/138 on PYBV11), however it improves consistency in how types are declared, removing the special case for make_new. Signed-off-by: Jim Mussared --- drivers/ninaw10/nina_wifi_bsp.c | 2 +- examples/natmod/framebuf/framebuf.c | 6 +- examples/natmod/uzlib/uzlib.c | 6 +- extmod/machine_i2c.c | 2 +- extmod/machine_i2c.h | 2 +- extmod/machine_mem.c | 1 - extmod/machine_pinbase.c | 2 +- extmod/machine_pwm.c | 2 +- extmod/machine_signal.c | 2 +- extmod/machine_spi.c | 2 +- extmod/machine_spi.h | 2 +- extmod/modbluetooth.c | 4 +- extmod/modbtree.c | 1 - extmod/modframebuf.c | 2 +- extmod/modlwip.c | 4 +- extmod/moduasyncio.c | 4 +- extmod/moducryptolib.c | 2 +- extmod/moductypes.c | 2 +- extmod/moduhashlib.c | 6 +- extmod/modure.c | 2 - extmod/moduselect.c | 1 - extmod/modusocket.c | 2 +- extmod/modussl_axtls.c | 1 - extmod/modussl_mbedtls.c | 1 - extmod/modutimeq.c | 2 +- extmod/moduwebsocket.c | 2 +- extmod/moduzlib.c | 2 +- extmod/modwebrepl.c | 2 +- extmod/network_cyw43.c | 2 +- extmod/network_ninaw10.c | 4 +- extmod/network_wiznet5k.c | 6 +- extmod/vfs.c | 6 +- extmod/vfs_fat.c | 2 +- extmod/vfs_fat_file.c | 2 - extmod/vfs_lfsx.c | 2 +- extmod/vfs_lfsx_file.c | 2 - extmod/vfs_posix.c | 2 +- extmod/vfs_posix_file.c | 2 - ports/cc3200/misc/mpirq.c | 1 - ports/cc3200/mods/modnetwork.c | 2 +- ports/cc3200/mods/moduhashlib.c | 4 +- ports/cc3200/mods/modusocket.c | 2 +- ports/cc3200/mods/modwlan.c | 2 +- ports/cc3200/mods/pybadc.c | 3 +- ports/cc3200/mods/pybflash.c | 2 +- ports/cc3200/mods/pybi2c.c | 2 +- ports/cc3200/mods/pybpin.c | 3 +- ports/cc3200/mods/pybrtc.c | 2 +- ports/cc3200/mods/pybsd.c | 2 +- ports/cc3200/mods/pybsleep.c | 3 +- ports/cc3200/mods/pybspi.c | 2 +- ports/cc3200/mods/pybtimer.c | 3 +- ports/cc3200/mods/pybuart.c | 2 +- ports/cc3200/mods/pybwdt.c | 2 +- ports/esp32/esp32_nvs.c | 2 +- ports/esp32/esp32_partition.c | 2 +- ports/esp32/esp32_rmt.c | 2 +- ports/esp32/esp32_ulp.c | 2 +- ports/esp32/machine_adc.c | 2 +- ports/esp32/machine_adcblock.c | 2 +- ports/esp32/machine_dac.c | 2 +- ports/esp32/machine_hw_spi.c | 2 +- ports/esp32/machine_i2c.c | 2 +- ports/esp32/machine_i2s.c | 2 +- ports/esp32/machine_pin.c | 3 +- ports/esp32/machine_rtc.c | 2 +- ports/esp32/machine_sdcard.c | 2 +- ports/esp32/machine_timer.c | 2 +- ports/esp32/machine_touchpad.c | 2 +- ports/esp32/machine_uart.c | 2 +- ports/esp32/machine_wdt.c | 2 +- ports/esp32/modsocket.c | 2 +- ports/esp32/network_lan.c | 1 - ports/esp32/network_ppp.c | 1 - ports/esp32/network_wlan.c | 1 - ports/esp8266/machine_adc.c | 2 +- ports/esp8266/machine_hspi.c | 2 +- ports/esp8266/machine_pin.c | 3 +- ports/esp8266/machine_rtc.c | 2 +- ports/esp8266/machine_uart.c | 2 +- ports/esp8266/machine_wdt.c | 2 +- ports/esp8266/main.c | 2 +- ports/esp8266/modmachine.c | 2 +- ports/esp8266/modnetwork.c | 1 - ports/mimxrt/machine_adc.c | 2 +- ports/mimxrt/machine_i2c.c | 2 +- ports/mimxrt/machine_i2s.c | 2 +- ports/mimxrt/machine_led.c | 2 +- ports/mimxrt/machine_pin.c | 6 +- ports/mimxrt/machine_rtc.c | 2 +- ports/mimxrt/machine_sdcard.c | 2 +- ports/mimxrt/machine_spi.c | 2 +- ports/mimxrt/machine_timer.c | 2 +- ports/mimxrt/machine_uart.c | 2 +- ports/mimxrt/machine_wdt.c | 2 +- ports/mimxrt/mimxrt_flash.c | 2 +- ports/mimxrt/network_lan.c | 2 +- ports/nrf/boards/microbit/modules/iters.c | 1 - .../boards/microbit/modules/microbitdisplay.c | 1 - .../boards/microbit/modules/microbitimage.c | 4 +- ports/nrf/main.c | 2 +- ports/nrf/modules/board/led.c | 2 +- ports/nrf/modules/machine/adc.c | 2 +- ports/nrf/modules/machine/i2c.c | 2 +- ports/nrf/modules/machine/pin.c | 3 +- ports/nrf/modules/machine/pwm.c | 2 +- ports/nrf/modules/machine/rtcounter.c | 2 +- ports/nrf/modules/machine/spi.c | 2 +- ports/nrf/modules/machine/temp.c | 2 +- ports/nrf/modules/machine/timer.c | 2 +- ports/nrf/modules/machine/uart.c | 2 +- ports/nrf/modules/nrf/flashbdev.c | 2 +- .../modules/ubluepy/ubluepy_characteristic.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_constants.c | 2 - ports/nrf/modules/ubluepy/ubluepy_delegate.c | 2 +- .../nrf/modules/ubluepy/ubluepy_descriptor.c | 2 +- .../nrf/modules/ubluepy/ubluepy_peripheral.c | 2 +- .../nrf/modules/ubluepy/ubluepy_scan_entry.c | 1 - ports/nrf/modules/ubluepy/ubluepy_scanner.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_service.c | 2 +- ports/nrf/modules/ubluepy/ubluepy_uuid.c | 2 +- ports/nrf/modules/uos/microbitfs.c | 2 - ports/nrf/pin_named_pins.c | 2 - ports/pic16bit/modpybled.c | 2 +- ports/pic16bit/modpybswitch.c | 2 +- ports/renesas-ra/extint.c | 2 +- ports/renesas-ra/led.c | 2 +- ports/renesas-ra/machine_adc.c | 2 +- ports/renesas-ra/machine_i2c.c | 2 +- ports/renesas-ra/machine_pin.c | 4 +- ports/renesas-ra/machine_rtc.c | 2 +- ports/renesas-ra/machine_spi.c | 2 +- ports/renesas-ra/machine_timer.c | 2 +- ports/renesas-ra/machine_uart.c | 2 +- ports/renesas-ra/main.c | 2 +- ports/renesas-ra/storage.c | 2 +- ports/renesas-ra/timer.c | 3 +- ports/renesas-ra/usrsw.c | 2 +- ports/rp2/machine_adc.c | 2 +- ports/rp2/machine_i2c.c | 2 +- ports/rp2/machine_i2s.c | 2 +- ports/rp2/machine_pin.c | 2 +- ports/rp2/machine_rtc.c | 2 +- ports/rp2/machine_spi.c | 2 +- ports/rp2/machine_timer.c | 2 +- ports/rp2/machine_uart.c | 2 +- ports/rp2/machine_wdt.c | 2 +- ports/rp2/mpbthciport.c | 2 +- ports/rp2/rp2_flash.c | 2 +- ports/rp2/rp2_pio.c | 4 +- ports/samd/machine_led.c | 2 +- ports/samd/machine_pin.c | 2 +- ports/samd/samd_flash.c | 2 +- ports/stm32/accel.c | 2 +- ports/stm32/adc.c | 4 +- ports/stm32/boards/LEGO_HUB_NO6/cc2564.c | 2 +- ports/stm32/dac.c | 2 +- ports/stm32/extint.c | 2 +- ports/stm32/lcd.c | 2 +- ports/stm32/led.c | 2 +- ports/stm32/machine_adc.c | 2 +- ports/stm32/machine_i2c.c | 2 +- ports/stm32/machine_i2s.c | 2 +- ports/stm32/machine_spi.c | 2 +- ports/stm32/machine_timer.c | 2 +- ports/stm32/machine_uart.c | 2 +- ports/stm32/main.c | 2 +- ports/stm32/network_lan.c | 2 +- ports/stm32/pin.c | 3 +- ports/stm32/pin_named_pins.c | 2 - ports/stm32/pyb_can.c | 2 +- ports/stm32/pyb_i2c.c | 2 +- ports/stm32/pyb_spi.c | 2 +- ports/stm32/rtc.c | 2 +- ports/stm32/sdcard.c | 4 +- ports/stm32/servo.c | 2 +- ports/stm32/storage.c | 2 +- ports/stm32/timer.c | 3 +- ports/stm32/usb.c | 4 +- ports/stm32/usrsw.c | 2 +- ports/stm32/wdt.c | 2 +- ports/teensy/led.c | 2 +- ports/teensy/timer.c | 3 +- ports/teensy/uart.c | 2 +- ports/unix/coverage.c | 2 - ports/unix/main.c | 2 +- ports/unix/modffi.c | 8 +-- ports/unix/modjni.c | 3 - ports/unix/moduselect.c | 1 - ports/unix/modusocket.c | 2 +- ports/zephyr/machine_i2c.c | 2 +- ports/zephyr/machine_pin.c | 2 +- ports/zephyr/machine_spi.c | 2 +- ports/zephyr/machine_uart.c | 2 +- ports/zephyr/main.c | 4 +- ports/zephyr/modusocket.c | 2 +- ports/zephyr/modzsensor.c | 2 +- ports/zephyr/zephyr_storage.c | 4 +- py/builtinevex.c | 3 +- py/dynruntime.h | 2 +- py/modbuiltins.c | 2 +- py/modio.c | 4 +- py/modthread.c | 1 - py/obj.h | 56 +++++++++---------- py/objarray.c | 7 +-- py/objattrtuple.c | 1 - py/objbool.c | 2 +- py/objboundmeth.c | 1 - py/objcell.c | 2 +- py/objclosure.c | 1 - py/objcomplex.c | 3 +- py/objdeque.c | 2 +- py/objdict.c | 6 +- py/objenumerate.c | 2 +- py/objexcept.c | 12 ++-- py/objexcept.h | 3 +- py/objfilter.c | 2 +- py/objfloat.c | 3 +- py/objfun.c | 13 ++--- py/objgenerator.c | 3 - py/objgetitemiter.c | 1 - py/objint.c | 2 +- py/objlist.c | 4 +- py/objlist.h | 1 + py/objmap.c | 2 +- py/objmodule.c | 1 - py/objnamedtuple.c | 16 +++--- py/objnamedtuple.h | 4 +- py/objnone.c | 1 - py/objobject.c | 2 +- py/objpolyiter.c | 2 - py/objproperty.c | 2 +- py/objrange.c | 3 +- py/objreversed.c | 2 +- py/objset.c | 4 +- py/objsingleton.c | 2 +- py/objslice.c | 1 - py/objstr.c | 6 +- py/objstringio.c | 4 +- py/objstrunicode.c | 2 +- py/objtuple.c | 2 +- py/objtype.c | 56 +++++++++---------- py/objtype.h | 4 +- py/objzip.c | 2 +- py/profile.c | 2 - py/runtime.c | 1 - shared/runtime/mpirq.c | 1 - shared/runtime/sys_stdio_mphal.c | 2 - 248 files changed, 316 insertions(+), 397 deletions(-) diff --git a/drivers/ninaw10/nina_wifi_bsp.c b/drivers/ninaw10/nina_wifi_bsp.c index d5b1308536af..c65fb111fb10 100644 --- a/drivers/ninaw10/nina_wifi_bsp.c +++ b/drivers/ninaw10/nina_wifi_bsp.c @@ -73,7 +73,7 @@ int nina_bsp_init(void) { MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_BAUDRATE), }; - MP_STATE_PORT(mp_wifi_spi) = machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 0, args); + MP_STATE_PORT(mp_wifi_spi) = MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, make_new)((mp_obj_t)&machine_spi_type, 2, 0, args); return 0; } diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c index 4c557294719d..32b67eabcf84 100644 --- a/examples/natmod/framebuf/framebuf.c +++ b/examples/natmod/framebuf/framebuf.c @@ -20,8 +20,8 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a mp_type_framebuf.base.type = (void*)&mp_type_type; mp_type_framebuf.name = MP_QSTR_FrameBuffer; - mp_type_framebuf.make_new = framebuf_make_new; - MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, buffer, framebuf_get_buffer, 0); + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, make_new, framebuf_make_new, 0); + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, buffer, framebuf_get_buffer, 1); framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; @@ -33,7 +33,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; framebuf_locals_dict_table[10] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; - MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, locals_dict, (void*)&framebuf_locals_dict, 1); + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, locals_dict, (void*)&framebuf_locals_dict, 2); mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj)); diff --git a/examples/natmod/uzlib/uzlib.c b/examples/natmod/uzlib/uzlib.c index 469452e8f843..9cf58b10e78e 100644 --- a/examples/natmod/uzlib/uzlib.c +++ b/examples/natmod/uzlib/uzlib.c @@ -20,12 +20,12 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a decompio_type.base.type = mp_fun_table.type_type; decompio_type.name = MP_QSTR_DecompIO; - decompio_type.make_new = &decompio_make_new; - MP_OBJ_TYPE_SET_SLOT(&decompio_type, protocol, &decompio_stream_p, 0); + MP_OBJ_TYPE_SET_SLOT(&decompio_type, make_new, &decompio_make_new, 0); + MP_OBJ_TYPE_SET_SLOT(&decompio_type, protocol, &decompio_stream_p, 1); decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) }; decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) }; decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) }; - MP_OBJ_TYPE_SET_SLOT(&decompio_type, locals_dict, (void*)&decompio_locals_dict, 1); + MP_OBJ_TYPE_SET_SLOT(&decompio_type, locals_dict, (void*)&decompio_locals_dict, 2); mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib)); mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj)); diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index bb7ade6fcf57..3563b3243c36 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -734,7 +734,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_machine_soft_i2c_type, MP_QSTR_SoftI2C, MP_TYPE_FLAG_NONE, - mp_machine_soft_i2c_make_new, + make_new, mp_machine_soft_i2c_make_new, print, mp_machine_soft_i2c_print, protocol, &mp_machine_soft_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/extmod/machine_i2c.h b/extmod/machine_i2c.h index a3363d4c341c..600145bfedf4 100644 --- a/extmod/machine_i2c.h +++ b/extmod/machine_i2c.h @@ -38,7 +38,7 @@ --n_args; \ ++all_args; \ } \ - return mp_machine_soft_i2c_type.make_new(&mp_machine_soft_i2c_type, n_args, n_kw, all_args); \ + return MP_OBJ_TYPE_GET_SLOT(&mp_machine_soft_i2c_type, make_new)(&mp_machine_soft_i2c_type, n_args, n_kw, all_args); \ } \ } while (0) diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index 422e99d3ce42..f27356e02836 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -105,7 +105,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_mem_type, MP_QSTR_mem, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, machine_mem_print, subscr, machine_mem_subscr ); diff --git a/extmod/machine_pinbase.c b/extmod/machine_pinbase.c index 617dd1280c78..8607e6ed3de9 100644 --- a/extmod/machine_pinbase.c +++ b/extmod/machine_pinbase.c @@ -81,7 +81,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pinbase_type, MP_QSTR_PinBase, MP_TYPE_FLAG_NONE, - pinbase_make_new, + make_new, pinbase_make_new, protocol, &pinbase_pin_p ); diff --git a/extmod/machine_pwm.c b/extmod/machine_pwm.c index f12f70a2d14d..220d34d7da58 100644 --- a/extmod/machine_pwm.c +++ b/extmod/machine_pwm.c @@ -136,7 +136,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pwm_type, MP_QSTR_PWM, MP_TYPE_FLAG_NONE, - mp_machine_pwm_make_new, + make_new, mp_machine_pwm_make_new, print, mp_machine_pwm_print, locals_dict, &machine_pwm_locals_dict ); diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c index 49ee6dfb4abc..7922ed70771e 100644 --- a/extmod/machine_signal.c +++ b/extmod/machine_signal.c @@ -176,7 +176,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_signal_type, MP_QSTR_Signal, MP_TYPE_FLAG_NONE, - signal_make_new, + make_new, signal_make_new, call, signal_call, protocol, &signal_pin_p, locals_dict, &signal_locals_dict diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index 54f1964e2193..bb35cff38e61 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -255,7 +255,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_machine_soft_spi_type, MP_QSTR_SoftSPI, MP_TYPE_FLAG_NONE, - mp_machine_soft_spi_make_new, + make_new, mp_machine_soft_spi_make_new, print, mp_machine_soft_spi_print, protocol, &mp_machine_soft_spi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h index ca92c719a8b5..93ee8d00ca32 100644 --- a/extmod/machine_spi.h +++ b/extmod/machine_spi.h @@ -39,7 +39,7 @@ --n_args; \ ++all_args; \ } \ - return mp_machine_soft_spi_type.make_new(&mp_machine_soft_spi_type, n_args, n_kw, all_args); \ + return MP_OBJ_TYPE_GET_SLOT(&mp_machine_soft_spi_type, make_new)(&mp_machine_soft_spi_type, n_args, n_kw, all_args); \ } \ } while (0) diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 2e058fc7deb2..9c168483ba45 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -244,7 +244,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_bluetooth_uuid, MP_QSTR_UUID, MP_TYPE_FLAG_NONE, - bluetooth_uuid_make_new, + make_new, bluetooth_uuid_make_new, unary_op, bluetooth_uuid_unary_op, binary_op, bluetooth_uuid_binary_op, print, bluetooth_uuid_print, @@ -980,7 +980,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_bluetooth_ble, MP_QSTR_BLE, MP_TYPE_FLAG_NONE, - bluetooth_ble_make_new, + make_new, bluetooth_ble_make_new, locals_dict, &bluetooth_ble_locals_dict ); diff --git a/extmod/modbtree.c b/extmod/modbtree.c index f21fe3ff9417..2da65a2c7aff 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -328,7 +328,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( btree_type, MP_QSTR_btree, MP_TYPE_FLAG_ITER_IS_CUSTOM, - MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module print, btree_print, iter, &btree_getiter_iternext, diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 5347be564366..e7825b59128e 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -833,7 +833,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_framebuf, MP_QSTR_FrameBuffer, MP_TYPE_FLAG_NONE, - framebuf_make_new, + make_new, framebuf_make_new, buffer, framebuf_get_buffer, locals_dict, &framebuf_locals_dict ); diff --git a/extmod/modlwip.c b/extmod/modlwip.c index 2f5da36f4084..f64a5a6250ba 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -181,7 +181,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( lwip_slip_type, MP_QSTR_slip, MP_TYPE_FLAG_NONE, - lwip_slip_make_new, + make_new, lwip_slip_make_new, locals_dict, &lwip_slip_locals_dict ); @@ -1599,7 +1599,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( lwip_socket_type, MP_QSTR_socket, MP_TYPE_FLAG_NONE, - lwip_socket_make_new, + make_new, lwip_socket_make_new, print, lwip_socket_print, protocol, &lwip_socket_stream_p, locals_dict, &lwip_socket_locals_dict diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c index b0eb8b6509c8..021e0da1be2c 100644 --- a/extmod/moduasyncio.c +++ b/extmod/moduasyncio.c @@ -148,7 +148,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( task_queue_type, MP_QSTR_TaskQueue, MP_TYPE_FLAG_NONE, - task_queue_make_new, + make_new, task_queue_make_new, locals_dict, &task_queue_locals_dict ); @@ -296,7 +296,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( task_type, MP_QSTR_Task, MP_TYPE_FLAG_ITER_IS_CUSTOM, - task_make_new, + make_new, task_make_new, attr, task_attr, iter, &task_getiter_iternext ); diff --git a/extmod/moducryptolib.c b/extmod/moducryptolib.c index e4625c21a878..fc3fcfd90d90 100644 --- a/extmod/moducryptolib.c +++ b/extmod/moducryptolib.c @@ -352,7 +352,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ucryptolib_aes_type, MP_QSTR_aes, MP_TYPE_FLAG_NONE, - ucryptolib_aes_make_new, + make_new, ucryptolib_aes_make_new, locals_dict, &ucryptolib_aes_locals_dict ); diff --git a/extmod/moductypes.c b/extmod/moductypes.c index a9ad500c2d1a..15c36290a9f0 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -638,7 +638,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( uctypes_struct_type, MP_QSTR_struct, MP_TYPE_FLAG_NONE, - uctypes_struct_make_new, + make_new, uctypes_struct_make_new, print, uctypes_struct_print, attr, uctypes_struct_attr, subscr, uctypes_struct_subscr, diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 9535e00b406d..64e15c444df8 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -161,7 +161,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( uhashlib_sha256_type, MP_QSTR_sha256, MP_TYPE_FLAG_NONE, - uhashlib_sha256_make_new, + make_new, uhashlib_sha256_make_new, locals_dict, &uhashlib_sha256_locals_dict ); #endif @@ -255,7 +255,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( uhashlib_sha1_type, MP_QSTR_sha1, MP_TYPE_FLAG_NONE, - uhashlib_sha1_make_new, + make_new, uhashlib_sha1_make_new, locals_dict, &uhashlib_sha1_locals_dict ); #endif @@ -349,7 +349,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( uhashlib_md5_type, MP_QSTR_md5, MP_TYPE_FLAG_NONE, - uhashlib_md5_make_new, + make_new, uhashlib_md5_make_new, locals_dict, &uhashlib_md5_locals_dict ); #endif // MICROPY_PY_UHASHLIB_MD5 diff --git a/extmod/modure.c b/extmod/modure.c index c0114c14fd57..801e5df89779 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -183,7 +183,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( match_type, MP_QSTR_match, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, match_print, locals_dict, &match_locals_dict ); @@ -417,7 +416,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( re_type, MP_QSTR_ure, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, re_print, locals_dict, &re_locals_dict ); diff --git a/extmod/moduselect.c b/extmod/moduselect.c index 58bd1169a945..128154a4b6d9 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -340,7 +340,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_poll, MP_QSTR_poll, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, poll_iternext, locals_dict, &poll_locals_dict ); diff --git a/extmod/modusocket.c b/extmod/modusocket.c index fc16d7e27030..194ee6899ede 100644 --- a/extmod/modusocket.c +++ b/extmod/modusocket.c @@ -532,7 +532,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( socket_type, MP_QSTR_socket, MP_TYPE_FLAG_NONE, - socket_make_new, + make_new, socket_make_new, protocol, &socket_stream_p, locals_dict, &socket_locals_dict, print, socket_print diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c index a6d606d560eb..2eae46504835 100644 --- a/extmod/modussl_axtls.c +++ b/extmod/modussl_axtls.c @@ -318,7 +318,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ussl_socket_type, MP_QSTR_ussl, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module print, ussl_socket_print, protocol, &ussl_socket_stream_p, diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 50712980ba04..95cf12c975af 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -396,7 +396,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ussl_socket_type, MP_QSTR_ussl, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, // Save on qstr's, reuse same as for module print, socket_print, protocol, &ussl_socket_stream_p, diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index 1a7575adc9e5..1a38104eafcd 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -213,7 +213,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( utimeq_type, MP_QSTR_utimeq, MP_TYPE_FLAG_NONE, - utimeq_make_new, + make_new, utimeq_make_new, unary_op, utimeq_unary_op, locals_dict, &utimeq_locals_dict ); diff --git a/extmod/moduwebsocket.c b/extmod/moduwebsocket.c index c6be50d0e15a..9b12fc86358c 100644 --- a/extmod/moduwebsocket.c +++ b/extmod/moduwebsocket.c @@ -294,7 +294,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( websocket_type, MP_QSTR_websocket, MP_TYPE_FLAG_NONE, - websocket_make_new, + make_new, websocket_make_new, protocol, &websocket_stream_p, locals_dict, &websocket_locals_dict ); diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 533168d0b054..14d15321a3c1 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -144,7 +144,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( decompio_type, MP_QSTR_DecompIO, MP_TYPE_FLAG_NONE, - decompio_make_new, + make_new, decompio_make_new, protocol, &decompio_stream_p, locals_dict, &decompio_locals_dict ); diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index fc5ca35ea033..d86f35896234 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -346,7 +346,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( webrepl_type, MP_QSTR__webrepl, MP_TYPE_FLAG_NONE, - webrepl_make_new, + make_new, webrepl_make_new, protocol, &webrepl_stream_p, locals_dict, &webrepl_locals_dict ); diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index 329ba53ef51a..87d9b9f61428 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -500,7 +500,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_network_cyw43_type, MP_QSTR_CYW43, MP_TYPE_FLAG_NONE, - network_cyw43_make_new, + make_new, network_cyw43_make_new, print, network_cyw43_print, locals_dict, &network_cyw43_locals_dict ); diff --git a/extmod/network_ninaw10.c b/extmod/network_ninaw10.c index 806819648d2e..f4cc0b22244d 100644 --- a/extmod/network_ninaw10.c +++ b/extmod/network_ninaw10.c @@ -159,7 +159,7 @@ STATIC mp_obj_t network_ninaw10_active(size_t n_args, const mp_obj_t *args) { MP_OBJ_NEW_QSTR(MP_QSTR_freq), MP_OBJ_NEW_SMALL_INT(10), MP_OBJ_NEW_QSTR(MP_QSTR_callback), MP_OBJ_FROM_PTR(&network_ninaw10_timer_callback_obj), }; - MP_STATE_PORT(mp_wifi_timer) = machine_timer_type.make_new((mp_obj_t)&machine_timer_type, 0, 2, timer_args); + MP_STATE_PORT(mp_wifi_timer) = MP_OBJ_TYPE_GET_SLOT(&machine_timer_type, make_new)((mp_obj_t)&machine_timer_type, 0, 2, timer_args); } } else { nina_deinit(); @@ -778,7 +778,7 @@ STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE( mod_network_nic_type_nina_base, MP_QSTR_nina, MP_TYPE_FLAG_NONE, - network_ninaw10_make_new, + make_new, network_ninaw10_make_new, locals_dict, &nina_locals_dict ); diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index 82f836f69184..af2014508127 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -708,7 +708,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size MP_ROM_QSTR(MP_QSTR_miso), mp_pin_make_new(NULL, 1, 0, &miso_obj), MP_ROM_QSTR(MP_QSTR_mosi), mp_pin_make_new(NULL, 1, 0, &mosi_obj), }; - spi = MP_OBJ_TO_PTR(machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 3, args)); + spi = MP_OBJ_TO_PTR(MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, make_new)((mp_obj_t)&machine_spi_type, 2, 3, args)); cs = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_CS)})); rst = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_RST)})); @@ -1020,7 +1020,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mod_network_nic_type_wiznet5k, MP_QSTR_WIZNET5K, MP_TYPE_FLAG_NONE, - wiznet5k_make_new, + make_new, wiznet5k_make_new, locals_dict, &wiznet5k_locals_dict ); #else // WIZNET5K_PROVIDED_STACK @@ -1028,7 +1028,7 @@ STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE( mod_network_nic_type_wiznet5k_base, MP_QSTR_WIZNET5K, MP_TYPE_FLAG_NONE, - wiznet5k_make_new, + make_new, wiznet5k_make_new, locals_dict, &wiznet5k_locals_dict ); diff --git a/extmod/vfs.c b/extmod/vfs.c index 00450e100559..af63ceb37eb1 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -173,7 +173,7 @@ STATIC mp_obj_t mp_vfs_autodetect(mp_obj_t bdev_obj) { #if MICROPY_VFS_LFS1 if (memcmp(&buf[32], "littlefs", 8) == 0) { // LFS1 - mp_obj_t vfs = mp_type_vfs_lfs1.make_new(&mp_type_vfs_lfs1, 1, 0, &bdev_obj); + mp_obj_t vfs = MP_OBJ_TYPE_GET_SLOT(&mp_type_vfs_lfs1, make_new)(&mp_type_vfs_lfs1, 1, 0, &bdev_obj); nlr_pop(); return vfs; } @@ -181,7 +181,7 @@ STATIC mp_obj_t mp_vfs_autodetect(mp_obj_t bdev_obj) { #if MICROPY_VFS_LFS2 if (memcmp(&buf[0], "littlefs", 8) == 0) { // LFS2 - mp_obj_t vfs = mp_type_vfs_lfs2.make_new(&mp_type_vfs_lfs2, 1, 0, &bdev_obj); + mp_obj_t vfs = MP_OBJ_TYPE_GET_SLOT(&mp_type_vfs_lfs2, make_new)(&mp_type_vfs_lfs2, 1, 0, &bdev_obj); nlr_pop(); return vfs; } @@ -194,7 +194,7 @@ STATIC mp_obj_t mp_vfs_autodetect(mp_obj_t bdev_obj) { #endif #if MICROPY_VFS_FAT - return mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, 0, &bdev_obj); + return MP_OBJ_TYPE_GET_SLOT(&mp_fat_vfs_type, make_new)(&mp_fat_vfs_type, 1, 0, &bdev_obj); #endif // no filesystem found diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 7c18a5163374..efb6bf7e9815 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -435,7 +435,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_fat_vfs_type, MP_QSTR_VfsFat, MP_TYPE_FLAG_NONE, - fat_vfs_make_new, + make_new, fat_vfs_make_new, protocol, &fat_vfs_proto, locals_dict, &fat_vfs_locals_dict ); diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index ca2e2b446f13..07e6df9bf959 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -180,7 +180,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_fat_fileio, MP_QSTR_FileIO, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, file_obj_print, protocol, &vfs_fat_fileio_stream_p, locals_dict, &vfs_fat_rawfile_locals_dict @@ -197,7 +196,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_fat_textio, MP_QSTR_TextIOWrapper, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, file_obj_print, protocol, &vfs_fat_textio_stream_p, locals_dict, &vfs_fat_rawfile_locals_dict diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index 33e2ef551987..d9617817f956 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -512,7 +512,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_VFS_LFSx, VFS_LFSx_QSTR, MP_TYPE_FLAG_NONE, - MP_VFS_LFSx(make_new), + make_new, MP_VFS_LFSx(make_new), protocol, &MP_VFS_LFSx(proto), locals_dict, &MP_VFS_LFSx(locals_dict) ); diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c index f97641b7b951..2c87fd5b994c 100644 --- a/extmod/vfs_lfsx_file.c +++ b/extmod/vfs_lfsx_file.c @@ -224,7 +224,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_VFS_LFSx_(_fileio), MP_QSTR_FileIO, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, MP_VFS_LFSx(file_print), protocol, &MP_VFS_LFSx(fileio_stream_p), locals_dict, &MP_VFS_LFSx(file_locals_dict) @@ -241,7 +240,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_VFS_LFSx_(_textio), MP_QSTR_TextIOWrapper, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, MP_VFS_LFSx(file_print), protocol, &MP_VFS_LFSx(textio_stream_p), locals_dict, &MP_VFS_LFSx(file_locals_dict) diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index b02827e8647c..3694ebaf9974 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -402,7 +402,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_posix, MP_QSTR_VfsPosix, MP_TYPE_FLAG_NONE, - vfs_posix_make_new, + make_new, vfs_posix_make_new, protocol, &vfs_posix_proto, locals_dict, &vfs_posix_locals_dict ); diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 729d914d3a11..4a37489686cd 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -253,7 +253,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_posix_fileio, MP_QSTR_FileIO, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, vfs_posix_file_print, protocol, &vfs_posix_fileio_stream_p, locals_dict, &vfs_posix_rawfile_locals_dict @@ -270,7 +269,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_vfs_posix_textio, MP_QSTR_TextIOWrapper, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, vfs_posix_file_print, protocol, &vfs_posix_textio_stream_p, locals_dict, &vfs_posix_rawfile_locals_dict diff --git a/ports/cc3200/misc/mpirq.c b/ports/cc3200/misc/mpirq.c index 9c3c2f719672..eb813fa4c6f2 100644 --- a/ports/cc3200/misc/mpirq.c +++ b/ports/cc3200/misc/mpirq.c @@ -194,7 +194,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_irq_type, MP_QSTR_irq, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, call, mp_irq_call, locals_dict, &mp_irq_locals_dict ); diff --git a/ports/cc3200/mods/modnetwork.c b/ports/cc3200/mods/modnetwork.c index 0a72a1ab3256..590e87268393 100644 --- a/ports/cc3200/mods/modnetwork.c +++ b/ports/cc3200/mods/modnetwork.c @@ -175,7 +175,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( network_server_type, MP_QSTR_Server, MP_TYPE_FLAG_NONE, - network_server_make_new, + make_new, network_server_make_new, locals_dict, &network_server_locals_dict ); #endif diff --git a/ports/cc3200/mods/moduhashlib.c b/ports/cc3200/mods/moduhashlib.c index 4a759d8ea5c5..302ff335ff86 100644 --- a/ports/cc3200/mods/moduhashlib.c +++ b/ports/cc3200/mods/moduhashlib.c @@ -181,7 +181,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( sha1_type, MP_QSTR_sha1, MP_TYPE_FLAG_NONE, - hash_make_new, + make_new, hash_make_new, locals_dict, &hash_locals_dict ); @@ -189,7 +189,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( sha256_type, MP_QSTR_sha256, MP_TYPE_FLAG_NONE, - hash_make_new, + make_new, hash_make_new, locals_dict, &hash_locals_dict ); diff --git a/ports/cc3200/mods/modusocket.c b/ports/cc3200/mods/modusocket.c index 55d504a70972..cd1489fb4ae5 100644 --- a/ports/cc3200/mods/modusocket.c +++ b/ports/cc3200/mods/modusocket.c @@ -763,7 +763,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( socket_type, MP_QSTR_socket, MP_TYPE_FLAG_NONE, - socket_make_new, + make_new, socket_make_new, protocol, &socket_stream_p, locals_dict, &socket_locals_dict ); diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c index 1e82b07e0874..6cf1cbee4e41 100644 --- a/ports/cc3200/mods/modwlan.c +++ b/ports/cc3200/mods/modwlan.c @@ -1289,7 +1289,7 @@ STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE( mod_network_nic_type_wlan_base, MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, - wlan_make_new, + make_new, wlan_make_new, locals_dict, &wlan_locals_dict ); diff --git a/ports/cc3200/mods/pybadc.c b/ports/cc3200/mods/pybadc.c index a14f9aced261..74664282560d 100644 --- a/ports/cc3200/mods/pybadc.c +++ b/ports/cc3200/mods/pybadc.c @@ -237,7 +237,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - adc_make_new, + make_new, adc_make_new, print, adc_print, locals_dict, &adc_locals_dict ); @@ -305,7 +305,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( pyb_adc_channel_type, MP_QSTR_ADCChannel, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, adc_channel_print, call, adc_channel_call, locals_dict, &adc_channel_locals_dict diff --git a/ports/cc3200/mods/pybflash.c b/ports/cc3200/mods/pybflash.c index a6d1e23fbf02..46b7be234f9c 100644 --- a/ports/cc3200/mods/pybflash.c +++ b/ports/cc3200/mods/pybflash.c @@ -88,7 +88,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_flash_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - pyb_flash_make_new, + make_new, pyb_flash_make_new, locals_dict, &pyb_flash_locals_dict ); diff --git a/ports/cc3200/mods/pybi2c.c b/ports/cc3200/mods/pybi2c.c index de92cc7c32b3..5d77dc8367c4 100644 --- a/ports/cc3200/mods/pybi2c.c +++ b/ports/cc3200/mods/pybi2c.c @@ -525,7 +525,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - pyb_i2c_make_new, + make_new, pyb_i2c_make_new, print, pyb_i2c_print, locals_dict, &pyb_i2c_locals_dict ); diff --git a/ports/cc3200/mods/pybpin.c b/ports/cc3200/mods/pybpin.c index 374d09ddfbd7..f04ca756540e 100644 --- a/ports/cc3200/mods/pybpin.c +++ b/ports/cc3200/mods/pybpin.c @@ -935,7 +935,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - pin_make_new, + make_new, pin_make_new, print, pin_print, call, pin_call, locals_dict, &pin_locals_dict @@ -957,7 +957,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_board_pins_obj_type, MP_QSTR_board, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pin_named_pins_obj_print, locals_dict, &pin_board_pins_locals_dict ); diff --git a/ports/cc3200/mods/pybrtc.c b/ports/cc3200/mods/pybrtc.c index ed7a20fecbf6..21e729dbf175 100644 --- a/ports/cc3200/mods/pybrtc.c +++ b/ports/cc3200/mods/pybrtc.c @@ -473,7 +473,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - pyb_rtc_make_new, + make_new, pyb_rtc_make_new, locals_dict, &pyb_rtc_locals_dict ); diff --git a/ports/cc3200/mods/pybsd.c b/ports/cc3200/mods/pybsd.c index 968a6a87ec4d..209c3b5a85ec 100644 --- a/ports/cc3200/mods/pybsd.c +++ b/ports/cc3200/mods/pybsd.c @@ -216,6 +216,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_sd_type, MP_QSTR_SD, MP_TYPE_FLAG_NONE, - pyb_sd_make_new, + make_new, pyb_sd_make_new, locals_dict, &pyb_sd_locals_dict ); diff --git a/ports/cc3200/mods/pybsleep.c b/ports/cc3200/mods/pybsleep.c index 423099991f8d..ffb281e6b13d 100644 --- a/ports/cc3200/mods/pybsleep.c +++ b/ports/cc3200/mods/pybsleep.c @@ -128,8 +128,7 @@ STATIC pybsleep_wake_reason_t pybsleep_wake_reason = PYB_SLP_WAKED_PWRON; STATIC MP_DEFINE_CONST_OBJ_TYPE( pyb_sleep_type, MP_QSTR_sleep, - MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW + MP_TYPE_FLAG_NONE ); /****************************************************************************** diff --git a/ports/cc3200/mods/pybspi.c b/ports/cc3200/mods/pybspi.c index 7d83fabfde4d..61086ec2e1d8 100644 --- a/ports/cc3200/mods/pybspi.c +++ b/ports/cc3200/mods/pybspi.c @@ -381,7 +381,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - pyb_spi_make_new, + make_new, pyb_spi_make_new, print, pyb_spi_print, locals_dict, &pyb_spi_locals_dict ); diff --git a/ports/cc3200/mods/pybtimer.c b/ports/cc3200/mods/pybtimer.c index 14e1deb083ed..be365f3c92b2 100644 --- a/ports/cc3200/mods/pybtimer.c +++ b/ports/cc3200/mods/pybtimer.c @@ -463,7 +463,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - pyb_timer_make_new, + make_new, pyb_timer_make_new, print, pyb_timer_print, locals_dict, &pyb_timer_locals_dict ); @@ -726,7 +726,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_channel_type, MP_QSTR_TimerChannel, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pyb_timer_channel_print, locals_dict, &pyb_timer_channel_locals_dict ); diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c index f92f54473220..424ca251ec79 100644 --- a/ports/cc3200/mods/pybuart.c +++ b/ports/cc3200/mods/pybuart.c @@ -689,7 +689,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - pyb_uart_make_new, + make_new, pyb_uart_make_new, print, pyb_uart_print, protocol, &uart_stream_p, locals_dict, &pyb_uart_locals_dict diff --git a/ports/cc3200/mods/pybwdt.c b/ports/cc3200/mods/pybwdt.c index 3c1f9eb195f1..589f53cf1275 100644 --- a/ports/cc3200/mods/pybwdt.c +++ b/ports/cc3200/mods/pybwdt.c @@ -154,7 +154,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_wdt_type, MP_QSTR_WDT, MP_TYPE_FLAG_NONE, - pyb_wdt_make_new, + make_new, pyb_wdt_make_new, locals_dict, &pybwdt_locals_dict ); diff --git a/ports/esp32/esp32_nvs.c b/ports/esp32/esp32_nvs.c index d935a13d6fe5..0b3661918c77 100644 --- a/ports/esp32/esp32_nvs.c +++ b/ports/esp32/esp32_nvs.c @@ -145,7 +145,7 @@ MP_DEFINE_CONST_OBJ_TYPE( esp32_nvs_type, MP_QSTR_NVS, MP_TYPE_FLAG_NONE, - esp32_nvs_make_new, + make_new, esp32_nvs_make_new, print, esp32_nvs_print, locals_dict, &esp32_nvs_locals_dict ); diff --git a/ports/esp32/esp32_partition.c b/ports/esp32/esp32_partition.c index 6ce1e90b4c70..17aa34e560e8 100644 --- a/ports/esp32/esp32_partition.c +++ b/ports/esp32/esp32_partition.c @@ -288,7 +288,7 @@ MP_DEFINE_CONST_OBJ_TYPE( esp32_partition_type, MP_QSTR_Partition, MP_TYPE_FLAG_NONE, - esp32_partition_make_new, + make_new, esp32_partition_make_new, print, esp32_partition_print, locals_dict, &esp32_partition_locals_dict ); diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index ee09ac520061..78c8c8aceeff 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -376,7 +376,7 @@ MP_DEFINE_CONST_OBJ_TYPE( esp32_rmt_type, MP_QSTR_RMT, MP_TYPE_FLAG_NONE, - esp32_rmt_make_new, + make_new, esp32_rmt_make_new, print, esp32_rmt_print, locals_dict, &esp32_rmt_locals_dict ); diff --git a/ports/esp32/esp32_ulp.c b/ports/esp32/esp32_ulp.c index 5030f980675e..843bdb2366df 100644 --- a/ports/esp32/esp32_ulp.c +++ b/ports/esp32/esp32_ulp.c @@ -95,7 +95,7 @@ MP_DEFINE_CONST_OBJ_TYPE( esp32_ulp_type, MP_QSTR_ULP, MP_TYPE_FLAG_NONE, - esp32_ulp_make_new, + make_new, esp32_ulp_make_new, locals_dict, &esp32_ulp_locals_dict ); diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c index c4e04159c0b9..1e20186b97be 100644 --- a/ports/esp32/machine_adc.c +++ b/ports/esp32/machine_adc.c @@ -260,7 +260,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - madc_make_new, + make_new, madc_make_new, print, madc_print, locals_dict, &madc_locals_dict ); diff --git a/ports/esp32/machine_adcblock.c b/ports/esp32/machine_adcblock.c index ae3244f7fdb4..afe8fdea40b2 100644 --- a/ports/esp32/machine_adcblock.c +++ b/ports/esp32/machine_adcblock.c @@ -198,7 +198,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adcblock_type, MP_QSTR_ADCBlock, MP_TYPE_FLAG_NONE, - madcblock_make_new, + make_new, madcblock_make_new, print, madcblock_print, locals_dict, &madcblock_locals_dict ); diff --git a/ports/esp32/machine_dac.c b/ports/esp32/machine_dac.c index fbe33b0344a4..0e85dc9c9bfb 100644 --- a/ports/esp32/machine_dac.c +++ b/ports/esp32/machine_dac.c @@ -108,7 +108,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_dac_type, MP_QSTR_DAC, MP_TYPE_FLAG_NONE, - mdac_make_new, + make_new, mdac_make_new, print, mdac_print, locals_dict, &mdac_locals_dict ); diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 51ea31ac1b3d..05b1c871cb3c 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -549,7 +549,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hw_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_hw_spi_make_new, + make_new, machine_hw_spi_make_new, print, machine_hw_spi_print, protocol, &machine_hw_spi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index 895dc3a39874..9244343dcf61 100644 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -196,7 +196,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hw_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_hw_i2c_make_new, + make_new, machine_hw_i2c_make_new, print, machine_hw_i2c_print, protocol, &machine_hw_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index 6e18394cc5e5..eecf71549871 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -833,7 +833,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_i2s_make_new, + make_new, machine_i2s_make_new, print, machine_i2s_print, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index fd523a38edac..4f6f948d52af 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -533,7 +533,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, machine_pin_print, call, machine_pin_call, protocol, &pin_pin_p, @@ -728,7 +728,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( machine_pin_irq_type, MP_QSTR_IRQ, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, call, machine_pin_irq_call, locals_dict, &machine_pin_irq_locals_dict ); diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index 19b83703fd43..3d620336c9a9 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -177,6 +177,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - machine_rtc_make_new, + make_new, machine_rtc_make_new, locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/esp32/machine_sdcard.c b/ports/esp32/machine_sdcard.c index 0b6159157d98..801a26f378db 100644 --- a/ports/esp32/machine_sdcard.c +++ b/ports/esp32/machine_sdcard.c @@ -403,7 +403,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_sdcard_type, MP_QSTR_SDCard, MP_TYPE_FLAG_NONE, - machine_sdcard_make_new, + make_new, machine_sdcard_make_new, locals_dict, &machine_sdcard_locals_dict ); diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 2fd40fa2afc1..83fe81f6eee3 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -281,7 +281,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - machine_timer_make_new, + make_new, machine_timer_make_new, print, machine_timer_print, locals_dict, &machine_timer_locals_dict ); diff --git a/ports/esp32/machine_touchpad.c b/ports/esp32/machine_touchpad.c index deba818dd1c8..ad1f6c9474cd 100644 --- a/ports/esp32/machine_touchpad.c +++ b/ports/esp32/machine_touchpad.c @@ -138,7 +138,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_touchpad_type, MP_QSTR_TouchPad, MP_TYPE_FLAG_NONE, - mtp_make_new, + make_new, mtp_make_new, locals_dict, &mtp_locals_dict ); diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 1f404154fc5b..4cfa31b71de3 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -534,7 +534,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_uart_make_new, + make_new, machine_uart_make_new, print, machine_uart_print, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict diff --git a/ports/esp32/machine_wdt.c b/ports/esp32/machine_wdt.c index bda9c6975e15..4ccf417b6099 100644 --- a/ports/esp32/machine_wdt.c +++ b/ports/esp32/machine_wdt.c @@ -87,6 +87,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_wdt_type, MP_QSTR_WDT, MP_TYPE_FLAG_NONE, - machine_wdt_make_new, + make_new, machine_wdt_make_new, locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/esp32/modsocket.c b/ports/esp32/modsocket.c index e7e6f3c26e28..334c5bae33c4 100644 --- a/ports/esp32/modsocket.c +++ b/ports/esp32/modsocket.c @@ -789,7 +789,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( socket_type, MP_QSTR_socket, MP_TYPE_FLAG_NONE, - socket_make_new, + make_new, socket_make_new, protocol, &socket_stream_p, locals_dict, &socket_locals_dict ); diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c index 3c5aea5fb8a4..c57d7815d7ca 100644 --- a/ports/esp32/network_lan.c +++ b/ports/esp32/network_lan.c @@ -306,7 +306,6 @@ MP_DEFINE_CONST_OBJ_TYPE( lan_if_type, MP_QSTR_LAN, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &lan_if_locals_dict ); diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c index df07515c7d41..703cdc7889fd 100644 --- a/ports/esp32/network_ppp.c +++ b/ports/esp32/network_ppp.c @@ -282,6 +282,5 @@ MP_DEFINE_CONST_OBJ_TYPE( ppp_if_type, MP_QSTR_PPP, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &ppp_if_locals_dict ); diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c index 0f1f5de14937..f0b458e6ddfe 100644 --- a/ports/esp32/network_wlan.c +++ b/ports/esp32/network_wlan.c @@ -619,7 +619,6 @@ MP_DEFINE_CONST_OBJ_TYPE( wlan_if_type, MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &wlan_if_locals_dict ); diff --git a/ports/esp8266/machine_adc.c b/ports/esp8266/machine_adc.c index b1e7b3843527..f4fd32db9c76 100644 --- a/ports/esp8266/machine_adc.c +++ b/ports/esp8266/machine_adc.c @@ -93,7 +93,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - machine_adc_make_new, + make_new, machine_adc_make_new, print, machine_adc_print, locals_dict, &machine_adc_locals_dict ); diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c index 3f449a1de91e..2edb294adeff 100644 --- a/ports/esp8266/machine_hspi.c +++ b/ports/esp8266/machine_hspi.c @@ -179,7 +179,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hspi_type, MP_QSTR_HSPI, MP_TYPE_FLAG_NONE, - machine_hspi_make_new, + make_new, machine_hspi_make_new, print, machine_hspi_print, protocol, &machine_hspi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/ports/esp8266/machine_pin.c b/ports/esp8266/machine_pin.c index 32ffca873dfa..ea17728e2359 100644 --- a/ports/esp8266/machine_pin.c +++ b/ports/esp8266/machine_pin.c @@ -454,7 +454,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, pyb_pin_print, call, pyb_pin_call, protocol, &pin_pin_p, @@ -514,7 +514,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( pin_irq_type, MP_QSTR_IRQ, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, call, pin_irq_call, locals_dict, &pin_irq_locals_dict ); diff --git a/ports/esp8266/machine_rtc.c b/ports/esp8266/machine_rtc.c index cc6b79a031be..d8cbb8f8247d 100644 --- a/ports/esp8266/machine_rtc.c +++ b/ports/esp8266/machine_rtc.c @@ -266,6 +266,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - pyb_rtc_make_new, + make_new, pyb_rtc_make_new, locals_dict, &pyb_rtc_locals_dict ); diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index af6231c21903..873b12b2fab9 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -347,7 +347,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - pyb_uart_make_new, + make_new, pyb_uart_make_new, print, pyb_uart_print, protocol, &uart_stream_p, locals_dict, &pyb_uart_locals_dict diff --git a/ports/esp8266/machine_wdt.c b/ports/esp8266/machine_wdt.c index 26d5c9fa76f1..39a5d51119ef 100644 --- a/ports/esp8266/machine_wdt.c +++ b/ports/esp8266/machine_wdt.c @@ -73,6 +73,6 @@ MP_DEFINE_CONST_OBJ_TYPE( esp_wdt_type, MP_QSTR_WDT, MP_TYPE_FLAG_NONE, - machine_wdt_make_new, + make_new, machine_wdt_make_new, locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c index ded5e58abf7a..583540a81c76 100644 --- a/ports/esp8266/main.c +++ b/ports/esp8266/main.c @@ -68,7 +68,7 @@ STATIC void mp_reset(void) { mp_obj_t args[2]; args[0] = MP_OBJ_NEW_SMALL_INT(0); args[1] = MP_OBJ_NEW_SMALL_INT(115200); - args[0] = pyb_uart_type.make_new(&pyb_uart_type, 2, 0, args); + args[0] = MP_OBJ_TYPE_GET_SLOT(&pyb_uart_type, make_new)(&pyb_uart_type, 2, 0, args); args[1] = MP_OBJ_NEW_SMALL_INT(1); mp_uos_dupterm_obj.fun.var(2, args); } diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index eb41e30f66b1..af46cbbfe747 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -341,7 +341,7 @@ MP_DEFINE_CONST_OBJ_TYPE( esp_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - esp_timer_make_new, + make_new, esp_timer_make_new, print, esp_timer_print, locals_dict, &esp_timer_locals_dict ); diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index 45a5a2be5412..ec62528a0834 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -514,7 +514,6 @@ MP_DEFINE_CONST_OBJ_TYPE( wlan_if_type, MP_QSTR_WLAN, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &wlan_if_locals_dict ); diff --git a/ports/mimxrt/machine_adc.c b/ports/mimxrt/machine_adc.c index 7a19d1225ee7..d63157d36efb 100644 --- a/ports/mimxrt/machine_adc.c +++ b/ports/mimxrt/machine_adc.c @@ -121,7 +121,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - adc_obj_make_new, + make_new, adc_obj_make_new, print, adc_obj_print, locals_dict, &adc_locals_dict ); diff --git a/ports/mimxrt/machine_i2c.c b/ports/mimxrt/machine_i2c.c index 62dfd8204c08..f00ba6b1ba76 100644 --- a/ports/mimxrt/machine_i2c.c +++ b/ports/mimxrt/machine_i2c.c @@ -201,7 +201,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_i2c_make_new, + make_new, machine_i2c_make_new, print, machine_i2c_print, protocol, &machine_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/ports/mimxrt/machine_i2s.c b/ports/mimxrt/machine_i2s.c index b6c630138b76..1733140fb57e 100644 --- a/ports/mimxrt/machine_i2s.c +++ b/ports/mimxrt/machine_i2s.c @@ -1217,7 +1217,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_i2s_make_new, + make_new, machine_i2s_make_new, print, machine_i2s_print, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict diff --git a/ports/mimxrt/machine_led.c b/ports/mimxrt/machine_led.c index 9fd98ef71043..8dd74b32ba76 100644 --- a/ports/mimxrt/machine_led.c +++ b/ports/mimxrt/machine_led.c @@ -84,7 +84,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - led_obj_make_new, + make_new, led_obj_make_new, print, led_obj_print, locals_dict, &led_locals_dict ); diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 261e3e414803..836bd8524b72 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -62,7 +62,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_cpu_pins_obj_type, MP_QSTR_cpu, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &machine_pin_cpu_pins_locals_dict ); @@ -70,7 +69,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_board_pins_obj_type, MP_QSTR_board, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &machine_pin_board_pins_locals_dict ); @@ -424,7 +422,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, machine_pin_obj_print, call, machine_pin_obj_call, protocol, &machine_pin_obj_protocol, @@ -436,7 +434,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_af_type, MP_QSTR_PinAF, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, machine_pin_obj_print, locals_dict, &machine_pin_locals_dict ); diff --git a/ports/mimxrt/machine_rtc.c b/ports/mimxrt/machine_rtc.c index 2e1a09dedbe6..da7a437491f7 100644 --- a/ports/mimxrt/machine_rtc.c +++ b/ports/mimxrt/machine_rtc.c @@ -170,6 +170,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - machine_rtc_make_new, + make_new, machine_rtc_make_new, locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/mimxrt/machine_sdcard.c b/ports/mimxrt/machine_sdcard.c index 22f7e7c232a8..9254faf14a44 100644 --- a/ports/mimxrt/machine_sdcard.c +++ b/ports/mimxrt/machine_sdcard.c @@ -212,7 +212,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_sdcard_type, MP_QSTR_SDCard, MP_TYPE_FLAG_NONE, - sdcard_obj_make_new, + make_new, sdcard_obj_make_new, locals_dict, &sdcard_locals_dict ); diff --git a/ports/mimxrt/machine_spi.c b/ports/mimxrt/machine_spi.c index 93b75e931eb4..a3a6bb414edd 100644 --- a/ports/mimxrt/machine_spi.c +++ b/ports/mimxrt/machine_spi.c @@ -255,7 +255,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_spi_make_new, + make_new, machine_spi_make_new, print, machine_spi_print, protocol, &machine_spi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/ports/mimxrt/machine_timer.c b/ports/mimxrt/machine_timer.c index a6b61982f7ec..a237272390ce 100644 --- a/ports/mimxrt/machine_timer.c +++ b/ports/mimxrt/machine_timer.c @@ -215,7 +215,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - machine_timer_make_new, + make_new, machine_timer_make_new, print, machine_timer_print, locals_dict, &machine_timer_locals_dict ); diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c index e93d2478f3ff..a0706c8f4fca 100644 --- a/ports/mimxrt/machine_uart.c +++ b/ports/mimxrt/machine_uart.c @@ -473,7 +473,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_uart_make_new, + make_new, machine_uart_make_new, print, machine_uart_print, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict diff --git a/ports/mimxrt/machine_wdt.c b/ports/mimxrt/machine_wdt.c index e0b5c74b5426..f5f14f9ef7b2 100644 --- a/ports/mimxrt/machine_wdt.c +++ b/ports/mimxrt/machine_wdt.c @@ -103,6 +103,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_wdt_type, MP_QSTR_WDT, MP_TYPE_FLAG_NONE, - machine_wdt_make_new, + make_new, machine_wdt_make_new, locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index bd03c853d597..fd2e7558f9f8 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -219,6 +219,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mimxrt_flash_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - mimxrt_flash_make_new, + make_new, mimxrt_flash_make_new, locals_dict, &mimxrt_flash_locals_dict ); diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index e15894294b68..0842cde82d00 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -224,7 +224,7 @@ MP_DEFINE_CONST_OBJ_TYPE( network_lan_type, MP_QSTR_LAN, MP_TYPE_FLAG_NONE, - network_lan_make_new, + make_new, network_lan_make_new, print, network_lan_print, locals_dict, &network_lan_locals_dict ); diff --git a/ports/nrf/boards/microbit/modules/iters.c b/ports/nrf/boards/microbit/modules/iters.c index 2fe14866914f..e6762421eb57 100644 --- a/ports/nrf/boards/microbit/modules/iters.c +++ b/ports/nrf/boards/microbit/modules/iters.c @@ -47,7 +47,6 @@ MP_DEFINE_CONST_OBJ_TYPE( microbit_repeat_iterator_type, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, microbit_repeat_iter_next ); diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c index 5cb25ea1ced4..e4e4d13fe449 100644 --- a/ports/nrf/boards/microbit/modules/microbitdisplay.c +++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c @@ -546,7 +546,6 @@ MP_DEFINE_CONST_OBJ_TYPE( microbit_display_type, MP_QSTR_MicroBitDisplay, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, µbit_display_locals_dict ); diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c index b22c2e29acec..17d737dba5e5 100644 --- a/ports/nrf/boards/microbit/modules/microbitimage.c +++ b/ports/nrf/boards/microbit/modules/microbitimage.c @@ -682,7 +682,7 @@ MP_DEFINE_CONST_OBJ_TYPE( microbit_image_type, MP_QSTR_MicroBitImage, MP_TYPE_FLAG_NONE, - microbit_image_make_new, + make_new, microbit_image_make_new, print, microbit_image_print, binary_op, image_binary_op, locals_dict, µbit_image_locals_dict @@ -832,7 +832,6 @@ MP_DEFINE_CONST_OBJ_TYPE( microbit_scrolling_string_iterator_type, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, microbit_scrolling_string_iter_next ); @@ -912,7 +911,6 @@ MP_DEFINE_CONST_OBJ_TYPE( microbit_facade_iterator_type, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, microbit_facade_iter_next ); diff --git a/ports/nrf/main.c b/ports/nrf/main.c index 83466626fca0..bcfaafd39c7e 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -170,7 +170,7 @@ int main(int argc, char **argv) { MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_NEW_SMALL_INT(115200), }; - MP_STATE_PORT(board_stdio_uart) = machine_hard_uart_type.make_new((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); + MP_STATE_PORT(board_stdio_uart) = MP_OBJ_TYPE_GET_SLOT(&machine_hard_uart_type, make_new)((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); } #endif diff --git a/ports/nrf/modules/board/led.c b/ports/nrf/modules/board/led.c index 577c2b62843f..57065a48517a 100644 --- a/ports/nrf/modules/board/led.c +++ b/ports/nrf/modules/board/led.c @@ -198,7 +198,7 @@ MP_DEFINE_CONST_OBJ_TYPE( board_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - led_obj_make_new, + make_new, led_obj_make_new, print, led_obj_print, locals_dict, &led_locals_dict ); diff --git a/ports/nrf/modules/machine/adc.c b/ports/nrf/modules/machine/adc.c index 84db8d259f2a..df9d23465a8d 100644 --- a/ports/nrf/modules/machine/adc.c +++ b/ports/nrf/modules/machine/adc.c @@ -298,7 +298,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - machine_adc_make_new, + make_new, machine_adc_make_new, locals_dict, &machine_adc_locals_dict, print, machine_adc_print ); diff --git a/ports/nrf/modules/machine/i2c.c b/ports/nrf/modules/machine/i2c.c index 7cb55d078821..c16c3669ec57 100644 --- a/ports/nrf/modules/machine/i2c.c +++ b/ports/nrf/modules/machine/i2c.c @@ -165,7 +165,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_hard_i2c_make_new, + make_new, machine_hard_i2c_make_new, print, machine_hard_i2c_print, protocol, &machine_hard_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/ports/nrf/modules/machine/pin.c b/ports/nrf/modules/machine/pin.c index 4f283e5dba14..db5cc9cbb136 100644 --- a/ports/nrf/modules/machine/pin.c +++ b/ports/nrf/modules/machine/pin.c @@ -600,7 +600,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - pin_make_new, + make_new, pin_make_new, print, pin_print, call, pin_call, locals_dict, &pin_locals_dict @@ -676,7 +676,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_af_type, MP_QSTR_PinAF, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pin_af_obj_print, locals_dict, &pin_af_locals_dict ); diff --git a/ports/nrf/modules/machine/pwm.c b/ports/nrf/modules/machine/pwm.c index 54e643ec55ff..862e1907cbf3 100644 --- a/ports/nrf/modules/machine/pwm.c +++ b/ports/nrf/modules/machine/pwm.c @@ -343,7 +343,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_pwm_type, MP_QSTR_PWM, MP_TYPE_FLAG_NONE, - machine_pwm_make_new, + make_new, machine_pwm_make_new, print, machine_pwm_print, locals_dict, &machine_pwm_locals_dict ); diff --git a/ports/nrf/modules/machine/rtcounter.c b/ports/nrf/modules/machine/rtcounter.c index cafe08b6c684..d52ca3e9a336 100644 --- a/ports/nrf/modules/machine/rtcounter.c +++ b/ports/nrf/modules/machine/rtcounter.c @@ -266,7 +266,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_rtcounter_type, MP_QSTR_RTCounter, MP_TYPE_FLAG_NONE, - machine_rtc_make_new, + make_new, machine_rtc_make_new, print, rtc_print, locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/nrf/modules/machine/spi.c b/ports/nrf/modules/machine/spi.c index d5613a464324..fd7f7bb5bcce 100644 --- a/ports/nrf/modules/machine/spi.c +++ b/ports/nrf/modules/machine/spi.c @@ -431,7 +431,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_spi_make_new, + make_new, machine_spi_make_new, print, machine_hard_spi_print, protocol, &machine_hard_spi_p, locals_dict, &machine_spi_locals_dict diff --git a/ports/nrf/modules/machine/temp.c b/ports/nrf/modules/machine/temp.c index 00d6329b6498..dff15a9d1497 100644 --- a/ports/nrf/modules/machine/temp.c +++ b/ports/nrf/modules/machine/temp.c @@ -116,7 +116,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_temp_type, MP_QSTR_Temp, MP_TYPE_FLAG_NONE, - machine_temp_make_new, + make_new, machine_temp_make_new, locals_dict, &machine_temp_locals_dict, print, machine_temp_print ); diff --git a/ports/nrf/modules/machine/timer.c b/ports/nrf/modules/machine/timer.c index f7f6101726a6..091e6d0e32ff 100644 --- a/ports/nrf/modules/machine/timer.c +++ b/ports/nrf/modules/machine/timer.c @@ -238,7 +238,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - machine_timer_make_new, + make_new, machine_timer_make_new, print, timer_print, locals_dict, &machine_timer_locals_dict ); diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index ca0fcf859a55..035a30df9c01 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -374,7 +374,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_hard_uart_make_new, + make_new, machine_hard_uart_make_new, print, machine_hard_uart_print, protocol, &uart_stream_p, locals_dict, &machine_hard_uart_locals_dict diff --git a/ports/nrf/modules/nrf/flashbdev.c b/ports/nrf/modules/nrf/flashbdev.c index 84a3dd2520b4..e92919cac5a2 100644 --- a/ports/nrf/modules/nrf/flashbdev.c +++ b/ports/nrf/modules/nrf/flashbdev.c @@ -187,7 +187,7 @@ MP_DEFINE_CONST_OBJ_TYPE( nrf_flashbdev_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - nrf_flashbdev_make_new, + make_new, nrf_flashbdev_make_new, print, nrf_flashbdev_print, locals_dict, &nrf_flashbdev_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c index 2be7dab9d3f7..7b9e3af6a317 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c +++ b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c @@ -213,7 +213,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_characteristic_type, MP_QSTR_Characteristic, MP_TYPE_FLAG_NONE, - ubluepy_characteristic_make_new, + make_new, ubluepy_characteristic_make_new, print, ubluepy_characteristic_print, locals_dict, &ubluepy_characteristic_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c index c6c399924573..cad9adbb0325 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ b/ports/nrf/modules/ubluepy/ubluepy_constants.c @@ -73,7 +73,6 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_constants_ad_types_type, MP_QSTR_ad_types, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &ubluepy_constants_ad_types_locals_dict ); @@ -96,7 +95,6 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_constants_type, MP_QSTR_constants, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &ubluepy_constants_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_delegate.c b/ports/nrf/modules/ubluepy/ubluepy_delegate.c index dd19f70be445..43720b4186b0 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_delegate.c +++ b/ports/nrf/modules/ubluepy/ubluepy_delegate.c @@ -81,7 +81,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_delegate_type, MP_QSTR_DefaultDelegate, MP_TYPE_FLAG_NONE, - ubluepy_delegate_make_new, + make_new, ubluepy_delegate_make_new, print, ubluepy_delegate_print, locals_dict, &ubluepy_delegate_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c index d942d9822306..062b4210941f 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c +++ b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c @@ -74,7 +74,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_descriptor_type, MP_QSTR_Descriptor, MP_TYPE_FLAG_NONE, - ubluepy_descriptor_make_new, + make_new, ubluepy_descriptor_make_new, print, ubluepy_descriptor_print, locals_dict, &ubluepy_descriptor_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 9f638b45d735..d2a9e0011d12 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -486,7 +486,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_peripheral_type, MP_QSTR_Peripheral, MP_TYPE_FLAG_NONE, - ubluepy_peripheral_make_new, + make_new, ubluepy_peripheral_make_new, print, ubluepy_peripheral_print, locals_dict, &ubluepy_peripheral_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c index 89ca65d18c80..2dd4f57860fc 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c @@ -140,7 +140,6 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_scan_entry_type, MP_QSTR_ScanEntry, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, ubluepy_scan_entry_print, locals_dict, &ubluepy_scan_entry_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_scanner.c b/ports/nrf/modules/ubluepy/ubluepy_scanner.c index b56ec349d043..ffb7e946717b 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scanner.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scanner.c @@ -118,7 +118,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_scanner_type, MP_QSTR_Scanner, MP_TYPE_FLAG_NONE, - ubluepy_scanner_make_new, + make_new, ubluepy_scanner_make_new, print, ubluepy_scanner_print, locals_dict, &ubluepy_scanner_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c index 2bec6befd689..bf336d04c58a 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ b/ports/nrf/modules/ubluepy/ubluepy_service.c @@ -175,7 +175,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_service_type, MP_QSTR_Service, MP_TYPE_FLAG_NONE, - ubluepy_service_make_new, + make_new, ubluepy_service_make_new, print, ubluepy_service_print, locals_dict, &ubluepy_service_locals_dict ); diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c index 0fd6e75e5b62..abfe3cadd525 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c +++ b/ports/nrf/modules/ubluepy/ubluepy_uuid.c @@ -164,7 +164,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ubluepy_uuid_type, MP_QSTR_UUID, MP_TYPE_FLAG_NONE, - ubluepy_uuid_make_new, + make_new, ubluepy_uuid_make_new, print, ubluepy_uuid_print, locals_dict, &ubluepy_uuid_locals_dict ); diff --git a/ports/nrf/modules/uos/microbitfs.c b/ports/nrf/modules/uos/microbitfs.c index d1b320111607..6d697e1d1a0d 100644 --- a/ports/nrf/modules/uos/microbitfs.c +++ b/ports/nrf/modules/uos/microbitfs.c @@ -630,7 +630,6 @@ MP_DEFINE_CONST_OBJ_TYPE( uos_mbfs_textio_type, MP_QSTR_TextIO, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, protocol, &textio_stream_p, locals_dict, &uos_mbfs_file_locals_dict ); @@ -645,7 +644,6 @@ MP_DEFINE_CONST_OBJ_TYPE( uos_mbfs_fileio_type, MP_QSTR_FileIO, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, protocol, &fileio_stream_p, locals_dict, &uos_mbfs_file_locals_dict ); diff --git a/ports/nrf/pin_named_pins.c b/ports/nrf/pin_named_pins.c index 84ec89f44aa6..30e60692f741 100644 --- a/ports/nrf/pin_named_pins.c +++ b/ports/nrf/pin_named_pins.c @@ -40,7 +40,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_cpu_pins_obj_type, MP_QSTR_cpu, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pin_named_pins_obj_print, locals_dict, &pin_cpu_pins_locals_dict ); @@ -49,7 +48,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_board_pins_obj_type, MP_QSTR_board, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pin_named_pins_obj_print, locals_dict, &pin_board_pins_locals_dict ); diff --git a/ports/pic16bit/modpybled.c b/ports/pic16bit/modpybled.c index 2e5c2dcca3b1..47e83e040921 100644 --- a/ports/pic16bit/modpybled.c +++ b/ports/pic16bit/modpybled.c @@ -88,7 +88,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - pyb_led_make_new, + make_new, pyb_led_make_new, print, pyb_led_print, locals_dict, &pyb_led_locals_dict ); diff --git a/ports/pic16bit/modpybswitch.c b/ports/pic16bit/modpybswitch.c index f27cfb9b093a..b7192c5bba69 100644 --- a/ports/pic16bit/modpybswitch.c +++ b/ports/pic16bit/modpybswitch.c @@ -75,7 +75,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_switch_type, MP_QSTR_Switch, MP_TYPE_FLAG_NONE, - pyb_switch_make_new, + make_new, pyb_switch_make_new, print, pyb_switch_print, call, pyb_switch_call, locals_dict, &pyb_switch_locals_dict diff --git a/ports/renesas-ra/extint.c b/ports/renesas-ra/extint.c index 496a50c3e827..915c23e3cd85 100644 --- a/ports/renesas-ra/extint.c +++ b/ports/renesas-ra/extint.c @@ -378,7 +378,7 @@ MP_DEFINE_CONST_OBJ_TYPE( extint_type, MP_QSTR_ExtInt, MP_TYPE_FLAG_NONE, - extint_make_new, + make_new, extint_make_new, locals_dict, &extint_locals_dict, print, extint_obj_print ); diff --git a/ports/renesas-ra/led.c b/ports/renesas-ra/led.c index 9a3f1d40e965..a2284c5339b9 100644 --- a/ports/renesas-ra/led.c +++ b/ports/renesas-ra/led.c @@ -174,7 +174,7 @@ MP_DEFINE_CONST_OBJ_TYPE( ra_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - led_obj_make_new, + make_new, led_obj_make_new, locals_dict, &led_locals_dict, print, led_obj_print ); diff --git a/ports/renesas-ra/machine_adc.c b/ports/renesas-ra/machine_adc.c index 99e35f48d997..b71c3db4b025 100644 --- a/ports/renesas-ra/machine_adc.c +++ b/ports/renesas-ra/machine_adc.c @@ -130,7 +130,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - machine_adc_make_new, + make_new, machine_adc_make_new, locals_dict, &machine_adc_locals_dict, print, machine_adc_print ); diff --git a/ports/renesas-ra/machine_i2c.c b/ports/renesas-ra/machine_i2c.c index 563ea8787e52..16bd58996498 100644 --- a/ports/renesas-ra/machine_i2c.c +++ b/ports/renesas-ra/machine_i2c.c @@ -160,7 +160,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_i2c_make_new, + make_new, machine_i2c_make_new, locals_dict, &mp_machine_i2c_locals_dict, print, machine_i2c_print, protocol, &machine_i2c_p diff --git a/ports/renesas-ra/machine_pin.c b/ports/renesas-ra/machine_pin.c index 17ef1e19a413..0e393b64e554 100644 --- a/ports/renesas-ra/machine_pin.c +++ b/ports/renesas-ra/machine_pin.c @@ -353,7 +353,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, locals_dict, &machine_pin_locals_dict, print, machine_pin_print, call, machine_pin_call, @@ -393,7 +393,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_cpu_pins_obj_type, MP_QSTR_cpu, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &pin_cpu_pins_locals_dict ); @@ -401,7 +400,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_board_pins_obj_type, MP_QSTR_board, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &pin_board_pins_locals_dict ); diff --git a/ports/renesas-ra/machine_rtc.c b/ports/renesas-ra/machine_rtc.c index c3f64c697108..e699bea0bcc0 100644 --- a/ports/renesas-ra/machine_rtc.c +++ b/ports/renesas-ra/machine_rtc.c @@ -345,6 +345,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - machine_rtc_make_new, + make_new, machine_rtc_make_new, locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/renesas-ra/machine_spi.c b/ports/renesas-ra/machine_spi.c index d0e8b03bd12e..b9f5b1ad1b4e 100644 --- a/ports/renesas-ra/machine_spi.c +++ b/ports/renesas-ra/machine_spi.c @@ -301,7 +301,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_hard_spi_make_new, + make_new, machine_hard_spi_make_new, locals_dict, &mp_machine_spi_locals_dict, print, machine_hard_spi_print, protocol, &machine_hard_spi_p diff --git a/ports/renesas-ra/machine_timer.c b/ports/renesas-ra/machine_timer.c index f3e5aafb7cab..0f6ff80d27f4 100644 --- a/ports/renesas-ra/machine_timer.c +++ b/ports/renesas-ra/machine_timer.c @@ -140,7 +140,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - machine_timer_make_new, + make_new, machine_timer_make_new, locals_dict, &machine_timer_locals_dict, print, machine_timer_print ); diff --git a/ports/renesas-ra/machine_uart.c b/ports/renesas-ra/machine_uart.c index 6fa84ca821e4..86505ea0b953 100644 --- a/ports/renesas-ra/machine_uart.c +++ b/ports/renesas-ra/machine_uart.c @@ -575,7 +575,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_uart_make_new, + make_new, machine_uart_make_new, locals_dict, &machine_uart_locals_dict, print, machine_uart_print, protocol, &uart_stream_p diff --git a/ports/renesas-ra/main.c b/ports/renesas-ra/main.c index a87ddbd86804..d403dbacbe43 100644 --- a/ports/renesas-ra/main.c +++ b/ports/renesas-ra/main.c @@ -182,7 +182,7 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) { if (len != -1) { // Detected a littlefs filesystem so create correct block device for it mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR_len), MP_OBJ_NEW_SMALL_INT(len) }; - bdev = pyb_flash_type.make_new(&pyb_flash_type, 0, 1, args); + bdev = MP_OBJ_TYPE_GET_SLOT(&pyb_flash_type, make_new)(&pyb_flash_type, 0, 1, args); } #endif diff --git a/ports/renesas-ra/storage.c b/ports/renesas-ra/storage.c index f573894a5014..18dff9780078 100644 --- a/ports/renesas-ra/storage.c +++ b/ports/renesas-ra/storage.c @@ -404,7 +404,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_flash_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - pyb_flash_make_new, + make_new, pyb_flash_make_new, locals_dict, &pyb_flash_locals_dict, print, pyb_flash_print ); diff --git a/ports/renesas-ra/timer.c b/ports/renesas-ra/timer.c index 8f7acbcdaa47..04bd752b98cc 100644 --- a/ports/renesas-ra/timer.c +++ b/ports/renesas-ra/timer.c @@ -414,7 +414,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - pyb_timer_make_new, + make_new, pyb_timer_make_new, locals_dict, &pyb_timer_locals_dict, print, pyb_timer_print ); @@ -507,7 +507,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_channel_type, MP_QSTR_TimerChannel, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &pyb_timer_channel_locals_dict, print, pyb_timer_channel_print ); diff --git a/ports/renesas-ra/usrsw.c b/ports/renesas-ra/usrsw.c index 4107d7850d38..edbe51968301 100644 --- a/ports/renesas-ra/usrsw.c +++ b/ports/renesas-ra/usrsw.c @@ -139,7 +139,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_switch_type, MP_QSTR_Switch, MP_TYPE_FLAG_NONE, - pyb_switch_make_new, + make_new, pyb_switch_make_new, locals_dict, &pyb_switch_locals_dict, print, pyb_switch_print, call, pyb_switch_call diff --git a/ports/rp2/machine_adc.c b/ports/rp2/machine_adc.c index 85562d5c0758..9e3d7f57a86e 100644 --- a/ports/rp2/machine_adc.c +++ b/ports/rp2/machine_adc.c @@ -117,7 +117,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - machine_adc_make_new, + make_new, machine_adc_make_new, print, machine_adc_print, locals_dict, &machine_adc_locals_dict ); diff --git a/ports/rp2/machine_i2c.c b/ports/rp2/machine_i2c.c index 5ab93f63581d..00dc36a4e0cb 100644 --- a/ports/rp2/machine_i2c.c +++ b/ports/rp2/machine_i2c.c @@ -180,7 +180,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hw_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_i2c_make_new, + make_new, machine_i2c_make_new, print, machine_i2c_print, protocol, &machine_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c index 53ff7417d79a..d5175471ae80 100644 --- a/ports/rp2/machine_i2s.c +++ b/ports/rp2/machine_i2s.c @@ -1141,7 +1141,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_i2s_make_new, + make_new, machine_i2s_make_new, print, machine_i2s_print, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict diff --git a/ports/rp2/machine_pin.c b/ports/rp2/machine_pin.c index 8ccfbca3ab42..9abcf064e74e 100644 --- a/ports/rp2/machine_pin.c +++ b/ports/rp2/machine_pin.c @@ -645,7 +645,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, machine_pin_print, call, machine_pin_call, protocol, &pin_pin_p, diff --git a/ports/rp2/machine_rtc.c b/ports/rp2/machine_rtc.c index 6b2c9ac71b65..a9d3426cf838 100644 --- a/ports/rp2/machine_rtc.c +++ b/ports/rp2/machine_rtc.c @@ -119,6 +119,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - machine_rtc_make_new, + make_new, machine_rtc_make_new, locals_dict, &machine_rtc_locals_dict ); diff --git a/ports/rp2/machine_spi.c b/ports/rp2/machine_spi.c index 08c79712cf22..b2b879c9a8ed 100644 --- a/ports/rp2/machine_spi.c +++ b/ports/rp2/machine_spi.c @@ -294,7 +294,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_spi_make_new, + make_new, machine_spi_make_new, print, machine_spi_print, protocol, &machine_spi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/ports/rp2/machine_timer.c b/ports/rp2/machine_timer.c index 66f632329c72..e4fbb03af437 100644 --- a/ports/rp2/machine_timer.c +++ b/ports/rp2/machine_timer.c @@ -160,7 +160,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - machine_timer_make_new, + make_new, machine_timer_make_new, print, machine_timer_print, locals_dict, &machine_timer_locals_dict ); diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index 06f7e9aaaca2..e4881cd4f117 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -583,7 +583,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_uart_make_new, + make_new, machine_uart_make_new, print, machine_uart_print, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict diff --git a/ports/rp2/machine_wdt.c b/ports/rp2/machine_wdt.c index c224298d136b..6574a6180f8a 100644 --- a/ports/rp2/machine_wdt.c +++ b/ports/rp2/machine_wdt.c @@ -81,6 +81,6 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_wdt_type, MP_QSTR_WDT, MP_TYPE_FLAG_NONE, - machine_wdt_make_new, + make_new, machine_wdt_make_new, locals_dict, &machine_wdt_locals_dict ); diff --git a/ports/rp2/mpbthciport.c b/ports/rp2/mpbthciport.c index e37167a974de..8840fe52f124 100644 --- a/ports/rp2/mpbthciport.c +++ b/ports/rp2/mpbthciport.c @@ -103,7 +103,7 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) { // This is a statically-allocated UART (see machine_uart.c), and doesn't // contain any heap pointers other than the ringbufs (which are already // root pointers), so no need to track this as a root pointer. - mp_bthci_uart = machine_uart_type.make_new((mp_obj_t)&machine_uart_type, 2, 2, args); + mp_bthci_uart = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, 2, 2, args); // Start the HCI polling to process any initial events/packets. mp_bluetooth_hci_start_polling(); diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c index df49c881c4a4..0a94b6cc9065 100644 --- a/ports/rp2/rp2_flash.c +++ b/ports/rp2/rp2_flash.c @@ -189,6 +189,6 @@ MP_DEFINE_CONST_OBJ_TYPE( rp2_flash_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - rp2_flash_make_new, + make_new, rp2_flash_make_new, locals_dict, &rp2_flash_locals_dict ); diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index cfba9cce5ae0..87deaf7e5f8b 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -380,7 +380,7 @@ MP_DEFINE_CONST_OBJ_TYPE( rp2_pio_type, MP_QSTR_PIO, MP_TYPE_FLAG_NONE, - rp2_pio_make_new, + make_new, rp2_pio_make_new, print, rp2_pio_print, locals_dict, &rp2_pio_locals_dict ); @@ -811,7 +811,7 @@ MP_DEFINE_CONST_OBJ_TYPE( rp2_state_machine_type, MP_QSTR_StateMachine, MP_TYPE_FLAG_NONE, - rp2_state_machine_make_new, + make_new, rp2_state_machine_make_new, print, rp2_state_machine_print, locals_dict, &rp2_state_machine_locals_dict ); diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index 7a9b2299ae3b..03b47e7cf2aa 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -166,7 +166,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - mp_led_make_new, + make_new, mp_led_make_new, print, machine_led_print, call, machine_led_call, locals_dict, &machine_led_locals_dict diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 75e1a2356c4d..5f9cbfb99b85 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -291,7 +291,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, machine_pin_print, call, machine_pin_call, protocol, &pin_pin_p, diff --git a/ports/samd/samd_flash.c b/ports/samd/samd_flash.c index 9d64768cfa02..522522ef8473 100644 --- a/ports/samd/samd_flash.c +++ b/ports/samd/samd_flash.c @@ -185,6 +185,6 @@ MP_DEFINE_CONST_OBJ_TYPE( samd_flash_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - samd_flash_make_new, + make_new, samd_flash_make_new, locals_dict, &samd_flash_locals_dict ); diff --git a/ports/stm32/accel.c b/ports/stm32/accel.c index 05fd1898bc11..19e16831ead8 100644 --- a/ports/stm32/accel.c +++ b/ports/stm32/accel.c @@ -285,7 +285,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_accel_type, MP_QSTR_Accel, MP_TYPE_FLAG_NONE, - pyb_accel_make_new, + make_new, pyb_accel_make_new, locals_dict, &pyb_accel_locals_dict ); diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index e0759439d1ec..712e9b3adeb2 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -707,7 +707,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - adc_make_new, + make_new, adc_make_new, print, adc_print, locals_dict, &adc_locals_dict ); @@ -916,7 +916,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_adc_all_type, MP_QSTR_ADCAll, MP_TYPE_FLAG_NONE, - adc_all_make_new, + make_new, adc_all_make_new, locals_dict, &adc_all_locals_dict ); diff --git a/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c b/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c index 50ba81c57ac1..6ec20935f001 100644 --- a/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c +++ b/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c @@ -63,7 +63,7 @@ int mp_bluetooth_hci_controller_init(void) { // tim_ch = tim.channel(TIM_CH, pyb.Timer.PWM, pin=btclk) // tim_ch.pulse_width_percent(50) mp_obj_t args[6] = { MP_OBJ_NEW_SMALL_INT(CC2564_TIMER_BT_SLOWCLOCK_TIM), MP_OBJ_NEW_QSTR(MP_QSTR_freq), MP_OBJ_NEW_SMALL_INT(32768), MP_OBJ_NULL }; - mp_obj_t tim = pyb_timer_type.make_new(&pyb_timer_type, 1, 1, args); + mp_obj_t tim = MP_OBJ_TYPE_GET_SLOT(&pyb_timer_type, make_new)(&pyb_timer_type, 1, 1, args); mp_load_method(tim, MP_QSTR_channel, args); args[2] = MP_OBJ_NEW_SMALL_INT(CC2564_TIMER_BT_SLOWCLOCK_TIM_CH); args[3] = MP_OBJ_NEW_SMALL_INT(0); // CHANNEL_MODE_PWM_NORMAL diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index ac8d76090ee0..36ef9387f873 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -506,7 +506,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_dac_type, MP_QSTR_DAC, MP_TYPE_FLAG_NONE, - pyb_dac_make_new, + make_new, pyb_dac_make_new, print, pyb_dac_print, locals_dict, &pyb_dac_locals_dict ); diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index 0f28610cc3e7..ca23261ca736 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -663,7 +663,7 @@ MP_DEFINE_CONST_OBJ_TYPE( extint_type, MP_QSTR_ExtInt, MP_TYPE_FLAG_NONE, - extint_make_new, + make_new, extint_make_new, print, extint_obj_print, locals_dict, &extint_locals_dict ); diff --git a/ports/stm32/lcd.c b/ports/stm32/lcd.c index 5017a68fe548..e5d7f30efbd0 100644 --- a/ports/stm32/lcd.c +++ b/ports/stm32/lcd.c @@ -529,7 +529,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_lcd_type, MP_QSTR_LCD, MP_TYPE_FLAG_NONE, - pyb_lcd_make_new, + make_new, pyb_lcd_make_new, locals_dict, &pyb_lcd_locals_dict ); diff --git a/ports/stm32/led.c b/ports/stm32/led.c index 6e3229ab3218..fa211f1e145b 100644 --- a/ports/stm32/led.c +++ b/ports/stm32/led.c @@ -385,7 +385,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - led_obj_make_new, + make_new, led_obj_make_new, print, led_obj_print, locals_dict, &led_locals_dict ); diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index 3659073d06bf..000b478f86b0 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -496,7 +496,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_adc_type, MP_QSTR_ADC, MP_TYPE_FLAG_NONE, - machine_adc_make_new, + make_new, machine_adc_make_new, print, machine_adc_print, locals_dict, &machine_adc_locals_dict ); diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 7927daac1bdd..9a2d338f5498 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -240,7 +240,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_hard_i2c_make_new, + make_new, machine_hard_i2c_make_new, print, machine_hard_i2c_print, protocol, &machine_hard_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c index d68648bc348a..83ac6bc124eb 100644 --- a/ports/stm32/machine_i2s.c +++ b/ports/stm32/machine_i2s.c @@ -1118,7 +1118,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_i2s_type, MP_QSTR_I2S, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_i2s_make_new, + make_new, machine_i2s_make_new, print, machine_i2s_print, protocol, &i2s_stream_p, locals_dict, &machine_i2s_locals_dict diff --git a/ports/stm32/machine_spi.c b/ports/stm32/machine_spi.c index d64ff2af8f76..718ae1af5e5a 100644 --- a/ports/stm32/machine_spi.c +++ b/ports/stm32/machine_spi.c @@ -139,7 +139,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_hard_spi_make_new, + make_new, machine_hard_spi_make_new, print, machine_hard_spi_print, protocol, &machine_hard_spi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c index 2e0120ea8191..640d1d200fa5 100644 --- a/ports/stm32/machine_timer.c +++ b/ports/stm32/machine_timer.c @@ -140,7 +140,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - machine_timer_make_new, + make_new, machine_timer_make_new, print, machine_timer_print, locals_dict, &machine_timer_locals_dict ); diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index 4ccff8c136ad..bb35bac5cc95 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -664,7 +664,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - pyb_uart_make_new, + make_new, pyb_uart_make_new, print, pyb_uart_print, protocol, &uart_stream_p, locals_dict, &pyb_uart_locals_dict diff --git a/ports/stm32/main.c b/ports/stm32/main.c index c00123470448..7f864a018c2a 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -182,7 +182,7 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) { if (len != -1) { // Detected a littlefs filesystem so create correct block device for it mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR_len), MP_OBJ_NEW_SMALL_INT(len) }; - bdev = pyb_flash_type.make_new(&pyb_flash_type, 0, 1, args); + bdev = MP_OBJ_TYPE_GET_SLOT(&pyb_flash_type, make_new)(&pyb_flash_type, 0, 1, args); } #endif diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c index 25a955508853..556adebd8fe9 100644 --- a/ports/stm32/network_lan.c +++ b/ports/stm32/network_lan.c @@ -162,7 +162,7 @@ MP_DEFINE_CONST_OBJ_TYPE( network_lan_type, MP_QSTR_LAN, MP_TYPE_FLAG_NONE, - network_lan_make_new, + make_new, network_lan_make_new, print, network_lan_print, locals_dict, &network_lan_locals_dict ); diff --git a/ports/stm32/pin.c b/ports/stm32/pin.c index 3c3cde026568..0e4a7e993861 100644 --- a/ports/stm32/pin.c +++ b/ports/stm32/pin.c @@ -596,7 +596,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, pin_print, call, pin_call, protocol, &pin_pin_p, @@ -674,7 +674,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_af_type, MP_QSTR_PinAF, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pin_af_obj_print, locals_dict, &pin_af_locals_dict ); diff --git a/ports/stm32/pin_named_pins.c b/ports/stm32/pin_named_pins.c index 1a35ec57875f..8eeb4ed32b11 100644 --- a/ports/stm32/pin_named_pins.c +++ b/ports/stm32/pin_named_pins.c @@ -35,7 +35,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_cpu_pins_obj_type, MP_QSTR_cpu, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &pin_cpu_pins_locals_dict ); @@ -43,7 +42,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pin_board_pins_obj_type, MP_QSTR_board, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &pin_board_pins_locals_dict ); diff --git a/ports/stm32/pyb_can.c b/ports/stm32/pyb_can.c index a07fc921649c..69e807c79dfd 100644 --- a/ports/stm32/pyb_can.c +++ b/ports/stm32/pyb_can.c @@ -1076,7 +1076,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_can_type, MP_QSTR_CAN, MP_TYPE_FLAG_NONE, - pyb_can_make_new, + make_new, pyb_can_make_new, print, pyb_can_print, protocol, &can_stream_p, locals_dict, &pyb_can_locals_dict diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 9071d92944ee..0cbb640473b8 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -1108,7 +1108,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - pyb_i2c_make_new, + make_new, pyb_i2c_make_new, print, pyb_i2c_print, locals_dict, &pyb_i2c_locals_dict ); diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c index a225bd84e753..54582f8e5414 100644 --- a/ports/stm32/pyb_spi.c +++ b/ports/stm32/pyb_spi.c @@ -354,7 +354,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - pyb_spi_make_new, + make_new, pyb_spi_make_new, print, pyb_spi_print, protocol, &pyb_spi_p, locals_dict, &pyb_spi_locals_dict diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c index f501ec23b1b3..aacfc3805e97 100644 --- a/ports/stm32/rtc.c +++ b/ports/stm32/rtc.c @@ -841,6 +841,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_rtc_type, MP_QSTR_RTC, MP_TYPE_FLAG_NONE, - pyb_rtc_make_new, + make_new, pyb_rtc_make_new, locals_dict, &pyb_rtc_locals_dict ); diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index cbf1ade5c5b7..964ed49a67dd 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -876,7 +876,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_sdcard_type, MP_QSTR_SDCard, MP_TYPE_FLAG_NONE, - pyb_sdcard_make_new, + make_new, pyb_sdcard_make_new, locals_dict, &pyb_sdcard_locals_dict ); #endif @@ -886,7 +886,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_mmcard_type, MP_QSTR_MMCard, MP_TYPE_FLAG_NONE, - pyb_mmcard_make_new, + make_new, pyb_mmcard_make_new, locals_dict, &pyb_sdcard_locals_dict ); #endif diff --git a/ports/stm32/servo.c b/ports/stm32/servo.c index 1b0ca0a88224..e0aa2d6b69f8 100644 --- a/ports/stm32/servo.c +++ b/ports/stm32/servo.c @@ -340,7 +340,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_servo_type, MP_QSTR_Servo, MP_TYPE_FLAG_NONE, - pyb_servo_make_new, + make_new, pyb_servo_make_new, print, pyb_servo_print, locals_dict, &pyb_servo_locals_dict ); diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c index a0154408dd5f..848602a7878e 100644 --- a/ports/stm32/storage.c +++ b/ports/stm32/storage.c @@ -457,7 +457,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_flash_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, - pyb_flash_make_new, + make_new, pyb_flash_make_new, print, pyb_flash_print, locals_dict, &pyb_flash_locals_dict ); diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index 91c88df1b372..7a6ccd4dfd2d 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -1475,7 +1475,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - pyb_timer_make_new, + make_new, pyb_timer_make_new, print, pyb_timer_print, locals_dict, &pyb_timer_locals_dict ); @@ -1615,7 +1615,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_channel_type, MP_QSTR_TimerChannel, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pyb_timer_channel_print, locals_dict, &pyb_timer_channel_locals_dict ); diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index e389ef68f2aa..12c5e497de84 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -940,7 +940,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_usb_vcp_type, MP_QSTR_USB_VCP, MP_TYPE_FLAG_ITER_IS_STREAM, - pyb_usb_vcp_make_new, + make_new, pyb_usb_vcp_make_new, print, pyb_usb_vcp_print, protocol, &pyb_usb_vcp_stream_p, locals_dict, &pyb_usb_vcp_locals_dict @@ -1080,7 +1080,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_usb_hid_type, MP_QSTR_USB_HID, MP_TYPE_FLAG_NONE, - pyb_usb_hid_make_new, + make_new, pyb_usb_hid_make_new, protocol, &pyb_usb_hid_stream_p, locals_dict, &pyb_usb_hid_locals_dict ); diff --git a/ports/stm32/usrsw.c b/ports/stm32/usrsw.c index 7d406c0ecd71..170c01bd6d04 100644 --- a/ports/stm32/usrsw.c +++ b/ports/stm32/usrsw.c @@ -138,7 +138,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_switch_type, MP_QSTR_Switch, MP_TYPE_FLAG_NONE, - pyb_switch_make_new, + make_new, pyb_switch_make_new, print, pyb_switch_print, call, pyb_switch_call, locals_dict, &pyb_switch_locals_dict diff --git a/ports/stm32/wdt.c b/ports/stm32/wdt.c index 09780ea9d3cc..e541e4d36b4f 100644 --- a/ports/stm32/wdt.c +++ b/ports/stm32/wdt.c @@ -106,6 +106,6 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_wdt_type, MP_QSTR_WDT, MP_TYPE_FLAG_NONE, - pyb_wdt_make_new, + make_new, pyb_wdt_make_new, locals_dict, &pyb_wdt_locals_dict ); diff --git a/ports/teensy/led.c b/ports/teensy/led.c index dd4c65da39e1..46c6ae492f85 100644 --- a/ports/teensy/led.c +++ b/ports/teensy/led.c @@ -138,7 +138,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_led_type, MP_QSTR_LED, MP_TYPE_FLAG_NONE, - led_obj_make_new, + make_new, led_obj_make_new, print, led_obj_print, locals_dict, &led_locals_dict ); diff --git a/ports/teensy/timer.c b/ports/teensy/timer.c index a0f490d925fb..8c7609e4479e 100644 --- a/ports/teensy/timer.c +++ b/ports/teensy/timer.c @@ -750,7 +750,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_type, MP_QSTR_Timer, MP_TYPE_FLAG_NONE, - pyb_timer_make_new, + make_new, pyb_timer_make_new, print, pyb_timer_print, locals_dict, &pyb_timer_locals_dict ); @@ -894,7 +894,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( pyb_timer_channel_type, MP_QSTR_TimerChannel, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, pyb_timer_channel_print, locals_dict, &pyb_timer_channel_locals_dict ); diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c index db5b8e2f4433..e71f676d0ae1 100644 --- a/ports/teensy/uart.c +++ b/ports/teensy/uart.c @@ -487,7 +487,7 @@ MP_DEFINE_CONST_OBJ_TYPE( pyb_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_NONE, - pyb_uart_make_new, + make_new, pyb_uart_make_new, print, pyb_uart_print, locals_dict, &pyb_uart_locals_dict ); diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 7b4c0c0bf48e..8b7fc7de6780 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -110,7 +110,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_stest_fileio, MP_QSTR_stest_fileio, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, protocol, &fileio_stream_p, locals_dict, &rawfile_locals_dict ); @@ -140,7 +139,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_stest_textio2, MP_QSTR_stest_textio2, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, protocol, &textio_stream_p2, locals_dict, &rawfile_locals_dict2 ); diff --git a/ports/unix/main.c b/ports/unix/main.c index 4f019b6c2c30..44823ee17477 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -518,7 +518,7 @@ MP_NOINLINE int main_(int argc, char **argv) { { // Mount the host FS at the root of our internal VFS mp_obj_t args[2] = { - mp_type_vfs_posix.make_new(&mp_type_vfs_posix, 0, 0, NULL), + MP_OBJ_TYPE_GET_SLOT(&mp_type_vfs_posix, make_new)(&mp_type_vfs_posix, 0, 0, NULL), MP_OBJ_NEW_QSTR(MP_QSTR__slash_), }; mp_vfs_mount(2, args, (mp_map_t *)&mp_const_empty_map); diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 04152f1ad41f..3df748b80d95 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -425,7 +425,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ffimod_type, MP_QSTR_ffimod, MP_TYPE_FLAG_NONE, - ffimod_make_new, + make_new, ffimod_make_new, print, ffimod_print, locals_dict, &ffimod_locals_dict ); @@ -535,7 +535,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ffifunc_type, MP_QSTR_ffifunc, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, ffifunc_print, call, ffifunc_call ); @@ -563,7 +562,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( fficallback_type, MP_QSTR_fficallback, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, fficallback_print, locals_dict, &fficallback_locals_dict ); @@ -601,7 +599,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( ffivar_type, MP_QSTR_ffivar, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, ffivar_print, locals_dict, &ffivar_locals_dict ); @@ -613,8 +610,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( opaque_type, MP_QSTR_opaqueval, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, - // .print = opaque_print, + make_new, // .print = opaque_print, ); */ diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index e6b874b235ec..5988876f888a 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -178,7 +178,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( jclass_type, MP_QSTR_jclass, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, jclass_print, attr, jclass_attr, call, jclass_call, @@ -326,7 +325,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( jobject_type, MP_QSTR_jobject, MP_TYPE_FLAG_ITER_IS_GETITER, - MP_TYPE_NULL_MAKE_NEW, print, jobject_print, unary_op, jobject_unary_op, attr, jobject_attr, @@ -575,7 +573,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( jmethod_type, MP_QSTR_jmethod, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, jmethod_print, call, jmethod_call, // .attr = jobject_attr, diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index 674841bf1871..8f71813e70ae 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -315,7 +315,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_poll, MP_QSTR_poll, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, poll_iternext, locals_dict, &poll_locals_dict ); diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index dfbf15cd3efd..a32fc6016313 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -520,7 +520,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_socket, MP_QSTR_socket, MP_TYPE_FLAG_NONE, - socket_make_new, + make_new, socket_make_new, print, socket_print, protocol, &usocket_stream_p, locals_dict, &usocket_locals_dict diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c index a844eceb50c1..8f0f25257ba5 100644 --- a/ports/zephyr/machine_i2c.c +++ b/ports/zephyr/machine_i2c.c @@ -130,7 +130,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, - machine_hard_i2c_make_new, + make_new, machine_hard_i2c_make_new, print, machine_hard_i2c_print, protocol, &machine_hard_i2c_p, locals_dict, &mp_machine_i2c_locals_dict diff --git a/ports/zephyr/machine_pin.c b/ports/zephyr/machine_pin.c index 3114ac36fd00..be0698651bbf 100644 --- a/ports/zephyr/machine_pin.c +++ b/ports/zephyr/machine_pin.c @@ -289,7 +289,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_pin_type, MP_QSTR_Pin, MP_TYPE_FLAG_NONE, - mp_pin_make_new, + make_new, mp_pin_make_new, print, machine_pin_print, call, machine_pin_call, protocol, &machine_pin_pin_p, diff --git a/ports/zephyr/machine_spi.c b/ports/zephyr/machine_spi.c index d990ed9c150f..19d4ae6dee68 100644 --- a/ports/zephyr/machine_spi.c +++ b/ports/zephyr/machine_spi.c @@ -201,7 +201,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_hard_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - machine_hard_spi_make_new, + make_new, machine_hard_spi_make_new, print, machine_hard_spi_print, protocol, &machine_hard_spi_p, locals_dict, &mp_machine_spi_locals_dict diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c index 867c5ae8863a..b989c0f4817c 100644 --- a/ports/zephyr/machine_uart.c +++ b/ports/zephyr/machine_uart.c @@ -158,7 +158,7 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, - machine_uart_make_new, + make_new, machine_uart_make_new, print, machine_uart_print, protocol, &uart_stream_p, locals_dict, &machine_uart_locals_dict diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c index c638f389206e..869449e7df47 100644 --- a/ports/zephyr/main.c +++ b/ports/zephyr/main.c @@ -104,11 +104,11 @@ STATIC void vfs_init(void) { #ifdef CONFIG_DISK_DRIVER_SDMMC mp_obj_t args[] = { mp_obj_new_str(CONFIG_SDMMC_VOLUME_NAME, strlen(CONFIG_SDMMC_VOLUME_NAME)) }; - bdev = zephyr_disk_access_type.make_new(&zephyr_disk_access_type, ARRAY_SIZE(args), 0, args); + bdev = MP_OBJ_TYPE_GET_SLOT(&zephyr_disk_access_type, make_new)(&zephyr_disk_access_type, ARRAY_SIZE(args), 0, args); mount_point_str = "/sd"; #elif defined(CONFIG_FLASH_MAP) && FLASH_AREA_LABEL_EXISTS(storage) mp_obj_t args[] = { MP_OBJ_NEW_SMALL_INT(FLASH_AREA_ID(storage)), MP_OBJ_NEW_SMALL_INT(4096) }; - bdev = zephyr_flash_area_type.make_new(&zephyr_flash_area_type, ARRAY_SIZE(args), 0, args); + bdev = MP_OBJ_TYPE_GET_SLOT(&zephyr_flash_area_type, make_new)(&zephyr_flash_area_type, ARRAY_SIZE(args), 0, args); mount_point_str = "/flash"; #endif diff --git a/ports/zephyr/modusocket.c b/ports/zephyr/modusocket.c index 77f839fdd510..c79f73a9d275 100644 --- a/ports/zephyr/modusocket.c +++ b/ports/zephyr/modusocket.c @@ -357,7 +357,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( socket_type, MP_QSTR_socket, MP_TYPE_FLAG_NONE, - socket_make_new, + make_new, socket_make_new, print, socket_print, protocol, &socket_stream_p, locals_dict, &socket_locals_dict diff --git a/ports/zephyr/modzsensor.c b/ports/zephyr/modzsensor.c index beb4d6ad7903..e35a1716f473 100644 --- a/ports/zephyr/modzsensor.c +++ b/ports/zephyr/modzsensor.c @@ -109,7 +109,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( sensor_type, MP_QSTR_Sensor, MP_TYPE_FLAG_NONE, - sensor_make_new, + make_new, sensor_make_new, locals_dict, &sensor_locals_dict ); diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c index 6ab8271d3476..498fea6fb1c8 100644 --- a/ports/zephyr/zephyr_storage.c +++ b/ports/zephyr/zephyr_storage.c @@ -132,7 +132,7 @@ MP_DEFINE_CONST_OBJ_TYPE( zephyr_disk_access_type, MP_QSTR_DiskAccess, MP_TYPE_FLAG_NONE, - zephyr_disk_access_make_new, + make_new, zephyr_disk_access_make_new, print, zephyr_disk_access_print, locals_dict, &zephyr_disk_access_locals_dict ); @@ -254,7 +254,7 @@ MP_DEFINE_CONST_OBJ_TYPE( zephyr_flash_area_type, MP_QSTR_FlashArea, MP_TYPE_FLAG_NONE, - zephyr_flash_area_make_new, + make_new, zephyr_flash_area_make_new, print, zephyr_flash_area_print, locals_dict, &zephyr_flash_area_locals_dict ); diff --git a/py/builtinevex.c b/py/builtinevex.c index 403cd95a9dee..173978ef5221 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -41,8 +41,7 @@ typedef struct _mp_obj_code_t { STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_code, MP_QSTR_code, - MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW + MP_TYPE_FLAG_NONE ); STATIC mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj_dict_t *locals) { diff --git a/py/dynruntime.h b/py/dynruntime.h index be573bde2ad4..8564715c0b59 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -105,7 +105,7 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_const_none ((mp_obj_t)mp_fun_table.const_none) #define mp_const_false ((mp_obj_t)mp_fun_table.const_false) #define mp_const_true ((mp_obj_t)mp_fun_table.const_true) -#define mp_const_empty_bytes (mp_type_bytes.make_new(NULL, 0, 0, NULL)) +#define mp_const_empty_bytes (MP_OBJ_TYPE_GET_SLOT(&mp_type_bytes, make_new)(NULL, 0, 0, NULL)) #define mp_const_empty_tuple (mp_fun_table.new_tuple(0, NULL)) #define mp_obj_new_bool(b) ((b) ? (mp_obj_t)mp_fun_table.const_true : (mp_obj_t)mp_fun_table.const_false) diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 152323b5ca96..06e9f1acb5e3 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -547,7 +547,7 @@ STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t if (n_args > 1) { mp_raise_TypeError(MP_ERROR_TEXT("must use keyword argument for key function")); } - mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args); + mp_obj_t self = mp_obj_list_make_new(&mp_type_list, 1, 0, args); mp_obj_list_sort(1, &self, kwargs); return self; diff --git a/py/modio.c b/py/modio.c index a1e04e4cac54..9ec6bbcc4ecd 100644 --- a/py/modio.c +++ b/py/modio.c @@ -101,7 +101,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_iobase, MP_QSTR_IOBase, MP_TYPE_FLAG_NONE, - iobase_make_new, + make_new, iobase_make_new, protocol, &iobase_p ); @@ -196,7 +196,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_bufwriter, MP_QSTR_BufferedWriter, MP_TYPE_FLAG_NONE, - bufwriter_make_new, + make_new, bufwriter_make_new, protocol, &bufwriter_stream_p, locals_dict, &bufwriter_locals_dict ); diff --git a/py/modthread.c b/py/modthread.c index 3116fe6bd9db..51d63e470372 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -120,7 +120,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_thread_lock, MP_QSTR_lock, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, locals_dict, &thread_lock_locals_dict ); diff --git a/py/obj.h b/py/obj.h index b1d722080c66..34adfbd0f042 100644 --- a/py/obj.h +++ b/py/obj.h @@ -594,15 +594,15 @@ struct _mp_obj_type_t { // The name of this type, a qstr. uint16_t name; - // Corresponds to __new__ and __init__ special methods, to make an instance of the type. - mp_make_new_fun_t make_new; - // Slots: For the rest of the fields, the slot index points to the // relevant function in the variable-length "slots" field. Ideally these // would be only 4 bits, but the extra overhead of accessing them adds // more code, and we also need to be able to take the address of them for // mp_obj_class_lookup. + // Corresponds to __new__ and __init__ special methods, to make an instance of the type. + uint8_t slot_index_make_new; + // Corresponds to __repr__ and __str__ special methods. uint8_t slot_index_print; @@ -673,8 +673,8 @@ typedef struct _mp_obj_empty_type_t { mp_obj_base_t base; uint16_t flags; uint16_t name; - mp_make_new_fun_t make_new; + uint8_t slot_index_make_new; uint8_t slot_index_print; uint8_t slot_index_call; uint8_t slot_index_unary_op; @@ -694,8 +694,8 @@ typedef struct _mp_obj_full_type_t { mp_obj_base_t base; uint16_t flags; uint16_t name; - mp_make_new_fun_t make_new; + uint8_t slot_index_make_new; uint8_t slot_index_print; uint8_t slot_index_call; uint8_t slot_index_unary_op; @@ -712,8 +712,7 @@ typedef struct _mp_obj_full_type_t { const void *slots[11]; } mp_obj_full_type_t; -#define MP_TYPE_NULL_MAKE_NEW (NULL) - +#define _MP_OBJ_TYPE_SLOT_TYPE_make_new (mp_make_new_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_print (mp_print_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_call (mp_call_fun_t) #define _MP_OBJ_TYPE_SLOT_TYPE_unary_op (mp_unary_op_fun_t) @@ -730,42 +729,41 @@ typedef struct _mp_obj_full_type_t { // Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE. // Generated with: // for i in range(13): -// print(f"#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_{i}(_struct_type, _typename, _name, _flags, _make_new{''.join(f', f{j+1}, v{j+1}' for j in range(i))}) const _struct_type _typename = {{ .base = {{ &mp_type_type }}, .name = _name, .flags = _flags, .make_new = _make_new{''.join(f', .slot_index_##f{j+1} = {j+1}' for j in range(i))}{', .slots = { ' + ''.join(f'v{j+1}, ' for j in range(i)) + '}' if i else '' } }}") -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0(_struct_type, _typename, _name, _flags, _make_new) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_1(_struct_type, _typename, _name, _flags, _make_new, f1, v1) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slots = { v1, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_2(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slots = { v1, v2, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_3(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slots = { v1, v2, v3, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_4(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slots = { v1, v2, v3, v4, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_5(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slots = { v1, v2, v3, v4, v5, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_6(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slots = { v1, v2, v3, v4, v5, v6, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slots = { v1, v2, v3, v4, v5, v6, v7, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_8(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_9(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_10(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, } } -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slot_index_##f12 = 12, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, } } +// print(f"#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_{i}(_struct_type, _typename, _name, _flags{''.join(f', f{j+1}, v{j+1}' for j in range(i))}) const _struct_type _typename = {{ .base = {{ &mp_type_type }}, .name = _name, .flags = _flags{''.join(f', .slot_index_##f{j+1} = {j+1}' for j in range(i))}{', .slots = { ' + ''.join(f'v{j+1}, ' for j in range(i)) + '}' if i else '' } }}") +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0(_struct_type, _typename, _name, _flags) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_1(_struct_type, _typename, _name, _flags, f1, v1) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slots = { v1, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_2(_struct_type, _typename, _name, _flags, f1, v1, f2, v2) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slots = { v1, v2, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_3(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slots = { v1, v2, v3, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_4(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slots = { v1, v2, v3, v4, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_5(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slots = { v1, v2, v3, v4, v5, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_6(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slots = { v1, v2, v3, v4, v5, v6, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slots = { v1, v2, v3, v4, v5, v6, v7, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_8(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_9(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_10(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, } } +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slot_index_##f12 = 12, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, } } #define MP_OBJ_TYPE_HAS_SLOT(t, f) ((t)->slot_index_##f) #define MP_OBJ_TYPE_GET_SLOT(t, f) (_MP_OBJ_TYPE_SLOT_TYPE_##f(t)->slots[(t)->slot_index_##f - 1]) #define MP_OBJ_TYPE_GET_SLOT_OR_NULL(t, f) (_MP_OBJ_TYPE_SLOT_TYPE_##f(MP_OBJ_TYPE_HAS_SLOT(t, f) ? MP_OBJ_TYPE_GET_SLOT(t, f) : NULL)) #define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->slot_index_##f = (n) + 1, (t)->slots[(t)->slot_index_##f - 1] = (void *)v) #define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, slot_index_##f)) -// For everything except make_new, the offset is to the uint8_t index. For make_new, we need to check the pointer. -#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(uint8_t *)((char *)(t) + (offset)) != 0 || (offset == offsetof(mp_obj_type_t, make_new) && t->make_new)) +#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(uint8_t *)((char *)(t) + (offset)) != 0) // Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x // This macro evaluates to MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N, where N is the value -// of the 30th argument (30 is 13*2 + 4). -#define MP_DEFINE_CONST_OBJ_TYPE_NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, N, ...) MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N +// of the 29th argument (29 is 13*2 + 3). +#define MP_DEFINE_CONST_OBJ_TYPE_NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, N, ...) MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N // These macros are used to define a object type in ROM. // Invoke as MP_DEFINE_CONST_OBJ_TYPE(_typename, _name, _flags, _make_new [, slot, func]*) // They use the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_* // macro to use based on the number of arguments. It works by shifting the // numeric values 12, 11, ... 0 by the number of arguments, such that the -// 30th argument ends up being the number to use. The _INV values are +// 29th argument ends up being the number to use. The _INV values are // placeholders because the slot arguments come in pairs. #define MP_DEFINE_CONST_OBJ_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_type_t, __VA_ARGS__)) #define MP_DEFINE_CONST_OBJ_FULL_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_full_type_t, __VA_ARGS__)) @@ -916,7 +914,7 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); #define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_exact_type(o, &mp_type_int)) #define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_exact_type(o, &mp_type_str)) #define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, binary_op) == mp_obj_str_binary_op)) -#define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new) +#define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, make_new) == mp_obj_dict_make_new) #define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); @@ -1032,7 +1030,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in); mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in); // exception -#define mp_obj_is_native_exception_instance(o) (mp_obj_get_type(o)->make_new == mp_obj_exception_make_new) +#define mp_obj_is_native_exception_instance(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), make_new) == mp_obj_exception_make_new) bool mp_obj_is_exception_type(mp_obj_t self_in); bool mp_obj_is_exception_instance(mp_obj_t self_in); bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type); @@ -1044,7 +1042,7 @@ mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in); void mp_init_emergency_exception_buf(void); static inline mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { - assert(exc_type->make_new == mp_obj_exception_make_new); + assert(MP_OBJ_TYPE_GET_SLOT_OR_NULL(exc_type, make_new) == mp_obj_exception_make_new); return mp_obj_exception_make_new(exc_type, 1, 0, &arg); } diff --git a/py/objarray.c b/py/objarray.c index 0d1032929f48..42fc0749d2b2 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -575,7 +575,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_array, MP_QSTR_array, MP_TYPE_FLAG_ITER_IS_GETITER, - array_make_new, + make_new, array_make_new, print, array_print, iter, array_iterator_new, unary_op, array_unary_op, @@ -591,7 +591,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_bytearray, MP_QSTR_bytearray, MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, - bytearray_make_new, + make_new, bytearray_make_new, print, array_print, iter, array_iterator_new, unary_op, array_unary_op, @@ -619,7 +619,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_memoryview, MP_QSTR_memoryview, MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, - memoryview_make_new, + make_new, memoryview_make_new, iter, array_iterator_new, unary_op, array_unary_op, binary_op, array_binary_op, @@ -677,7 +677,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_array_it, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, array_it_iternext ); diff --git a/py/objattrtuple.c b/py/objattrtuple.c index 2e207f4cf0c4..fbe04bedb877 100644 --- a/py/objattrtuple.c +++ b/py/objattrtuple.c @@ -84,7 +84,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_attrtuple, MP_QSTR_tuple, MP_TYPE_FLAG_ITER_IS_GETITER, - MP_TYPE_NULL_MAKE_NEW, // reuse tuple to save on a qstr print, mp_obj_attrtuple_print, unary_op, mp_obj_tuple_unary_op, diff --git a/py/objbool.c b/py/objbool.c index 5d014bbb8eaf..3267ff98bb8a 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -89,7 +89,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_bool, MP_QSTR_bool, MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, - bool_make_new, + make_new, bool_make_new, print, bool_print, unary_op, bool_unary_op, binary_op, bool_binary_op diff --git a/py/objboundmeth.c b/py/objboundmeth.c index f4b3b9b7df9c..8486f876f9a5 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -111,7 +111,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_bound_meth, MP_QSTR_bound_method, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, BOUND_METH_TYPE_PRINT BOUND_METH_TYPE_ATTR call, bound_meth_call diff --git a/py/objcell.c b/py/objcell.c index b100fae4fe99..0a74e29d2064 100644 --- a/py/objcell.c +++ b/py/objcell.c @@ -48,7 +48,7 @@ STATIC void cell_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t k STATIC MP_DEFINE_CONST_OBJ_TYPE( // cell representation is just value in < > - mp_type_cell, MP_QSTR_, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW + mp_type_cell, MP_QSTR_, MP_TYPE_FLAG_NONE CELL_TYPE_PRINT ); diff --git a/py/objclosure.c b/py/objclosure.c index 45a3e83c462d..6059d18100e0 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -99,7 +99,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_closure, MP_QSTR_closure, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, CLOSURE_TYPE_ATTR CLOSURE_TYPE_PRINT call, closure_call diff --git a/py/objcomplex.c b/py/objcomplex.c index cf213d718a79..ddd103eeb46e 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -152,7 +152,8 @@ STATIC void complex_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_complex, MP_QSTR_complex, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, complex_make_new, + mp_type_complex, MP_QSTR_complex, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + make_new, complex_make_new, print, complex_print, unary_op, complex_unary_op, binary_op, complex_binary_op, diff --git a/py/objdeque.c b/py/objdeque.c index 1a8f76ca110b..8b52b8d38730 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -159,7 +159,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_deque, MP_QSTR_deque, MP_TYPE_FLAG_NONE, - deque_make_new, + make_new, deque_make_new, unary_op, deque_unary_op, locals_dict, &deque_locals_dict ); diff --git a/py/objdict.c b/py/objdict.c index 7755d7b786d4..68c33961c70c 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -465,7 +465,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict_view_it, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, dict_view_it_iternext ); @@ -517,7 +516,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict_view, MP_QSTR_dict_view, MP_TYPE_FLAG_ITER_IS_GETITER, - MP_TYPE_NULL_MAKE_NEW, print, dict_view_print, binary_op, dict_view_binary_op, iter, dict_view_getiter @@ -592,7 +590,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict, MP_QSTR_dict, MP_TYPE_FLAG_ITER_IS_GETITER, - mp_obj_dict_make_new, + make_new, mp_obj_dict_make_new, print, dict_print, unary_op, dict_unary_op, binary_op, dict_binary_op, @@ -606,7 +604,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_ordereddict, MP_QSTR_OrderedDict, MP_TYPE_FLAG_ITER_IS_GETITER, - mp_obj_dict_make_new, + make_new, mp_obj_dict_make_new, print, dict_print, unary_op, dict_unary_op, binary_op, dict_binary_op, diff --git a/py/objenumerate.c b/py/objenumerate.c index eea9e3e381ed..40bed919ed75 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -71,7 +71,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_enumerate, MP_QSTR_enumerate, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - enumerate_make_new, + make_new, enumerate_make_new, iter, enumerate_iternext ); diff --git a/py/objexcept.c b/py/objexcept.c index 190213e12f61..3b76ae62ccc6 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -288,7 +288,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_BaseException, MP_QSTR_BaseException, MP_TYPE_FLAG_NONE, - mp_obj_exception_make_new, + make_new, mp_obj_exception_make_new, print, mp_obj_exception_print, attr, mp_obj_exception_attr ); @@ -375,12 +375,12 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) // *FORMAT-ON* mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type) { - assert(exc_type->make_new == mp_obj_exception_make_new); + assert(MP_OBJ_TYPE_GET_SLOT_OR_NULL(exc_type, make_new) == mp_obj_exception_make_new); return mp_obj_exception_make_new(exc_type, 0, 0, NULL); } mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args) { - assert(exc_type->make_new == mp_obj_exception_make_new); + assert(MP_OBJ_TYPE_GET_SLOT_OR_NULL(exc_type, make_new) == mp_obj_exception_make_new); return mp_obj_exception_make_new(exc_type, n_args, 0, args); } @@ -388,7 +388,7 @@ mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { // Check that the given type is an exception type - assert(exc_type->make_new == mp_obj_exception_make_new); + assert(MP_OBJ_TYPE_GET_SLOT_OR_NULL(exc_type, make_new) == mp_obj_exception_make_new); // Try to allocate memory for the message mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); @@ -467,7 +467,7 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_er assert(fmt != NULL); // Check that the given type is an exception type - assert(exc_type->make_new == mp_obj_exception_make_new); + assert(MP_OBJ_TYPE_GET_SLOT_OR_NULL(exc_type, make_new) == mp_obj_exception_make_new); // Try to allocate memory for the message mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); @@ -538,7 +538,7 @@ bool mp_obj_is_exception_type(mp_obj_t self_in) { if (mp_obj_is_type(self_in, &mp_type_type)) { // optimisation when self_in is a builtin exception mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); - if (self->make_new == mp_obj_exception_make_new) { + if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(self, make_new) == mp_obj_exception_make_new) { return true; } } diff --git a/py/objexcept.h b/py/objexcept.h index 5d56d67d7314..d532f6660924 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -41,7 +41,8 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); #define MP_DEFINE_EXCEPTION(exc_name, base_name) \ - MP_DEFINE_CONST_OBJ_TYPE(mp_type_##exc_name, MP_QSTR_##exc_name, MP_TYPE_FLAG_NONE, mp_obj_exception_make_new, \ + MP_DEFINE_CONST_OBJ_TYPE(mp_type_##exc_name, MP_QSTR_##exc_name, MP_TYPE_FLAG_NONE, \ + make_new, mp_obj_exception_make_new, \ print, mp_obj_exception_print, \ attr, mp_obj_exception_attr, \ parent, &mp_type_##base_name \ diff --git a/py/objfilter.c b/py/objfilter.c index bfe651f40d03..2a657fde4b71 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -64,7 +64,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_filter, MP_QSTR_filter, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - filter_make_new, + make_new, filter_make_new, iter, filter_iternext ); diff --git a/py/objfloat.c b/py/objfloat.c index 9ecbab7a4ded..c862b4843b27 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -183,7 +183,8 @@ STATIC mp_obj_t float_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_float, MP_QSTR_float, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, float_make_new, + mp_type_float, MP_QSTR_float, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + make_new, float_make_new, print, float_print, unary_op, float_unary_op, binary_op, float_binary_op diff --git a/py/objfun.c b/py/objfun.c index d6ff354575bf..390ddaa2d282 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -57,7 +57,7 @@ STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_fun_builtin_0, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + mp_type_fun_builtin_0, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, call, fun_builtin_0_call, unary_op, mp_generic_unary_op ); @@ -70,7 +70,7 @@ STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_fun_builtin_1, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + mp_type_fun_builtin_1, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, call, fun_builtin_1_call, unary_op, mp_generic_unary_op ); @@ -83,7 +83,7 @@ STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_fun_builtin_2, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + mp_type_fun_builtin_2, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, call, fun_builtin_2_call, unary_op, mp_generic_unary_op ); @@ -96,7 +96,7 @@ STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_fun_builtin_3, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + mp_type_fun_builtin_3, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, call, fun_builtin_3_call, unary_op, mp_generic_unary_op ); @@ -125,7 +125,7 @@ STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_fun_builtin_var, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, MP_TYPE_NULL_MAKE_NEW, + mp_type_fun_builtin_var, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN, call, fun_builtin_var_call, unary_op, mp_generic_unary_op ); @@ -368,7 +368,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_fun_bc, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, FUN_BC_TYPE_PRINT FUN_BC_TYPE_ATTR call, fun_bc_call, @@ -431,7 +430,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_fun_native, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, FUN_BC_TYPE_PRINT FUN_BC_TYPE_ATTR call, fun_native_call, @@ -542,7 +540,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_fun_asm, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, call, fun_asm_call, unary_op, mp_generic_unary_op ); diff --git a/py/objgenerator.c b/py/objgenerator.c index d8515c13ce25..8175dbd683db 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -80,7 +80,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_gen_wrap, MP_QSTR_generator, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, GEN_WRAP_TYPE_ATTR call, gen_wrap_call, unary_op, mp_generic_unary_op @@ -146,7 +145,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_native_gen_wrap, MP_QSTR_generator, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, call, native_gen_wrap_call, NATIVE_GEN_WRAP_TYPE_ATTR unary_op, mp_generic_unary_op @@ -371,7 +369,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_gen_instance, MP_QSTR_generator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, print, gen_instance_print, unary_op, mp_generic_unary_op, iter, gen_instance_iternext, diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c index 134cbcd6299d..c598d1daaca9 100644 --- a/py/objgetitemiter.c +++ b/py/objgetitemiter.c @@ -60,7 +60,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_it, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, it_iternext ); diff --git a/py/objint.c b/py/objint.c index f06bc441f15d..1a3ad8694717 100644 --- a/py/objint.c +++ b/py/objint.c @@ -461,7 +461,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_int, MP_QSTR_int, MP_TYPE_FLAG_NONE, - mp_obj_int_make_new, + make_new, mp_obj_int_make_new, print, mp_obj_int_print, unary_op, mp_obj_int_unary_op, binary_op, mp_obj_int_binary_op, diff --git a/py/objlist.c b/py/objlist.c index 8d18344ea8a7..18da91ba3abc 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -71,7 +71,7 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { return list; } -STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)type_in; mp_arg_check_num(n_args, n_kw, 0, 1, false); @@ -456,7 +456,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_list, MP_QSTR_list, MP_TYPE_FLAG_ITER_IS_GETITER, - list_make_new, + make_new, mp_obj_list_make_new, print, list_print, unary_op, list_unary_op, binary_op, list_binary_op, diff --git a/py/objlist.h b/py/objlist.h index a43663db76f8..a3bba68028f8 100644 --- a/py/objlist.h +++ b/py/objlist.h @@ -36,5 +36,6 @@ typedef struct _mp_obj_list_t { } mp_obj_list_t; void mp_obj_list_init(mp_obj_list_t *o, size_t n); +mp_obj_t mp_obj_list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); #endif // MICROPY_INCLUDED_PY_OBJLIST_H diff --git a/py/objmap.c b/py/objmap.c index 115832e387e5..e7e594cd2c54 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -67,6 +67,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_map, MP_QSTR_map, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - map_make_new, + make_new, map_make_new, iter, map_iternext ); diff --git a/py/objmodule.c b/py/objmodule.c index 6fc3653e6a24..d14a59b8632c 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -134,7 +134,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_module, MP_QSTR_module, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, module_print, attr, module_attr ); diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 3b45d8f76f29..75e21494b4d3 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -157,14 +157,14 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t type->base.type = &mp_type_type; type->flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple type->name = name; - type->make_new = namedtuple_make_new; - MP_OBJ_TYPE_SET_SLOT(type, print, namedtuple_print, 0); - MP_OBJ_TYPE_SET_SLOT(type, unary_op, mp_obj_tuple_unary_op, 1); - MP_OBJ_TYPE_SET_SLOT(type, binary_op, mp_obj_tuple_binary_op, 2); - MP_OBJ_TYPE_SET_SLOT(type, attr, namedtuple_attr, 3); - MP_OBJ_TYPE_SET_SLOT(type, subscr, mp_obj_tuple_subscr, 4); - MP_OBJ_TYPE_SET_SLOT(type, iter, mp_obj_tuple_getiter, 5); - MP_OBJ_TYPE_SET_SLOT(type, parent, &mp_type_tuple, 6); + MP_OBJ_TYPE_SET_SLOT(type, make_new, namedtuple_make_new, 0); + MP_OBJ_TYPE_SET_SLOT(type, print, namedtuple_print, 1); + MP_OBJ_TYPE_SET_SLOT(type, unary_op, mp_obj_tuple_unary_op, 2); + MP_OBJ_TYPE_SET_SLOT(type, binary_op, mp_obj_tuple_binary_op, 3); + MP_OBJ_TYPE_SET_SLOT(type, attr, namedtuple_attr, 4); + MP_OBJ_TYPE_SET_SLOT(type, subscr, mp_obj_tuple_subscr, 5); + MP_OBJ_TYPE_SET_SLOT(type, iter, mp_obj_tuple_getiter, 6); + MP_OBJ_TYPE_SET_SLOT(type, parent, &mp_type_tuple, 7); return MP_OBJ_FROM_PTR(o); } diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index db4a3d87d87f..c4f4149fd606 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -29,9 +29,9 @@ #include "py/objtuple.h" typedef struct _mp_obj_namedtuple_type_t { - // This is a mp_obj_type_t with seven slots. + // This is a mp_obj_type_t with eight slots. mp_obj_empty_type_t base; - void *slots[7]; + void *slots[8]; size_t n_fields; qstr fields[]; } mp_obj_namedtuple_type_t; diff --git a/py/objnone.c b/py/objnone.c index 4fffbc997e89..4f8996e897a8 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -47,7 +47,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_NoneType, MP_QSTR_NoneType, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, none_print, unary_op, mp_generic_unary_op ); diff --git a/py/objobject.c b/py/objobject.c index ffad61070727..1acae6d00b18 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -121,6 +121,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_object, MP_QSTR_object, MP_TYPE_FLAG_NONE, - object_make_new + make_new, object_make_new OBJECT_TYPE_LOCALS_DICT ); diff --git a/py/objpolyiter.c b/py/objpolyiter.c index 7a45b6b73fe6..78b600abacdc 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -49,7 +49,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_polymorph_iter, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, polymorph_it_iternext ); @@ -81,7 +80,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_polymorph_iter_with_finaliser, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, polymorph_it_iternext, locals_dict, &mp_obj_polymorph_iter_locals_dict ); diff --git a/py/objproperty.c b/py/objproperty.c index ce3b572591d2..2d3af10e8c70 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -94,7 +94,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_property, MP_QSTR_property, MP_TYPE_FLAG_NONE, - property_make_new, + make_new, property_make_new, locals_dict, &property_locals_dict ); diff --git a/py/objrange.c b/py/objrange.c index 1ad8f6031f29..f0fe56d9db12 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -54,7 +54,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_range_it, MP_QSTR_iterator, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - MP_TYPE_NULL_MAKE_NEW, iter, range_it_iternext ); @@ -225,7 +224,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_range, MP_QSTR_range, MP_TYPE_FLAG_NONE, - range_make_new, + make_new, range_make_new, RANGE_TYPE_BINOP RANGE_TYPE_ATTR print, range_print, diff --git a/py/objreversed.c b/py/objreversed.c index e265266d3f12..c66698f028ad 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -72,7 +72,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_reversed, MP_QSTR_reversed, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - reversed_make_new, + make_new, reversed_make_new, iter, reversed_iternext ); diff --git a/py/objset.c b/py/objset.c index b827f49f40df..906807889ab3 100644 --- a/py/objset.c +++ b/py/objset.c @@ -543,7 +543,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_set, MP_QSTR_set, MP_TYPE_FLAG_ITER_IS_GETITER, - set_make_new, + make_new, set_make_new, print, set_print, unary_op, set_unary_op, binary_op, set_binary_op, @@ -569,7 +569,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_frozenset, MP_QSTR_frozenset, MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, - set_make_new, + make_new, set_make_new, print, set_print, unary_op, set_unary_op, binary_op, set_binary_op, diff --git a/py/objsingleton.c b/py/objsingleton.c index 4a099657d4be..dc73d28c274c 100644 --- a/py/objsingleton.c +++ b/py/objsingleton.c @@ -44,7 +44,7 @@ STATIC void singleton_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ } MP_DEFINE_CONST_OBJ_TYPE( - mp_type_singleton, MP_QSTR_, MP_TYPE_FLAG_NONE, MP_TYPE_NULL_MAKE_NEW, + mp_type_singleton, MP_QSTR_, MP_TYPE_FLAG_NONE, print, singleton_print, unary_op, mp_generic_unary_op ); diff --git a/py/objslice.c b/py/objslice.c index d1dbb24586d9..01d4da0dbda4 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -104,7 +104,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_slice, MP_QSTR_slice, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, SLICE_TYPE_ATTR_OR_LOCALS_DICT print, slice_print ); diff --git a/py/objstr.c b/py/objstr.c index 12f6e15d0498..50ab0018ed6e 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -482,7 +482,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { if (!mp_obj_is_type(arg, &mp_type_list) && !mp_obj_is_type(arg, &mp_type_tuple)) { // arg is not a list nor a tuple, try to convert it to a list // TODO: Try to optimize? - arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg); + arg = mp_obj_list_make_new(&mp_type_list, 1, 0, &arg); } mp_obj_get_array(arg, &seq_len, &seq_items); @@ -2147,7 +2147,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_str, MP_QSTR_str, MP_TYPE_FLAG_NONE, - mp_obj_str_make_new, + make_new, mp_obj_str_make_new, print, str_print, binary_op, mp_obj_str_binary_op, subscr, bytes_subscr, @@ -2162,7 +2162,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_bytes, MP_QSTR_bytes, MP_TYPE_FLAG_NONE, - bytes_make_new, + make_new, bytes_make_new, print, str_print, binary_op, mp_obj_str_binary_op, subscr, bytes_subscr, diff --git a/py/objstringio.c b/py/objstringio.c index 4e19b83999aa..1a083449bafa 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -248,7 +248,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_stringio, MP_QSTR_StringIO, MP_TYPE_FLAG_ITER_IS_STREAM, - stringio_make_new, + make_new, stringio_make_new, print, stringio_print, protocol, &stringio_stream_p, locals_dict, &stringio_locals_dict @@ -265,7 +265,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_bytesio, MP_QSTR_BytesIO, MP_TYPE_FLAG_ITER_IS_STREAM, - stringio_make_new, + make_new, stringio_make_new, print, stringio_print, protocol, &bytesio_stream_p, locals_dict, &stringio_locals_dict diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 9b28841ecd17..93383b3c19e9 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -233,7 +233,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_str, MP_QSTR_str, MP_TYPE_FLAG_ITER_IS_GETITER, - mp_obj_str_make_new, + make_new, mp_obj_str_make_new, print, uni_print, unary_op, uni_unary_op, binary_op, mp_obj_str_binary_op, diff --git a/py/objtuple.c b/py/objtuple.c index 485d44c52a8d..9d6797b4ffc3 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -228,7 +228,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_tuple, MP_QSTR_tuple, MP_TYPE_FLAG_ITER_IS_GETITER, - mp_obj_tuple_make_new, + make_new, mp_obj_tuple_make_new, print, mp_obj_tuple_print, unary_op, mp_obj_tuple_unary_op, binary_op, mp_obj_tuple_binary_op, diff --git a/py/objtype.c b/py/objtype.c index 183dce071ee9..db364e0e5a5d 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -88,7 +88,7 @@ STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *args) { mp_obj_instance_t *self = MP_OBJ_TO_PTR(args[0]); const mp_obj_type_t *native_base = NULL; instance_count_native_bases(self->base.type, &native_base); - self->subobj[0] = native_base->make_new(native_base, n_args - 1, 0, args + 1); + self->subobj[0] = MP_OBJ_TYPE_GET_SLOT(native_base, make_new)(native_base, n_args - 1, 0, args + 1); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(native_base_init_wrapper_obj, 1, MP_OBJ_FUN_ARGS_MAX, native_base_init_wrapper); @@ -285,7 +285,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size struct class_lookup_data lookup = { .obj = NULL, .attr = MP_QSTR___new__, - .slot_offset = offsetof(mp_obj_type_t, make_new), + .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(make_new), .dest = init_fn, .is_type = false, }; @@ -362,7 +362,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size // If the type had a native base that was not explicitly initialised // (constructed) by the Python __init__() method then construct it now. if (native_base != NULL && o->subobj[0] == MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj)) { - o->subobj[0] = native_base->make_new(native_base, n_args, n_kw, args); + o->subobj[0] = MP_OBJ_TYPE_GET_SLOT(native_base, make_new)(native_base, n_args, n_kw, args); } return MP_OBJ_FROM_PTR(o); @@ -998,7 +998,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); - if (self->make_new == NULL) { + if (!MP_OBJ_TYPE_HAS_SLOT(self, make_new)) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't create instance")); #else @@ -1007,7 +1007,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp } // make new instance - mp_obj_t o = self->make_new(self, n_args, n_kw, args); + mp_obj_t o = MP_OBJ_TYPE_GET_SLOT(self, make_new)(self, n_args, n_kw, args); // return new instance return o; @@ -1109,7 +1109,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_type, MP_QSTR_type, MP_TYPE_FLAG_NONE, - type_make_new, + make_new, type_make_new, print, type_print, call, type_call, unary_op, mp_generic_unary_op, @@ -1141,7 +1141,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) } mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); // TODO: Verify with CPy, tested on function type - if (t->make_new == NULL) { + if (!MP_OBJ_TYPE_HAS_SLOT(t, make_new)) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("type isn't an acceptable base type")); #else @@ -1163,35 +1163,35 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) } // Allocate a variable-sized mp_obj_type_t with as many slots as we need - // (currently 9, plus 1 for base, plus 1 for base-protocol). - // Note: 11 slots pushes it from 4 to 5 GC blocks. - mp_obj_type_t *o = m_new_obj_var0(mp_obj_type_t, void *, 9 + (bases_len ? 1 : 0) + (base_protocol ? 1 : 0)); + // (currently 10, plus 1 for base, plus 1 for base-protocol). + // Note: mp_obj_type_t is (2 + 3 + #slots) words, so going from 11 to 12 slots + // moves from 4 to 5 gc blocks. + mp_obj_type_t *o = m_new_obj_var0(mp_obj_type_t, void *, 10 + (bases_len ? 1 : 0) + (base_protocol ? 1 : 0)); o->base.type = &mp_type_type; o->flags = base_flags; o->name = name; - o->make_new = mp_obj_instance_make_new; - MP_OBJ_TYPE_SET_SLOT(o, print, instance_print, 0); - MP_OBJ_TYPE_SET_SLOT(o, call, mp_obj_instance_call, 1); - MP_OBJ_TYPE_SET_SLOT(o, unary_op, instance_unary_op, 2); - MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 3); - MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 4); - MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 5); - MP_OBJ_TYPE_SET_SLOT(o, iter, mp_obj_instance_getiter, 6); - // MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented) - MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7); + MP_OBJ_TYPE_SET_SLOT(o, make_new, mp_obj_instance_make_new, 0); + MP_OBJ_TYPE_SET_SLOT(o, print, instance_print, 1); + MP_OBJ_TYPE_SET_SLOT(o, call, mp_obj_instance_call, 2); + MP_OBJ_TYPE_SET_SLOT(o, unary_op, instance_unary_op, 3); + MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 4); + MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 5); + MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 6); + MP_OBJ_TYPE_SET_SLOT(o, iter, mp_obj_instance_getiter, 7); + MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 8); mp_obj_dict_t *locals_ptr = MP_OBJ_TO_PTR(locals_dict); - MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 8); + MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 9); if (bases_len > 0) { if (bases_len >= 2) { #if MICROPY_MULTIPLE_INHERITANCE - MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_tuple), 9); + MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_tuple), 10); #else mp_raise_NotImplementedError(MP_ERROR_TEXT("multiple inheritance not supported")); #endif } else { - MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_items[0]), 9); + MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_items[0]), 10); } // Inherit protocol from a base class. This allows to define an @@ -1199,7 +1199,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // Python method calls, and any subclass inheriting from it will // support this feature. if (base_protocol) { - MP_OBJ_TYPE_SET_SLOT(o, protocol, base_protocol, 10); + MP_OBJ_TYPE_SET_SLOT(o, protocol, base_protocol, 11); } } @@ -1292,7 +1292,7 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { // Allow a call super().__init__() to reach any native base classes. if (attr == MP_QSTR___init__) { - lookup.slot_offset = offsetof(mp_obj_type_t, make_new); + lookup.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(make_new); } if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) { @@ -1340,7 +1340,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_super, MP_QSTR_super, MP_TYPE_FLAG_NONE, - super_make_new, + make_new, super_make_new, print, super_print, attr, super_attr ); @@ -1463,12 +1463,12 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_staticmethod, MP_QSTR_staticmethod, MP_TYPE_FLAG_NONE, - static_class_method_make_new + make_new, static_class_method_make_new ); MP_DEFINE_CONST_OBJ_TYPE( mp_type_classmethod, MP_QSTR_classmethod, MP_TYPE_FLAG_NONE, - static_class_method_make_new + make_new, static_class_method_make_new ); diff --git a/py/objtype.h b/py/objtype.h index 2c613b904580..76a290760c83 100644 --- a/py/objtype.h +++ b/py/objtype.h @@ -46,8 +46,8 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *cls, const mp_obj_ty bool mp_obj_instance_is_callable(mp_obj_t self_in); mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); -#define mp_obj_is_instance_type(type) ((type)->make_new == mp_obj_instance_make_new) -#define mp_obj_is_native_type(type) ((type)->make_new != mp_obj_instance_make_new) +#define mp_obj_is_instance_type(type) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(type, make_new) == mp_obj_instance_make_new) +#define mp_obj_is_native_type(type) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(type, make_new) != mp_obj_instance_make_new) // this needs to be exposed for the above macros to work correctly mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); diff --git a/py/objzip.c b/py/objzip.c index 34d73465ef2b..3c3138180a28 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -70,6 +70,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_zip, MP_QSTR_zip, MP_TYPE_FLAG_ITER_IS_ITERNEXT, - zip_make_new, + make_new, zip_make_new, iter, zip_iternext ); diff --git a/py/profile.c b/py/profile.c index 2b9531e245ac..fd2d61caa9f8 100644 --- a/py/profile.c +++ b/py/profile.c @@ -176,7 +176,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_settrace_codeobj, MP_QSTR_code, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, code_print, unary_op, mp_generic_unary_op, attr, code_attr @@ -247,7 +246,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_frame, MP_QSTR_frame, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, print, frame_print, unary_op, mp_generic_unary_op, attr, frame_attr diff --git a/py/runtime.c b/py/runtime.c index ec628bfe14b4..da6c86d97154 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1076,7 +1076,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_type_checked_fun, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, - MP_TYPE_NULL_MAKE_NEW, call, checked_fun_call ); diff --git a/shared/runtime/mpirq.c b/shared/runtime/mpirq.c index 889fa7a9a82e..f9a85ebbd61b 100644 --- a/shared/runtime/mpirq.c +++ b/shared/runtime/mpirq.c @@ -129,7 +129,6 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_irq_type, MP_QSTR_irq, MP_TYPE_FLAG_NONE, - MP_TYPE_NULL_MAKE_NEW, call, mp_irq_call, locals_dict, &mp_irq_locals_dict ); diff --git a/shared/runtime/sys_stdio_mphal.c b/shared/runtime/sys_stdio_mphal.c index 325f93dde1d8..ab5bdd34e73c 100644 --- a/shared/runtime/sys_stdio_mphal.c +++ b/shared/runtime/sys_stdio_mphal.c @@ -127,7 +127,6 @@ MP_DEFINE_CONST_OBJ_TYPE( stdio_obj_type, MP_QSTR_FileIO, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, stdio_obj_print, protocol, &stdio_obj_stream_p, locals_dict, &stdio_locals_dict @@ -161,7 +160,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE( stdio_buffer_obj_type, MP_QSTR_FileIO, MP_TYPE_FLAG_ITER_IS_STREAM, - MP_TYPE_NULL_MAKE_NEW, print, stdio_obj_print, protocol, &stdio_buffer_obj_stream_p, locals_dict, &stdio_locals_dict From b41aaaa8a918a6645ebc6bfa4483bd17286f9263 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 17 Sep 2022 22:22:32 +1000 Subject: [PATCH 1754/4290] py/obj: Optimise code size and performance for make_new as a slot. The check for make_new (i.e. used to determine something's type) is now more complicated due to the slot access. This commit changes the inlining of a few frequently-used helpers to overall improve code size and performance. --- py/obj.h | 6 ++++-- py/objdict.c | 4 ++++ py/objexcept.c | 4 ++++ py/objstr.c | 20 ++++++++++++-------- py/objtype.c | 5 +++-- py/objtype.h | 6 ++---- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/py/obj.h b/py/obj.h index 34adfbd0f042..8aa5b0a8e667 100644 --- a/py/obj.h +++ b/py/obj.h @@ -521,6 +521,7 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); // mp_getiter_iternext_custom_t struct instance (with both .getiter and .iternext set). // If MP_TYPE_FLAG_ITER_IS_STREAM is set then the type implicitly gets a "return self" // getiter, and mp_stream_unbuffered_iter for iternext. +// If MP_TYPE_FLAG_INSTANCE_TYPE is set then this is an instance type (i.e. defined in Python). #define MP_TYPE_FLAG_NONE (0x0000) #define MP_TYPE_FLAG_IS_SUBCLASSED (0x0001) #define MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002) @@ -533,6 +534,7 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); #define MP_TYPE_FLAG_ITER_IS_ITERNEXT (0x0080) #define MP_TYPE_FLAG_ITER_IS_CUSTOM (0x0100) #define MP_TYPE_FLAG_ITER_IS_STREAM (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM) +#define MP_TYPE_FLAG_INSTANCE_TYPE (0x0200) typedef enum { PRINT_STR = 0, @@ -914,7 +916,7 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); #define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_exact_type(o, &mp_type_int)) #define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_exact_type(o, &mp_type_str)) #define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, binary_op) == mp_obj_str_binary_op)) -#define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, make_new) == mp_obj_dict_make_new) +bool mp_obj_is_dict_or_ordereddict(mp_obj_t o); #define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); @@ -1030,7 +1032,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in); mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in); // exception -#define mp_obj_is_native_exception_instance(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), make_new) == mp_obj_exception_make_new) +bool mp_obj_is_native_exception_instance(mp_obj_t self_in); bool mp_obj_is_exception_type(mp_obj_t self_in); bool mp_obj_is_exception_instance(mp_obj_t self_in); bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type); diff --git a/py/objdict.c b/py/objdict.c index 68c33961c70c..7fad5fc8f4eb 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -33,6 +33,10 @@ #include "py/objtype.h" #include "py/objstr.h" +bool mp_obj_is_dict_or_ordereddict(mp_obj_t o) { + return mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, make_new) == mp_obj_dict_make_new; +} + const mp_obj_dict_t mp_const_empty_dict_obj = { .base = { .type = &mp_type_dict }, .map = { diff --git a/py/objexcept.c b/py/objexcept.c index 3b76ae62ccc6..515cbe7425b0 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -111,6 +111,10 @@ mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in) { #endif #endif // MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF +bool mp_obj_is_native_exception_instance(mp_obj_t self_in) { + return MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(self_in), make_new) == mp_obj_exception_make_new; +} + STATIC mp_obj_exception_t *get_native_exception(mp_obj_t self_in) { assert(mp_obj_is_exception_instance(self_in)); if (mp_obj_is_native_exception_instance(self_in)) { diff --git a/py/objstr.c b/py/objstr.c index 50ab0018ed6e..62d7bfb4cc39 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -63,6 +63,10 @@ STATIC void str_check_arg_type(const mp_obj_type_t *self_type, const mp_obj_t ar } } +STATIC void check_is_str_or_bytes(mp_obj_t self_in) { + mp_check_self(mp_obj_is_str_or_bytes(self_in)); +} + /******************************************************************************/ /* str */ @@ -468,7 +472,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { - mp_check_self(mp_obj_is_str_or_bytes(self_in)); + check_is_str_or_bytes(self_in); const mp_obj_type_t *self_type = mp_obj_get_type(self_in); const mp_obj_type_t *ret_type = self_type; @@ -724,7 +728,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj, 1, 3, str_rsplit); STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); - mp_check_self(mp_obj_is_str_or_bytes(args[0])); + check_is_str_or_bytes(args[0]); // check argument type str_check_arg_type(self_type, args[1]); @@ -820,7 +824,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith); enum { LSTRIP, RSTRIP, STRIP }; STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_str_or_bytes(args[0])); + check_is_str_or_bytes(args[0]); const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); const byte *chars_to_del; @@ -1422,7 +1426,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - mp_check_self(mp_obj_is_str_or_bytes(args[0])); + check_is_str_or_bytes(args[0]); GET_STR_DATA_LEN(args[0], str, len); int arg_i = 0; @@ -1433,7 +1437,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(str_format_obj, 1, mp_obj_str_format); #if MICROPY_PY_BUILTINS_STR_OP_MODULO STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict) { - mp_check_self(mp_obj_is_str_or_bytes(pattern)); + check_is_str_or_bytes(pattern); GET_STR_DATA_LEN(pattern, str, len); #if MICROPY_ERROR_REPORTING > MICROPY_ERROR_REPORTING_TERSE @@ -1639,7 +1643,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ // The implementation is optimized, returning the original string if there's // nothing to replace. STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_str_or_bytes(args[0])); + check_is_str_or_bytes(args[0]); mp_int_t max_rep = -1; if (n_args == 4) { @@ -1742,7 +1746,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); #if MICROPY_PY_BUILTINS_STR_COUNT STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); - mp_check_self(mp_obj_is_str_or_bytes(args[0])); + check_is_str_or_bytes(args[0]); // check argument type str_check_arg_type(self_type, args[1]); @@ -1782,7 +1786,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); #if MICROPY_PY_BUILTINS_STR_PARTITION STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { - mp_check_self(mp_obj_is_str_or_bytes(self_in)); + check_is_str_or_bytes(self_in); const mp_obj_type_t *self_type = mp_obj_get_type(self_in); str_check_arg_type(self_type, arg); diff --git a/py/objtype.c b/py/objtype.c index db364e0e5a5d..909fc833931f 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -277,7 +277,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k mp_printf(print, "<%s object at %p>", mp_obj_get_type_str(self_in), self); } -mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_instance_type(self)); // look for __new__ function @@ -1131,7 +1131,8 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) uint16_t base_flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST - | MP_TYPE_FLAG_ITER_IS_GETITER; + | MP_TYPE_FLAG_ITER_IS_GETITER + | MP_TYPE_FLAG_INSTANCE_TYPE; size_t bases_len; mp_obj_t *bases_items; mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); diff --git a/py/objtype.h b/py/objtype.h index 76a290760c83..839cc6d146bb 100644 --- a/py/objtype.h +++ b/py/objtype.h @@ -46,10 +46,8 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *cls, const mp_obj_ty bool mp_obj_instance_is_callable(mp_obj_t self_in); mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); -#define mp_obj_is_instance_type(type) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(type, make_new) == mp_obj_instance_make_new) -#define mp_obj_is_native_type(type) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(type, make_new) != mp_obj_instance_make_new) -// this needs to be exposed for the above macros to work correctly -mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +#define mp_obj_is_instance_type(type) ((type)->flags & MP_TYPE_FLAG_INSTANCE_TYPE) +#define mp_obj_is_native_type(type) (!((type)->flags & MP_TYPE_FLAG_INSTANCE_TYPE)) // this needs to be exposed for mp_getiter mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf); From d94141e1473aebae0d3c63aeaa8397651ad6fa01 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 17 Sep 2022 23:57:12 +1000 Subject: [PATCH 1755/4290] py/persistentcode: Introduce .mpy sub-version. The intent is to allow us to make breaking changes to the native ABI (e.g. changes to dynruntime.h) without needing the bytecode version to increment. With this commit the two bits previously used for the feature flags (but now unused as of .mpy version 6) encode a sub-version. A bytecode-only .mpy file can be loaded as long as MPY_VERSION matches, but a native .mpy (i.e. one with an arch set) must also match MPY_SUB_VERSION. This allows 3 additional updates to the native ABI per bytecode revision. The sub-version is set to 1 because the previous commits that changed the layout of mp_obj_type_t have changed the native ABI. Signed-off-by: Jim Mussared Signed-off-by: Damien George --- docs/reference/mpyfiles.rst | 6 ++++++ mpy-cross/main.c | 2 +- py/persistentcode.c | 6 +++--- py/persistentcode.h | 23 +++++++++++------------ tests/micropython/import_mpy_native.py | 7 ++++--- tests/micropython/import_mpy_native_gc.py | 12 +++++++----- tools/mpy-tool.py | 10 ++++++++-- tools/mpy_ld.py | 7 ++++++- 8 files changed, 46 insertions(+), 27 deletions(-) diff --git a/docs/reference/mpyfiles.rst b/docs/reference/mpyfiles.rst index fcb49965652f..d93a86383e98 100644 --- a/docs/reference/mpyfiles.rst +++ b/docs/reference/mpyfiles.rst @@ -27,6 +27,11 @@ Compatibility is based on the following: * Version of the .mpy file: the version of the file must match the version supported by the system loading it. +* Sub-version of the .mpy file: if the .mpy file contains native machine code + then the sub-version of the file must match the version support by the + system loading it. Otherwise, if there is no native machine code in the .mpy + file, then the sub-version is ignored when loading. + * Small integer bits: the .mpy file will require a minimum number of bits in a small integer and the system loading it must support at least this many bits. @@ -55,6 +60,7 @@ If importing an .mpy file fails then try the following: 'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp', 'xtensa', 'xtensawin'][sys_mpy >> 10] print('mpy version:', sys_mpy & 0xff) + print('mpy sub-version:', sys_mpy >> 8 & 3) print('mpy flags:', end='') if arch: print(' -march=' + arch, end='') diff --git a/mpy-cross/main.c b/mpy-cross/main.c index f3ffff61fdf8..4975c8ddb205 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -228,7 +228,7 @@ MP_NOINLINE int main_(int argc, char **argv) { a += 1; } else if (strcmp(argv[a], "--version") == 0) { printf("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE - "; mpy-cross emitting mpy v" MP_STRINGIFY(MPY_VERSION) "\n"); + "; mpy-cross emitting mpy v" MP_STRINGIFY(MPY_VERSION) "." MP_STRINGIFY(MPY_SUB_VERSION) "\n"); return 0; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; diff --git a/py/persistentcode.c b/py/persistentcode.c index 1b1741f2614e..de84c17359e3 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -393,14 +393,14 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *context) { byte header[4]; read_bytes(reader, header, sizeof(header)); + byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); if (header[0] != 'M' || header[1] != MPY_VERSION - || MPY_FEATURE_DECODE_FLAGS(header[2]) != MPY_FEATURE_FLAGS + || (arch != MP_NATIVE_ARCH_NONE && MPY_FEATURE_DECODE_SUB_VERSION(header[2]) != MPY_SUB_VERSION) || header[3] > MP_SMALL_INT_BITS) { mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); } if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE) { - byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); if (!MPY_FEATURE_ARCH_TEST(arch)) { if (MPY_FEATURE_ARCH_TEST(MP_NATIVE_ARCH_NONE)) { // On supported ports this can be resolved by enabling feature, eg @@ -596,7 +596,7 @@ void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print) { byte header[4] = { 'M', MPY_VERSION, - MPY_FEATURE_ENCODE_FLAGS(MPY_FEATURE_FLAGS_DYNAMIC), + MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION), #if MICROPY_DYNAMIC_COMPILER mp_dynamic_compiler.small_int_bits, #else diff --git a/py/persistentcode.h b/py/persistentcode.h index 29ccce4a3d96..e66435873761 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -30,24 +30,23 @@ #include "py/reader.h" #include "py/emitglue.h" -// The current version of .mpy files +// The current version of .mpy files. A bytecode-only .mpy file can be loaded +// as long as MPY_VERSION matches, but a native .mpy (i.e. one with an arch +// set) must also match MPY_SUB_VERSION. This allows 3 additional updates to +// the native ABI per bytecode revision. #define MPY_VERSION 6 +#define MPY_SUB_VERSION 1 -// Macros to encode/decode flags to/from the feature byte -#define MPY_FEATURE_ENCODE_FLAGS(flags) (flags) -#define MPY_FEATURE_DECODE_FLAGS(feat) ((feat) & 3) +// Macros to encode/decode sub-version to/from the feature byte. This replaces +// the bits previously used to encode the flags (map caching and unicode) +// which are no longer used starting at .mpy version 6. +#define MPY_FEATURE_ENCODE_SUB_VERSION(version) (version) +#define MPY_FEATURE_DECODE_SUB_VERSION(feat) ((feat) & 3) // Macros to encode/decode native architecture to/from the feature byte #define MPY_FEATURE_ENCODE_ARCH(arch) ((arch) << 2) #define MPY_FEATURE_DECODE_ARCH(feat) ((feat) >> 2) -// The feature flag bits encode the compile-time config options that affect -// the generate bytecode. Note: no longer used. -// (formerly MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE and MICROPY_PY_BUILTINS_STR_UNICODE). -#define MPY_FEATURE_FLAGS (0) -// This is a version of the flags that can be configured at runtime. -#define MPY_FEATURE_FLAGS_DYNAMIC (0) - // Define the host architecture #if MICROPY_EMIT_X86 #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_X86) @@ -82,7 +81,7 @@ // 16-bit little-endian integer with the second and third bytes of supported .mpy files #define MPY_FILE_HEADER_INT (MPY_VERSION \ - | (MPY_FEATURE_ENCODE_FLAGS(MPY_FEATURE_FLAGS) | MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH)) << 8) + | (MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION) | MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH)) << 8) enum { MP_NATIVE_ARCH_NONE = 0, diff --git a/tests/micropython/import_mpy_native.py b/tests/micropython/import_mpy_native.py index 449371ddac06..73e20694cc27 100644 --- a/tests/micropython/import_mpy_native.py +++ b/tests/micropython/import_mpy_native.py @@ -11,7 +11,8 @@ raise SystemExit mpy_arch = usys.implementation._mpy >> 8 -if mpy_arch == 0: +if mpy_arch >> 2 == 0: + # This system does not support .mpy files containing native code print("SKIP") raise SystemExit @@ -54,8 +55,8 @@ def open(self, path, mode): valid_header = bytes([77, 6, mpy_arch, 31]) # fmt: off user_files = { - # bad architecture - '/mod0.mpy': b'M\x06\xfc\x1f', + # bad architecture (mpy_arch needed for sub-version) + '/mod0.mpy': bytes([77, 6, 0xfc | mpy_arch, 31]), # test loading of viper and asm '/mod1.mpy': valid_header + ( diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py index bc8dcafdc763..e18720fb3147 100644 --- a/tests/micropython/import_mpy_native_gc.py +++ b/tests/micropython/import_mpy_native_gc.py @@ -46,24 +46,26 @@ def open(self, path, mode): # Pre-compiled examples/natmod/features0 example for various architectures, keyed -# by the required value of sys.implementation._mpy. +# by the required value of sys.implementation._mpy (without sub-version). features0_file_contents = { # -march=x64 - 0x806: b'M\x06\x08\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x8a\x02\xe9/\x00\x00\x00SH\x8b\x1d\x83\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dQ\x00\x00\x00H\x8bG\x08L\x8bc(H\x8bx\x08A\xff\xd4H\x8d5+\x00\x00\x00H\x89\xc5H\x8b\x059\x00\x00\x00\x0f\xb7x\x02\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11$\r&\xa3 \x01"\xff', + 0x806: b'M\x06\x09\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x8a\x02\xe9/\x00\x00\x00SH\x8b\x1d\x83\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dQ\x00\x00\x00H\x8bG\x08L\x8bc(H\x8bx\x08A\xff\xd4H\x8d5+\x00\x00\x00H\x89\xc5H\x8b\x059\x00\x00\x00\x0f\xb7x\x02\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11$\r&\xa3 \x01"\xff', # -march=armv6m - 0x1006: b"M\x06\x10\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x88\x02\x18\xe0\x00\x00\x10\xb5\tK\tJ{D\x9cX\x02!\xe3h\x98G\x03\x00\x01 \x00+\x02\xd0XC\x01;\xfa\xe7\x02!#i\x98G\x10\xbd\xc0Fj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\nN\nK~D\xf4XChgiXh\xb8G\x05\x00\x07K\x08I\xf3XyDX\x88ck\x98G(\x00\xb8G h\xf8\xbd\xc0F:\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11<\r>\xa38\x01:\xff", + 0x1006: b"M\x06\x11\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x88\x02\x18\xe0\x00\x00\x10\xb5\tK\tJ{D\x9cX\x02!\xe3h\x98G\x03\x00\x01 \x00+\x02\xd0XC\x01;\xfa\xe7\x02!#i\x98G\x10\xbd\xc0Fj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\nN\nK~D\xf4XChgiXh\xb8G\x05\x00\x07K\x08I\xf3XyDX\x88ck\x98G(\x00\xb8G h\xf8\xbd\xc0F:\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11<\r>\xa38\x01:\xff", } # Populate armv7m-derived archs based on armv6m. for arch in (0x1406, 0x1806, 0x1C06, 0x2006): features0_file_contents[arch] = features0_file_contents[0x1006] -if sys.implementation._mpy not in features0_file_contents: +# Check that a .mpy exists for the target (ignore sub-version in lookup). +sys_implementation_mpy = sys.implementation._mpy & ~(3 << 8) +if sys_implementation_mpy not in features0_file_contents: print("SKIP") raise SystemExit # These are the test .mpy files. -user_files = {"/features0.mpy": features0_file_contents[sys.implementation._mpy]} +user_files = {"/features0.mpy": features0_file_contents[sys_implementation_mpy]} # Create and mount a user filesystem. uos.mount(UserFS(user_files), "/userfs") diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 31212fd5bdda..8b644c137f4c 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -88,6 +88,7 @@ def __str__(self): class Config: MPY_VERSION = 6 + MPY_SUB_VERSION = 1 MICROPY_LONGINT_IMPL_NONE = 0 MICROPY_LONGINT_IMPL_LONGLONG = 1 MICROPY_LONGINT_IMPL_MPZ = 2 @@ -1335,6 +1336,9 @@ def read_mpy(filename): feature_byte = header[2] mpy_native_arch = feature_byte >> 2 if mpy_native_arch != MP_NATIVE_ARCH_NONE: + mpy_sub_version = feature_byte & 3 + if mpy_sub_version != config.MPY_SUB_VERSION: + raise MPYReadError(filename, "incompatible .mpy sub-version") if config.native_arch == MP_NATIVE_ARCH_NONE: config.native_arch = mpy_native_arch elif config.native_arch != mpy_native_arch: @@ -1658,7 +1662,9 @@ def merge_mpy(compiled_modules, output_file): else: main_cm_idx = None for idx, cm in enumerate(compiled_modules): - if cm.header[2]: + feature_byte = cm.header[2] + mpy_native_arch = feature_byte >> 2 + if mpy_native_arch: # Must use qstr_table and obj_table from this raw_code if main_cm_idx is not None: raise Exception("can't merge files when more than one contains native code") @@ -1670,7 +1676,7 @@ def merge_mpy(compiled_modules, output_file): header = bytearray(4) header[0] = ord("M") header[1] = config.MPY_VERSION - header[2] = config.native_arch << 2 + header[2] = config.native_arch << 2 | config.MPY_SUB_VERSION header[3] = config.mp_small_int_bits merged_mpy.extend(header) diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index 09ea90dcd110..05e70709ad8a 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -36,6 +36,7 @@ # MicroPython constants MPY_VERSION = 6 +MPY_SUB_VERSION = 1 MP_CODE_BYTECODE = 2 MP_CODE_NATIVE_VIPER = 4 MP_NATIVE_ARCH_X86 = 1 @@ -917,7 +918,11 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs): out.open(fmpy) # MPY: header - out.write_bytes(bytearray([ord("M"), MPY_VERSION, env.arch.mpy_feature, MP_SMALL_INT_BITS])) + out.write_bytes( + bytearray( + [ord("M"), MPY_VERSION, env.arch.mpy_feature | MPY_SUB_VERSION, MP_SMALL_INT_BITS] + ) + ) # MPY: n_qstr out.write_uint(1 + len(native_qstr_vals)) From 15d0615d5cad430930d160a8ca3e809d7b82da32 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 13 Sep 2022 14:16:58 +1000 Subject: [PATCH 1756/4290] py/objmodule: Add support for __dict__. This matches class `__dict__`, and is similarly gated on MICROPY_CPYTHON_COMPAT. Unlike class though, because modules's globals are actually dict instances, the result is a mutable dictionary. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- py/objmodule.c | 4 ++++ tests/basics/module_dict.py | 13 +++++++++++++ tests/import/module_dict.py | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 tests/basics/module_dict.py create mode 100644 tests/import/module_dict.py diff --git a/py/objmodule.c b/py/objmodule.c index d14a59b8632c..63e9fa47571b 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -89,6 +89,10 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_map_elem_t *elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { dest[0] = elem->value; + #if MICROPY_CPYTHON_COMPAT + } else if (attr == MP_QSTR___dict__) { + dest[0] = MP_OBJ_FROM_PTR(self->globals); + #endif #if MICROPY_MODULE_GETATTR } else if (attr != MP_QSTR___getattr__) { elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(MP_QSTR___getattr__), MP_MAP_LOOKUP); diff --git a/tests/basics/module_dict.py b/tests/basics/module_dict.py new file mode 100644 index 000000000000..c847294f0891 --- /dev/null +++ b/tests/basics/module_dict.py @@ -0,0 +1,13 @@ +# test __dict__ attribute of a built-in module +# see import/module_dict.py for the equivalent test on user modules + +import sys + +if not hasattr(sys, "__dict__"): + print("SKIP") + raise SystemExit + + +# dict of a built-in module (read-only) +print(type(sys.__dict__)) +print(sys.__dict__["__name__"]) diff --git a/tests/import/module_dict.py b/tests/import/module_dict.py new file mode 100644 index 000000000000..431d80b3b43b --- /dev/null +++ b/tests/import/module_dict.py @@ -0,0 +1,17 @@ +# test __dict__ attribute of a user module + +import sys + +if not hasattr(sys, "__dict__"): + print("SKIP") + raise SystemExit + + +import import1b + +# dict of a user module (read/write) +print(import1b.var) +print(import1b.__dict__["var"]) +import1b.__dict__["var"] = "hello" +print(import1b.var) +print(import1b.__dict__["var"]) From cc588ac3a91a16807242347e8b182d4bc8b7f139 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2022 10:35:12 +1000 Subject: [PATCH 1757/4290] py/runtime: Add mp_raise_OSError_with_filename helper function. Useful when more detail is needed for an OSError associated with a file. Signed-off-by: Damien George --- py/runtime.c | 9 +++++++++ py/runtime.h | 1 + 2 files changed, 10 insertions(+) diff --git a/py/runtime.c b/py/runtime.c index da6c86d97154..23fae6041dd0 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1692,6 +1692,15 @@ NORETURN void mp_raise_OSError(int errno_) { mp_raise_type_arg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_)); } +NORETURN void mp_raise_OSError_with_filename(int errno_, const char *filename) { + vstr_t vstr; + vstr_init(&vstr, 32); + vstr_printf(&vstr, "can't open %s", filename); + mp_obj_t o_str = mp_obj_new_str_from_vstr(&vstr); + mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(errno_), MP_OBJ_FROM_PTR(o_str)}; + nlr_raise(mp_obj_exception_make_new(&mp_type_OSError, 2, 0, args)); +} + #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK NORETURN void mp_raise_recursion_depth(void) { mp_raise_type_arg(&mp_type_RuntimeError, MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded)); diff --git a/py/runtime.h b/py/runtime.h index 779b66f2bd25..36b3caa6c73e 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -196,6 +196,7 @@ NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg); NORETURN void mp_raise_StopIteration(mp_obj_t arg); NORETURN void mp_raise_OSError(int errno_); +NORETURN void mp_raise_OSError_with_filename(int errno_, const char *filename); NORETURN void mp_raise_recursion_depth(void); #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG From fb77be150636090d69460578ed8458d84db02614 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2022 10:36:17 +1000 Subject: [PATCH 1758/4290] py: Include filename in errors from loading/saving files via "open". This improves error messages in mpy-cross: - When loading a .py file that doesn't exist (or can't be opened) it now includes the filename in the OSError. - When saving a .mpy file that can't be opened it now raises an exception (prior, it would silently fail), and includes the filename in the OSError. Signed-off-by: Damien George --- py/persistentcode.c | 3 +++ py/reader.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/py/persistentcode.c b/py/persistentcode.c index de84c17359e3..67c8f327f002 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -644,6 +644,9 @@ void mp_raw_code_save_file(mp_compiled_module_t *cm, const char *filename) { MP_THREAD_GIL_EXIT(); int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); MP_THREAD_GIL_ENTER(); + if (fd < 0) { + mp_raise_OSError_with_filename(errno, filename); + } mp_print_t fd_print = {(void *)(intptr_t)fd, fd_print_strn}; mp_raw_code_save(cm, &fd_print); MP_THREAD_GIL_EXIT(); diff --git a/py/reader.c b/py/reader.c index d68406b1c68b..57b12b3b655c 100644 --- a/py/reader.c +++ b/py/reader.c @@ -139,7 +139,7 @@ void mp_reader_new_file(mp_reader_t *reader, const char *filename) { int fd = open(filename, O_RDONLY, 0644); MP_THREAD_GIL_ENTER(); if (fd < 0) { - mp_raise_OSError(errno); + mp_raise_OSError_with_filename(errno, filename); } mp_reader_new_file_from_fd(reader, fd, true); } From 9ae8d3820474a9525d707b1e19f7703721aec1c8 Mon Sep 17 00:00:00 2001 From: stijn Date: Mon, 12 Sep 2022 14:45:39 +0200 Subject: [PATCH 1759/4290] extmod/vfs_posix_file: Implement finaliser for files. Prevent handle leaks when file objects aren't closed explicitly and fix some MICROPY_CPYTHON_COMPAT issues: this wasn't properly adhered to because #ifdef was used so it was always on, and closing files multiple times should be avoided unconditionally. --- extmod/vfs_posix_file.c | 15 ++++++++------- tests/extmod/vfs_posix.py | 29 +++++++++++++++++++++++++++++ tests/extmod/vfs_posix.py.exp | 1 + 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 4a37489686cd..ea19de7fd04a 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -46,7 +46,7 @@ typedef struct _mp_obj_vfs_posix_file_t { int fd; } mp_obj_vfs_posix_file_t; -#ifdef MICROPY_CPYTHON_COMPAT +#if MICROPY_CPYTHON_COMPAT STATIC void check_fd_is_open(const mp_obj_vfs_posix_file_t *o) { if (o->fd < 0) { mp_raise_ValueError(MP_ERROR_TEXT("I/O operation on closed file")); @@ -63,7 +63,7 @@ STATIC void vfs_posix_file_print(const mp_print_t *print, mp_obj_t self_in, mp_p } mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_obj_t mode_in) { - mp_obj_vfs_posix_file_t *o = m_new_obj(mp_obj_vfs_posix_file_t); + mp_obj_vfs_posix_file_t *o = m_new_obj_with_finaliser(mp_obj_vfs_posix_file_t); const char *mode_s = mp_obj_str_get_str(mode_in); int mode_rw = 0, mode_x = 0; @@ -185,12 +185,12 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_ return 0; } case MP_STREAM_CLOSE: - MP_THREAD_GIL_EXIT(); - close(o->fd); - MP_THREAD_GIL_ENTER(); - #ifdef MICROPY_CPYTHON_COMPAT + if (o->fd >= 0) { + MP_THREAD_GIL_EXIT(); + close(o->fd); + MP_THREAD_GIL_ENTER(); + } o->fd = -1; - #endif return 0; case MP_STREAM_GET_FILENO: return o->fd; @@ -237,6 +237,7 @@ STATIC const mp_rom_map_elem_t vfs_posix_rawfile_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) }, { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&vfs_posix_file___exit___obj) }, }; diff --git a/tests/extmod/vfs_posix.py b/tests/extmod/vfs_posix.py index d193236696ea..3c23140065af 100644 --- a/tests/extmod/vfs_posix.py +++ b/tests/extmod/vfs_posix.py @@ -1,6 +1,7 @@ # Test for VfsPosix try: + import gc import uos uos.VfsPosix @@ -51,6 +52,34 @@ print(f.read()) f.close() +# file finaliser, also see vfs_fat_finaliser.py +names = [temp_dir + "/x%d" % i for i in range(4)] +basefd = temp_dir + "/nextfd1" +nextfd = temp_dir + "/nextfd2" + +with open(basefd, "w") as f: + base_file_no = f.fileno() + +for i in range(1024): # move GC head forwards by allocating a lot of single blocks + [] + + +def write_files_without_closing(): + for n in names: + open(n, "w").write(n) + sorted(list(range(128)), key=lambda x: x) # use up Python and C stack so f is really gone + + +write_files_without_closing() +gc.collect() + +with open(nextfd, "w") as f: + next_file_no = f.fileno() + print("next_file_no <= base_file_no", next_file_no <= base_file_no) + +for n in names + [basefd, nextfd]: + uos.remove(n) + # rename uos.rename(temp_dir + "/test", temp_dir + "/test2") print(uos.listdir(temp_dir)) diff --git a/tests/extmod/vfs_posix.py.exp b/tests/extmod/vfs_posix.py.exp index eb9ab43106e1..99922e621d4c 100644 --- a/tests/extmod/vfs_posix.py.exp +++ b/tests/extmod/vfs_posix.py.exp @@ -4,6 +4,7 @@ True hello +next_file_no <= base_file_no True ['test2'] ['test2'] From 6ecdf1a240e43bd60c824c7efd575c0a82d02d7e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 19 Sep 2022 12:03:38 +1000 Subject: [PATCH 1760/4290] tests/frozen: Move frozentest.mpy from ports/ to tests/. frozentest.mpy was previously duplicated in ports/minimal and ports/powerpc. This needs to be re-generated on every .mpy version increase, so might as well just have a single copy of it. Signed-off-by: Jim Mussared --- ports/minimal/Makefile | 2 +- ports/powerpc/Makefile | 2 +- ports/powerpc/frozentest.mpy | Bin 196 -> 0 bytes ports/powerpc/frozentest.py | 7 ------- tests/frozen/README.md | 2 ++ {ports/minimal => tests/frozen}/frozentest.mpy | Bin {ports/minimal => tests/frozen}/frozentest.py | 0 tools/ci.sh | 4 ++-- 8 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 ports/powerpc/frozentest.mpy delete mode 100644 ports/powerpc/frozentest.py create mode 100644 tests/frozen/README.md rename {ports/minimal => tests/frozen}/frozentest.mpy (100%) rename {ports/minimal => tests/frozen}/frozentest.py (100%) diff --git a/ports/minimal/Makefile b/ports/minimal/Makefile index 5ba6514c9ed4..0e875cc2491a 100644 --- a/ports/minimal/Makefile +++ b/ports/minimal/Makefile @@ -81,7 +81,7 @@ else all: $(BUILD)/firmware.elf endif -$(BUILD)/_frozen_mpy.c: frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h +$(BUILD)/_frozen_mpy.c: $(TOP)/tests/frozen/frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h $(ECHO) "MISC freezing bytecode" $(Q)$(TOP)/tools/mpy-tool.py -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h -mlongint-impl=none $< > $@ diff --git a/ports/powerpc/Makefile b/ports/powerpc/Makefile index 12ae485bb8f0..0986fd13eba0 100644 --- a/ports/powerpc/Makefile +++ b/ports/powerpc/Makefile @@ -50,7 +50,7 @@ OBJ += $(BUILD)/head.o all: $(BUILD)/firmware.elf $(BUILD)/firmware.map $(BUILD)/firmware.bin -$(BUILD)/_frozen_mpy.c: frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h +$(BUILD)/_frozen_mpy.c: $(TOP)/tests/frozen/frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h $(ECHO) "MISC freezing bytecode" $(Q)$(MPY_TOOL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h -mlongint-impl=mpz $< > $@ diff --git a/ports/powerpc/frozentest.mpy b/ports/powerpc/frozentest.mpy deleted file mode 100644 index 99581617ac3d13e416722a63852da14088ff8db7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmeZeW0GfOmP#wiuS(4;Ni8nXE2w1PZ!Bjk4X9*b%4A?wN>s?n&r4S*E-A_cQY9IQ zB?_6v3VHcJ3aFtdFExdMRV@)kJ|nSMp)@ZuIX@*;;oQb^o6c=kNX|$sDrR8gPO1c2 zqF`ubY{JOUVj#fBs15{LYJyAx%qEPHf=tQ`5Q-5(F@Y(iUGHa!0$B}CKH*|4f=q%e QKu+V+@RsY&`jLUj0I@qak^lez diff --git a/ports/powerpc/frozentest.py b/ports/powerpc/frozentest.py deleted file mode 100644 index 78cdd60bf043..000000000000 --- a/ports/powerpc/frozentest.py +++ /dev/null @@ -1,7 +0,0 @@ -print("uPy") -print("a long string that is not interned") -print("a string that has unicode αβγ chars") -print(b"bytes 1234\x01") -print(123456789) -for i in range(4): - print(i) diff --git a/tests/frozen/README.md b/tests/frozen/README.md new file mode 100644 index 000000000000..bd786d5a3c4c --- /dev/null +++ b/tests/frozen/README.md @@ -0,0 +1,2 @@ +This is a .mpy built against the current .mpy version that can be used to test +freezing without a dependency on mpy-cross. diff --git a/ports/minimal/frozentest.mpy b/tests/frozen/frozentest.mpy similarity index 100% rename from ports/minimal/frozentest.mpy rename to tests/frozen/frozentest.mpy diff --git a/ports/minimal/frozentest.py b/tests/frozen/frozentest.py similarity index 100% rename from ports/minimal/frozentest.py rename to tests/frozen/frozentest.py diff --git a/tools/ci.sh b/tools/ci.sh index 9c670b7be5ea..9963f7796cc0 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -75,8 +75,8 @@ function ci_mpy_format_setup { function ci_mpy_format_test { # Test mpy-tool.py dump feature on bytecode - python2 ./tools/mpy-tool.py -xd ports/minimal/frozentest.mpy - python3 ./tools/mpy-tool.py -xd ports/minimal/frozentest.mpy + python2 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy + python3 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy # Test mpy-tool.py dump feature on native code make -C examples/natmod/features1 From 920da9c5e30da58d5f77b2c5e28c74e3670e6a3b Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Mon, 19 Sep 2022 12:05:39 +1000 Subject: [PATCH 1761/4290] unix/variants/coverage: Add test for manifest freeze_mpy(). This uses the frozentest.mpy that is also used by ports/minimal. Also fixes two bugs that these new tests picked up: - File extension matching in manifestfile.py. - Handling of freeze_mpy results in makemanifest. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- ports/unix/variants/coverage/manifest.py | 1 + tests/unix/extra_coverage.py | 5 +++++ tests/unix/extra_coverage.py.exp | 10 ++++++++++ tools/makemanifest.py | 6 +++--- tools/manifestfile.py | 17 +++++++++++++---- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/ports/unix/variants/coverage/manifest.py b/ports/unix/variants/coverage/manifest.py index 611105088422..7c3d9a6b64d6 100644 --- a/ports/unix/variants/coverage/manifest.py +++ b/ports/unix/variants/coverage/manifest.py @@ -1,2 +1,3 @@ freeze_as_str("frzstr") freeze_as_mpy("frzmpy") +freeze_mpy("$(MPY_DIR)/tests/frozen") diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py index bb22485026e8..00226a68e601 100644 --- a/tests/unix/extra_coverage.py +++ b/tests/unix/extra_coverage.py @@ -96,3 +96,8 @@ from frzqstr import returns_NULL print(returns_NULL()) + +# test for freeze_mpy +import frozentest + +print(frozentest.__file__) diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 4d6e1e08567d..29411545569d 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -199,3 +199,13 @@ X '\x1b' b'\x00\xff' NULL +uPy +a long string that is not interned +a string that has unicode αβγ chars +b'bytes 1234\x01' +123456789 +0 +1 +2 +3 +frozentest.py diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 9dd8815aac5f..b2e4f7d8441b 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -210,9 +210,9 @@ def main(): ts_outfile = get_timestamp(outfile) mpy_files.append(outfile) else: - assert kind == manifestfile.KIND_FREEZE_MPY - mpy_files.append(full_path) - ts_outfile = timestamp + assert result.kind == manifestfile.KIND_FREEZE_MPY + mpy_files.append(result.full_path) + ts_outfile = result.timestamp ts_newest = max(ts_newest, ts_outfile) # Check if output file needs generating diff --git a/tools/manifestfile.py b/tools/manifestfile.py index 84c79ed82b28..a4d056137ffc 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -394,28 +394,37 @@ def freeze(self, path, script=None, opt=None): `opt` is the optimisation level to pass to mpy-cross when compiling .py to .mpy. """ - self._freeze_internal(path, script, exts=(".py", ".mpy"), kind=KIND_FREEZE_AUTO, opt=opt) + self._freeze_internal( + path, + script, + exts=( + ".py", + ".mpy", + ), + kind=KIND_FREEZE_AUTO, + opt=opt, + ) def freeze_as_str(self, path): """ Freeze the given `path` and all .py scripts within it as a string, which will be compiled upon import. """ - self._search(path, None, None, exts=(".py"), kind=KIND_FREEZE_AS_STR) + self._search(path, None, None, exts=(".py",), kind=KIND_FREEZE_AS_STR) def freeze_as_mpy(self, path, script=None, opt=None): """ Freeze the input (see above) by first compiling the .py scripts to .mpy files, then freezing the resulting .mpy files. """ - self._freeze_internal(path, script, exts=(".py"), kind=KIND_FREEZE_AS_MPY, opt=opt) + self._freeze_internal(path, script, exts=(".py",), kind=KIND_FREEZE_AS_MPY, opt=opt) def freeze_mpy(self, path, script=None, opt=None): """ Freeze the input (see above), which must be .mpy files that are frozen directly. """ - self._freeze_internal(path, script, exts=(".mpy"), kind=KIND_FREEZE_MPY, opt=opt) + self._freeze_internal(path, script, exts=(".mpy",), kind=KIND_FREEZE_MPY, opt=opt) # Generate a temporary file with a line appended to the end that adds __version__. From 7589d86b6b6ea4232ff5614f3e73565529d4b3bb Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 20 Sep 2022 08:54:53 +1000 Subject: [PATCH 1762/4290] tests/run-multitests: Extend usage information. --- tests/run-multitests.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/run-multitests.py b/tests/run-multitests.py index bd6cc70f7a51..b5ba83b0ad34 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -3,6 +3,11 @@ # This file is part of the MicroPython project, http://micropython.org/ # The MIT License (MIT) # Copyright (c) 2020 Damien P. George +# +# run-multitests.py +# Runs a test suite that relies on two micropython instances/devices +# interacting in some way. Typically used to test networking / bluetooth etc. + import sys, os, time, re, select import argparse @@ -471,7 +476,10 @@ def run_tests(test_files, instances_truth, instances_test): def main(): global cmd_args - cmd_parser = argparse.ArgumentParser(description="Run network tests for MicroPython") + cmd_parser = argparse.ArgumentParser( + description="Run network tests for MicroPython", + formatter_class=argparse.RawTextHelpFormatter, + ) cmd_parser.add_argument( "-s", "--show-output", action="store_true", help="show test output after running" ) @@ -488,6 +496,14 @@ def main(): default=1, help="repeat the test with this many permutations of the instance order", ) + cmd_parser.epilog = ( + "Supported instance types:\r\n" + " -i pyb: physical device (eg. pyboard) on provided repl port.\n" + " -i micropython unix micropython instance, path customised with MICROPY_MICROPYTHON env.\n" + " -i cpython desktop python3 instance, path customised with MICROPY_CPYTHON3 env.\n" + " -i exec: custom program run on provided path.\n" + "Each instance arg can optionally have custom env provided, eg. ,ENV=VAR,ENV=VAR...\n" + ) cmd_parser.add_argument("files", nargs="+", help="input test files") cmd_args = cmd_parser.parse_args() From 13c4470fd04981fce3fd29771e1d973febbe7d60 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 20 Sep 2022 08:54:58 +1000 Subject: [PATCH 1763/4290] tests/run-multitests: Make paths more deterministic. Allows running from a different directory, etc. This work was funded by Planet Innovation. --- tests/run-multitests.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/run-multitests.py b/tests/run-multitests.py index b5ba83b0ad34..70bae59474b4 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -15,15 +15,24 @@ import subprocess import tempfile -sys.path.append("../tools") +test_dir = os.path.abspath(os.path.dirname(__file__)) + +if os.path.abspath(sys.path[0]) == test_dir: + # remove the micropython/tests dir from path to avoid + # accidentally importing tests like micropython/const.py + sys.path.pop(0) + +sys.path.insert(0, test_dir + "/../tools") import pyboard if os.name == "nt": CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3.exe") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", test_dir + "/../ports/windows/micropython.exe") else: CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") - MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython") + MICROPYTHON = os.getenv( + "MICROPY_MICROPYTHON", test_dir + "/../ports/unix/build-standard/micropython" + ) # For diff'ing test output DIFF = os.getenv("MICROPY_DIFF", "diff -u") @@ -508,7 +517,7 @@ def main(): cmd_args = cmd_parser.parse_args() # clear search path to make sure tests use only builtin modules and those in extmod - os.environ["MICROPYPATH"] = os.pathsep + "../extmod" + os.environ["MICROPYPATH"] = os.pathsep.join(("", ".frozen", "../extmod")) test_files = prepare_test_file_list(cmd_args.files) max_instances = max(t[1] for t in test_files) From ed41d517466f329112529a20f9808f1c1724f759 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Sep 2022 11:47:03 +1000 Subject: [PATCH 1764/4290] extmod/modbluetooth: Change data_len type from size_t to uint16_t. For consistency, and to remove the need for additional conversion of types. Signed-off-by: Damien George --- extmod/modbluetooth.c | 16 ++++++++-------- extmod/modbluetooth.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 9c168483ba45..f02130818711 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -1139,7 +1139,7 @@ STATIC mp_obj_t invoke_irq_handler_run(uint16_t event, const mp_int_t *numeric, size_t n_unsigned, size_t n_signed, const uint8_t *addr, const mp_obj_bluetooth_uuid_t *uuid, - const uint8_t **data, size_t *data_len, size_t n_data) { + const uint8_t **data, uint16_t *data_len, size_t n_data) { mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth)); if (o->irq_handler == mp_const_none) { return mp_const_none; @@ -1199,7 +1199,7 @@ STATIC mp_obj_t invoke_irq_handler(uint16_t event, const mp_int_t *numeric, size_t n_unsigned, size_t n_signed, const uint8_t *addr, const mp_obj_bluetooth_uuid_t *uuid, - const uint8_t **data, size_t *data_len, size_t n_data) { + const uint8_t **data, uint16_t *data_len, size_t n_data) { // This code may run on an existing MicroPython thread, or a non-MicroPython thread // that's not using the mp_thread_get_state() value. In the former case the state @@ -1249,7 +1249,7 @@ STATIC mp_obj_t invoke_irq_handler(uint16_t event, const mp_int_t *numeric, size_t n_unsigned, size_t n_signed, const uint8_t *addr, const mp_obj_bluetooth_uuid_t *uuid, - const uint8_t **data, size_t *data_len, size_t n_data) { + const uint8_t **data, uint16_t *data_len, size_t n_data) { return invoke_irq_handler_run(event, numeric, n_unsigned, n_signed, addr, uuid, data, data_len, n_data); } @@ -1277,7 +1277,7 @@ void mp_bluetooth_gatts_on_encryption_update(uint16_t conn_handle, bool encrypte invoke_irq_handler(MP_BLUETOOTH_IRQ_ENCRYPTION_UPDATE, args, 5, 0, NULL_ADDR, NULL_UUID, NULL_DATA, NULL_DATA_LEN, 0); } -bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t *key, size_t key_len, const uint8_t **value, size_t *value_len) { +bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t *key, uint16_t key_len, const uint8_t **value, size_t *value_len) { mp_int_t args[] = {type, index}; mp_obj_t result = invoke_irq_handler(MP_BLUETOOTH_IRQ_GET_SECRET, args, 2, 0, NULL_ADDR, NULL_UUID, &key, &key_len, 1); if (result == mp_const_none) { @@ -1293,7 +1293,7 @@ bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t * bool mp_bluetooth_gap_on_set_secret(uint8_t type, const uint8_t *key, size_t key_len, const uint8_t *value, size_t value_len) { mp_int_t args[] = { type }; const uint8_t *data[] = {key, value}; - size_t data_len[] = {key_len, value_len}; + uint16_t data_len[] = {key_len, value_len}; mp_obj_t result = invoke_irq_handler(MP_BLUETOOTH_IRQ_SET_SECRET, args, 1, 0, NULL_ADDR, NULL_UUID, data, data_len, 2); return mp_obj_is_true(result); } @@ -1364,7 +1364,7 @@ void mp_bluetooth_gap_on_scan_complete(void) { invoke_irq_handler(MP_BLUETOOTH_IRQ_SCAN_DONE, NULL_NUMERIC, 0, 0, NULL_ADDR, NULL_UUID, NULL_DATA, NULL_DATA_LEN, 0); } -void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uint8_t adv_type, const int8_t rssi, const uint8_t *data, size_t data_len) { +void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uint8_t adv_type, const int8_t rssi, const uint8_t *data, uint16_t data_len) { mp_int_t args[] = {addr_type, adv_type, rssi}; invoke_irq_handler(MP_BLUETOOTH_IRQ_SCAN_RESULT, args, 1, 2, addr, NULL_UUID, &data, &data_len, 1); } @@ -1394,7 +1394,7 @@ void mp_bluetooth_gattc_on_discover_complete(uint8_t event, uint16_t conn_handle void mp_bluetooth_gattc_on_data_available(uint8_t event, uint16_t conn_handle, uint16_t value_handle, const uint8_t **data, uint16_t *data_len, size_t num) { const uint8_t *combined_data; - size_t total_len; + uint16_t total_len; if (num > 1) { // Fragmented buffer, need to combine into a new heap-allocated buffer @@ -1553,7 +1553,7 @@ void mp_bluetooth_gap_on_scan_complete(void) { schedule_ringbuf(atomic_state); } -void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uint8_t adv_type, const int8_t rssi, const uint8_t *data, size_t data_len) { +void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uint8_t adv_type, const int8_t rssi, const uint8_t *data, uint16_t data_len) { MICROPY_PY_BLUETOOTH_ENTER mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth)); data_len = MIN(o->irq_data_data_alloc, data_len); diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index d49034627820..ca6436b678d1 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -426,7 +426,7 @@ void mp_bluetooth_gatts_on_encryption_update(uint16_t conn_handle, bool encrypte // For get, if key is NULL, then the implementation must return the index'th matching key. Otherwise it should return a specific key. // For set, if value is NULL, then delete. // The "type" is stack-specific, but could also be used to implement versioning. -bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t *key, size_t key_len, const uint8_t **value, size_t *value_len); +bool mp_bluetooth_gap_on_get_secret(uint8_t type, uint8_t index, const uint8_t *key, uint16_t key_len, const uint8_t **value, size_t *value_len); bool mp_bluetooth_gap_on_set_secret(uint8_t type, const uint8_t *key, size_t key_len, const uint8_t *value, size_t value_len); // Call this when a passkey verification needs to be processed. @@ -451,7 +451,7 @@ void mp_bluetooth_gatts_on_mtu_exchanged(uint16_t conn_handle, uint16_t value); void mp_bluetooth_gap_on_scan_complete(void); // Notify modbluetooth of a scan result. -void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uint8_t adv_type, const int8_t rssi, const uint8_t *data, size_t data_len); +void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uint8_t adv_type, const int8_t rssi, const uint8_t *data, uint16_t data_len); #endif // MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE #if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT From db668742a5986ab1de9c0474ef268c00fb1879e7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 21 Sep 2022 13:22:27 +1000 Subject: [PATCH 1765/4290] extmod/modbluetooth: Do GATTC reassembly in protected uPy context. The calls to m_new and m_del require an exclusive uPy (really a GC) context. In particular these functions cannot be called directly from a FreeRTOS task on esp32. Fixes issue #9369. Signed-off-by: Damien George --- extmod/modbluetooth.c | 67 +++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index f02130818711..acdbf8d85d02 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -52,6 +52,9 @@ #error pairing and bonding require synchronous modbluetooth events #endif +// NimBLE can have fragmented data for GATTC events, so requires reassembly. +#define MICROPY_PY_BLUETOOTH_USE_GATTC_EVENT_DATA_REASSEMBLY MICROPY_BLUETOOTH_NIMBLE + #define MP_BLUETOOTH_CONNECT_DEFAULT_SCAN_DURATION_MS 2000 #define MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_TUPLE_LEN 5 @@ -1168,6 +1171,34 @@ STATIC mp_obj_t invoke_irq_handler_run(uint16_t event, data_tuple->items[data_tuple->len++] = MP_OBJ_FROM_PTR(uuid); } #endif + + #if MICROPY_PY_BLUETOOTH_USE_GATTC_EVENT_DATA_REASSEMBLY + void *buf_to_free = NULL; + uint16_t buf_to_free_len = 0; + if (event == MP_BLUETOOTH_IRQ_GATTC_NOTIFY || event == MP_BLUETOOTH_IRQ_GATTC_INDICATE || event == MP_BLUETOOTH_IRQ_GATTC_READ_RESULT) { + if (n_data > 1) { + // Fragmented buffer, need to combine into a new heap-allocated buffer + // in order to pass to Python. + // Only gattc_on_data_available calls this code, so data and data_len are writable. + uint16_t total_len = 0; + for (size_t i = 0; i < n_data; ++i) { + total_len += data_len[i]; + } + uint8_t *buf = m_new(uint8_t, total_len); + uint8_t *p = buf; + for (size_t i = 0; i < n_data; ++i) { + memcpy(p, data[i], data_len[i]); + p += data_len[i]; + } + data[0] = buf; + data_len[0] = total_len; + n_data = 1; + buf_to_free = buf; + buf_to_free_len = total_len; + } + } + #endif + for (size_t i = 0; i < n_data; ++i) { if (data[i]) { mp_obj_memoryview_init(&mv_data[i], 'B', 0, data_len[i], (void *)data[i]); @@ -1176,10 +1207,17 @@ STATIC mp_obj_t invoke_irq_handler_run(uint16_t event, data_tuple->items[data_tuple->len++] = mp_const_none; } } + assert(data_tuple->len <= MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_TUPLE_LEN); mp_obj_t result = mp_call_function_2(o->irq_handler, MP_OBJ_NEW_SMALL_INT(event), MP_OBJ_FROM_PTR(data_tuple)); + #if MICROPY_PY_BLUETOOTH_USE_GATTC_EVENT_DATA_REASSEMBLY + if (buf_to_free != NULL) { + m_del(uint8_t, (uint8_t *)buf_to_free, buf_to_free_len); + } + #endif + mp_local_free(data_tuple); return result; @@ -1393,35 +1431,8 @@ void mp_bluetooth_gattc_on_discover_complete(uint8_t event, uint16_t conn_handle } void mp_bluetooth_gattc_on_data_available(uint8_t event, uint16_t conn_handle, uint16_t value_handle, const uint8_t **data, uint16_t *data_len, size_t num) { - const uint8_t *combined_data; - uint16_t total_len; - - if (num > 1) { - // Fragmented buffer, need to combine into a new heap-allocated buffer - // in order to pass to Python. - total_len = 0; - for (size_t i = 0; i < num; ++i) { - total_len += data_len[i]; - } - uint8_t *buf = m_new(uint8_t, total_len); - uint8_t *p = buf; - for (size_t i = 0; i < num; ++i) { - memcpy(p, data[i], data_len[i]); - p += data_len[i]; - } - combined_data = buf; - } else { - // Single buffer, use directly. - combined_data = *data; - total_len = *data_len; - } - mp_int_t args[] = {conn_handle, value_handle}; - invoke_irq_handler(event, args, 2, 0, NULL_ADDR, NULL_UUID, &combined_data, &total_len, 1); - - if (num > 1) { - m_del(uint8_t, (uint8_t *)combined_data, total_len); - } + invoke_irq_handler(event, args, 2, 0, NULL_ADDR, NULL_UUID, data, data_len, num); } void mp_bluetooth_gattc_on_read_write_status(uint8_t event, uint16_t conn_handle, uint16_t value_handle, uint16_t status) { From f2ad152e7e04608cbf57d756f6a4cebbf9976f6c Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 23 Sep 2022 14:20:37 +1000 Subject: [PATCH 1766/4290] extmod/modbluetooth: Run BLE IRQ callback in protected NLR context. The call to invoke_irq_handler_run() always needs to run in a protected NLR context, to catch exceptions from the Python handler, and the m_new's (and also mp_local_alloc when PYSTACK is enabled). With MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS_WITH_INTERLOCK enabled there was already an explicit nlr_push, and that is now used in all cases. Without this change, on stm32 (for example), the callbacks from the BLE stack to invoke_irq_handler() were made via static scheduled nodes which do not have any NLR protection, and hence would lead to a hard fault (uncaught NLR) if an exception was raised in the Python BLE IRQ handler. This was a regression introduced by 8045ac07f599c0ccc447c88a0b778f704b497559, which is fixed by this commit. Signed-off-by: Damien George --- extmod/modbluetooth.c | 51 ++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index acdbf8d85d02..3a51fb8b2399 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -1143,10 +1143,6 @@ STATIC mp_obj_t invoke_irq_handler_run(uint16_t event, const uint8_t *addr, const mp_obj_bluetooth_uuid_t *uuid, const uint8_t **data, uint16_t *data_len, size_t n_data) { - mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth)); - if (o->irq_handler == mp_const_none) { - return mp_const_none; - } mp_obj_array_t mv_addr; mp_obj_array_t mv_data[2]; @@ -1210,6 +1206,7 @@ STATIC mp_obj_t invoke_irq_handler_run(uint16_t event, assert(data_tuple->len <= MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_TUPLE_LEN); + mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth)); mp_obj_t result = mp_call_function_2(o->irq_handler, MP_OBJ_NEW_SMALL_INT(event), MP_OBJ_FROM_PTR(data_tuple)); #if MICROPY_PY_BLUETOOTH_USE_GATTC_EVENT_DATA_REASSEMBLY @@ -1223,6 +1220,34 @@ STATIC mp_obj_t invoke_irq_handler_run(uint16_t event, return result; } +STATIC mp_obj_t invoke_irq_handler_run_protected(uint16_t event, + const mp_int_t *numeric, size_t n_unsigned, size_t n_signed, + const uint8_t *addr, + const mp_obj_bluetooth_uuid_t *uuid, + const uint8_t **data, uint16_t *data_len, size_t n_data) { + + mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth)); + if (o->irq_handler == mp_const_none) { + return mp_const_none; + } + + mp_obj_t result = mp_const_none; + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + result = invoke_irq_handler_run(event, numeric, n_unsigned, n_signed, addr, uuid, data, data_len, n_data); + nlr_pop(); + } else { + // Uncaught exception, print it out. + mp_printf(MICROPY_ERROR_PRINTER, "Unhandled exception in IRQ callback handler\n"); + mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(nlr.ret_val)); + + // Disable the BLE IRQ handler. + o->irq_handler = mp_const_none; + } + + return result; +} + #if MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS_WITH_INTERLOCK // On some systems the BLE event callbacks may occur on a system thread which is not @@ -1256,19 +1281,9 @@ STATIC mp_obj_t invoke_irq_handler(uint16_t event, MP_THREAD_GIL_ENTER(); } - mp_obj_t result = mp_const_none; - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_sched_lock(); - result = invoke_irq_handler_run(event, numeric, n_unsigned, n_signed, addr, uuid, data, data_len, n_data); - mp_sched_unlock(); - nlr_pop(); - } else { - // Uncaught exception, print it out. - mp_sched_unlock(); - mp_printf(MICROPY_ERROR_PRINTER, "Unhandled exception in IRQ callback handler\n"); - mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(nlr.ret_val)); - } + mp_sched_lock(); + mp_obj_t result = invoke_irq_handler_run_protected(event, numeric, n_unsigned, n_signed, addr, uuid, data, data_len, n_data); + mp_sched_unlock(); if (ts_orig == NULL) { MP_THREAD_GIL_EXIT(); @@ -1288,7 +1303,7 @@ STATIC mp_obj_t invoke_irq_handler(uint16_t event, const uint8_t *addr, const mp_obj_bluetooth_uuid_t *uuid, const uint8_t **data, uint16_t *data_len, size_t n_data) { - return invoke_irq_handler_run(event, numeric, n_unsigned, n_signed, addr, uuid, data, data_len, n_data); + return invoke_irq_handler_run_protected(event, numeric, n_unsigned, n_signed, addr, uuid, data, data_len, n_data); } #endif From f91ebf6fa972a593ede25d33740e693d99dbbc3f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 15 Aug 2022 12:02:23 +1000 Subject: [PATCH 1767/4290] tests: Allow 'special' tests to output "SKIP" on a single line. --- tests/run-tests.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/run-tests.py b/tests/run-tests.py index ca7941f6261b..6031b35b5334 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -305,6 +305,10 @@ def send_get(what): if had_crash or output_mupy in (b"SKIP\n", b"CRASH"): return output_mupy + # skipped special tests will output "SKIP" surrounded by other interpreter debug output + if is_special and not had_crash and b"\nSKIP\n" in output_mupy: + return b"SKIP\n" + if is_special or test_file in special_tests: # convert parts of the output that are not stable across runs with open(test_file + ".exp", "rb") as f: From 25ff5b52d9786beff0b90a268af813b223f31f57 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 27 Jul 2022 12:52:48 +1000 Subject: [PATCH 1768/4290] py/parse: Allow const types other than int to optimise as true/false. Allows optimisation of cases like: import micropython _DEBUG = micropython.const(False) if _DEBUG: print('Debugging info') Previously the 'if' statement was only optimised out if the type of the const() argument was integer. The change is implemented in a way that makes the compiler slightly smaller (-16 bytes on PYBV11) but compilation will also be very slightly slower. As a bonus, if const support is enabled then the compiler can now optimise const truthy/falsey expressions of other types, like: while "something": pass ... unclear if that is useful, but perhaps it could be. Signed-off-by: Angus Gratton --- py/parse.c | 28 +++-- tests/cmdline/cmd_showbc_const.py | 69 +++++++++++ tests/cmdline/cmd_showbc_const.py.exp | 160 ++++++++++++++++++++++++++ 3 files changed, 247 insertions(+), 10 deletions(-) create mode 100644 tests/cmdline/cmd_showbc_const.py create mode 100644 tests/cmdline/cmd_showbc_const.py.exp diff --git a/py/parse.c b/py/parse.c index d58098af2e16..62de3282b344 100644 --- a/py/parse.c +++ b/py/parse.c @@ -334,16 +334,6 @@ STATIC uint8_t peek_rule(parser_t *parser, size_t n) { } #endif -bool mp_parse_node_is_const_false(mp_parse_node_t pn) { - return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_FALSE) - || (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) == 0); -} - -bool mp_parse_node_is_const_true(mp_parse_node_t pn) { - return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_TRUE) - || (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) != 0); -} - bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) { if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { *o = MP_OBJ_NEW_SMALL_INT(MP_PARSE_NODE_LEAF_SMALL_INT(pn)); @@ -427,6 +417,24 @@ STATIC mp_obj_t mp_parse_node_convert_to_obj(mp_parse_node_t pn) { } #endif +STATIC bool parse_node_is_const_bool(mp_parse_node_t pn, bool value) { + // Returns true if 'pn' is a constant whose boolean value is equivalent to 'value' + #if MICROPY_COMP_CONST_TUPLE || MICROPY_COMP_CONST + return mp_parse_node_is_const(pn) && mp_obj_is_true(mp_parse_node_convert_to_obj(pn)) == value; + #else + return MP_PARSE_NODE_IS_TOKEN_KIND(pn, value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE) + || (MP_PARSE_NODE_IS_SMALL_INT(pn) && !!MP_PARSE_NODE_LEAF_SMALL_INT(pn) == value); + #endif +} + +bool mp_parse_node_is_const_false(mp_parse_node_t pn) { + return parse_node_is_const_bool(pn, false); +} + +bool mp_parse_node_is_const_true(mp_parse_node_t pn) { + return parse_node_is_const_bool(pn, true); +} + size_t mp_parse_node_extract_list(mp_parse_node_t *pn, size_t pn_kind, mp_parse_node_t **nodes) { if (MP_PARSE_NODE_IS_NULL(*pn)) { *nodes = NULL; diff --git a/tests/cmdline/cmd_showbc_const.py b/tests/cmdline/cmd_showbc_const.py new file mode 100644 index 000000000000..54f9ec23cdbe --- /dev/null +++ b/tests/cmdline/cmd_showbc_const.py @@ -0,0 +1,69 @@ +# cmdline: -v -v +# Test constant-related bytecode optimisations +# (constant folding, compile-time if/while evaluation, etc.) +from micropython import const +import sys + +try: + sys.settrace + # if MICROPY_PY_SYS_SETTRACE is enabled, compile-time const optimizations + # are disabled so the bytecode output is very different + print("SKIP") + raise SystemExit +except AttributeError: + pass + +_STR = const("foo") +_EMPTY_TUPLE = const(()) +_TRUE = const(True) +_FALSE = const(False) +_SMALLINT = const(33) +_ZERO = const(0) + +# Bytecode generated for these if/while statements should contain no JUMP_IF +# and no instances of string 'Eliminated' + +if _STR or _EMPTY_TUPLE: + print("Kept") +if _STR and _EMPTY_TUPLE: + print("Eliminated") +if _TRUE: + print("Kept") +if _SMALLINT: + print("Kept") +if _ZERO and _SMALLINT: + print("Eliminated") +if _FALSE: + print("Eliminated") + +while _SMALLINT: + print("Kept") + break +while _ZERO: + print("Eliminated") +while _FALSE: + print("Eliminated") + +# These values are stored in variables, and therefore bytecode will contain JUMP_IF + +a = _EMPTY_TUPLE or _STR +if a == _STR: + print("Kept") + +b = _SMALLINT and _STR +if b == _STR: + print("Kept") + +# The compiler is also unable to optimise these expressions, even though the arguments are const, +# so these also contain JUMP_IF + +if (_EMPTY_TUPLE or _STR) == _STR: + print("Kept") + +if (_EMPTY_TUPLE and _STR) == _STR: + print("Not Eliminated") + +if (not _STR) == _FALSE: + print("Kept") + +assert True diff --git a/tests/cmdline/cmd_showbc_const.py.exp b/tests/cmdline/cmd_showbc_const.py.exp new file mode 100644 index 000000000000..6cdc3e9c9637 --- /dev/null +++ b/tests/cmdline/cmd_showbc_const.py.exp @@ -0,0 +1,160 @@ +File cmdline/cmd_showbc_const.py, code block '' (descriptor: \.\+, bytecode @\.\+ 198 bytes) +Raw bytecode (code_info_size=40, bytecode_size=158): + 2c 4c 01 60 2c 46 22 65 27 4a 83 0c 20 27 40 20 + 27 20 27 40 60 20 27 24 40 60 40 24 27 47 24 27 + 67 40 27 47 27 47 26 47 80 10 02 2a 01 1b 03 1c + 02 16 02 59 80 51 1b 04 16 04 48 0f 11 04 13 05 + 59 11 09 10 06 34 01 59 11 0a 65 57 11 0b df 44 + 43 59 4a 01 5d 11 09 10 07 34 01 59 11 09 10 07 + 34 01 59 11 09 10 07 34 01 59 11 09 10 07 34 01 + 59 42 42 42 35 23 00 16 0c 11 0c 23 00 d9 44 47 + 11 09 10 07 34 01 59 23 00 16 0d 11 0d 23 00 d9 + 44 47 11 09 10 07 34 01 59 23 00 23 00 d9 44 47 + 11 09 10 07 34 01 59 23 01 23 00 d9 44 47 11 09 + 23 02 34 01 59 50 23 03 d9 44 47 11 09 10 07 34 + 01 59 42 40 51 63 +arg names: +(N_STATE 6) +(N_EXC_STACK 1) + bc=0 line=1 + bc=0 line=4 + bc=12 line=5 + bc=18 line=7 + bc=20 line=8 + bc=25 line=11 + bc=32 line=12 + bc=42 line=14 + bc=45 line=26 + bc=45 line=27 + bc=52 line=28 + bc=52 line=30 + bc=52 line=31 + bc=59 line=32 + bc=59 line=33 + bc=66 line=34 + bc=66 line=36 + bc=66 line=39 + bc=66 line=40 + bc=73 line=41 + bc=77 line=42 + bc=77 line=44 + bc=77 line=47 + bc=77 line=49 + bc=81 line=50 + bc=88 line=51 + bc=95 line=53 + bc=99 line=54 + bc=106 line=55 + bc=113 line=58 + bc=113 line=60 + bc=120 line=61 + bc=127 line=63 + bc=134 line=64 + bc=141 line=66 + bc=147 line=67 + bc=154 line=69 +00 LOAD_CONST_SMALL_INT 0 +01 LOAD_CONST_STRING 'const' +03 BUILD_TUPLE 1 +05 IMPORT_NAME 'micropython' +07 IMPORT_FROM 'const' +09 STORE_NAME const +11 POP_TOP +12 LOAD_CONST_SMALL_INT 0 +13 LOAD_CONST_NONE +14 IMPORT_NAME 'sys' +16 STORE_NAME sys +18 SETUP_EXCEPT 35 +20 LOAD_NAME sys +22 LOAD_ATTR settrace +24 POP_TOP +25 LOAD_NAME print +27 LOAD_CONST_STRING 'SKIP' +29 CALL_FUNCTION n=1 nkw=0 +31 POP_TOP +32 LOAD_NAME SystemExit +34 RAISE_OBJ +35 DUP_TOP +36 LOAD_NAME AttributeError +38 BINARY_OP 8 +39 POP_JUMP_IF_FALSE 44 +41 POP_TOP +42 POP_EXCEPT_JUMP 45 +44 END_FINALLY +45 LOAD_NAME print +47 LOAD_CONST_STRING 'Kept' +49 CALL_FUNCTION n=1 nkw=0 +51 POP_TOP +52 LOAD_NAME print +54 LOAD_CONST_STRING 'Kept' +56 CALL_FUNCTION n=1 nkw=0 +58 POP_TOP +59 LOAD_NAME print +61 LOAD_CONST_STRING 'Kept' +63 CALL_FUNCTION n=1 nkw=0 +65 POP_TOP +66 LOAD_NAME print +68 LOAD_CONST_STRING 'Kept' +70 CALL_FUNCTION n=1 nkw=0 +72 POP_TOP +73 JUMP 77 +75 JUMP 66 +77 LOAD_CONST_OBJ \.\+='foo' +79 STORE_NAME a +81 LOAD_NAME a +83 LOAD_CONST_OBJ \.\+='foo' +85 BINARY_OP 2 __eq__ +86 POP_JUMP_IF_FALSE 95 +88 LOAD_NAME print +90 LOAD_CONST_STRING 'Kept' +92 CALL_FUNCTION n=1 nkw=0 +94 POP_TOP +95 LOAD_CONST_OBJ \.\+='foo' +97 STORE_NAME b +99 LOAD_NAME b +101 LOAD_CONST_OBJ \.\+='foo' +103 BINARY_OP 2 __eq__ +104 POP_JUMP_IF_FALSE 113 +106 LOAD_NAME print +108 LOAD_CONST_STRING 'Kept' +110 CALL_FUNCTION n=1 nkw=0 +112 POP_TOP +113 LOAD_CONST_OBJ \.\+='foo' +115 LOAD_CONST_OBJ \.\+='foo' +117 BINARY_OP 2 __eq__ +118 POP_JUMP_IF_FALSE 127 +120 LOAD_NAME print +122 LOAD_CONST_STRING 'Kept' +124 CALL_FUNCTION n=1 nkw=0 +126 POP_TOP +127 LOAD_CONST_OBJ \.\+=() +129 LOAD_CONST_OBJ \.\+='foo' +131 BINARY_OP 2 __eq__ +132 POP_JUMP_IF_FALSE 141 +134 LOAD_NAME print +136 LOAD_CONST_OBJ \.\+='Not Eliminated' +138 CALL_FUNCTION n=1 nkw=0 +140 POP_TOP +141 LOAD_CONST_FALSE +142 LOAD_CONST_OBJ \.\+=False +144 BINARY_OP 2 __eq__ +145 POP_JUMP_IF_FALSE 154 +147 LOAD_NAME print +149 LOAD_CONST_STRING 'Kept' +151 CALL_FUNCTION n=1 nkw=0 +153 POP_TOP +154 JUMP 156 +156 LOAD_CONST_NONE +157 RETURN_VALUE +Kept +Kept +Kept +Kept +Kept +Kept +Kept +Kept +mem: total=\\d\+, current=\\d\+, peak=\\d\+ +stack: \\d\+ out of \\d\+ +GC: total: \\d\+, used: \\d\+, free: \\d\+ + No. of 1-blocks: \\d\+, 2-blocks: \\d\+, max blk sz: \\d\+, max free sz: \\d\+ From 30e50ab1951680a046c224c12f7cc29aed410e2a Mon Sep 17 00:00:00 2001 From: Jatty_ Date: Tue, 13 Sep 2022 18:38:03 +0700 Subject: [PATCH 1769/4290] stm32/make-stmconst.py: Support TypeDef's with a single char prefix. Update the regex to support parsing files from the STM32CubeU5 library. --- ports/stm32/make-stmconst.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/make-stmconst.py b/ports/stm32/make-stmconst.py index 554d66238445..aab4038e61df 100644 --- a/ports/stm32/make-stmconst.py +++ b/ports/stm32/make-stmconst.py @@ -72,7 +72,7 @@ class Lexer: ("}", re.compile(r"}$")), ( "} TypeDef", - re.compile(r"} *(?P[A-Z][A-Za-z0-9_]+)_(?P([A-Za-z0-9_]+)?)TypeDef;$"), + re.compile(r"} *(?P[A-Z][A-Za-z0-9_]*)_(?P([A-Za-z0-9_]+)?)TypeDef;$"), ), ( "IO reg", From ae0b0e701899297d057ab8dc578b3bdbf0144fc4 Mon Sep 17 00:00:00 2001 From: yn386 Date: Mon, 19 Sep 2022 17:55:51 +0900 Subject: [PATCH 1770/4290] lib/stm32lib: Update library to get L1 v1.10.3, and some other fixes. Changes in this new library version are: - Add L1 HAL at v1.10.3. - H7_HAL/rcc_ex: Add SPI45 to HAL_RCCEx_GetPeriphCLKFreq. - L4_HAL/gpio_ex: Add #define for GPIO_AF14_TIM2 on L4P5/L4Q5. - F4_HAL/i2c: Fix I2C frequency calculation macros. - L1_HAL/utils: Fix compile error when USE_HAL_DRIVER is defined. --- .gitmodules | 2 +- lib/stm32lib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3c47b5959aad..992fec3d1836 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ [submodule "lib/stm32lib"] path = lib/stm32lib url = https://github.com/micropython/stm32lib - branch = work-F0-1.9.0+F4-1.16.0+F7-1.7.0+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.17.0+WB-1.10.0+WL-1.1.0 + branch = work-F0-1.9.0+F4-1.16.0+F7-1.7.0+G0-1.5.1+G4-1.3.0+H7-1.6.0+L0-1.11.2+L1-1.10.3+L4-1.17.0+WB-1.10.0+WL-1.1.0 [submodule "lib/nrfx"] path = lib/nrfx url = https://github.com/NordicSemiconductor/nrfx.git diff --git a/lib/stm32lib b/lib/stm32lib index eb80f0126e50..a9f8fee7bb0c 160000 --- a/lib/stm32lib +++ b/lib/stm32lib @@ -1 +1 @@ -Subproject commit eb80f0126e50687aac966f4c39a2b5a5deffbe78 +Subproject commit a9f8fee7bb0cb4ac1b4ff719b6b5b285f613f352 From 427d72667f23ef8758fbfd2352dd28ba5565644a Mon Sep 17 00:00:00 2001 From: yn386 Date: Mon, 19 Sep 2022 17:56:31 +0900 Subject: [PATCH 1771/4290] stm32: Add support for STM32L1 MCUs. This change adds STM32L1 support to the STM32 port. --- ports/stm32/Makefile | 7 ++ ports/stm32/adc.c | 55 ++++++++- ports/stm32/boards/stm32l152_af.csv | 117 +++++++++++++++++++ ports/stm32/boards/stm32l152xe.ld | 37 ++++++ ports/stm32/boards/stm32l1xx_hal_conf_base.h | 99 ++++++++++++++++ ports/stm32/dac.c | 2 + ports/stm32/dma.c | 66 ++++++++++- ports/stm32/dma.h | 14 +++ ports/stm32/extint.c | 4 + ports/stm32/extint.h | 2 +- ports/stm32/flash.c | 10 +- ports/stm32/machine_adc.c | 7 +- ports/stm32/modmachine.c | 4 +- ports/stm32/mpconfigboard_common.h | 10 ++ ports/stm32/mphalport.c | 2 +- ports/stm32/mphalport.h | 2 + ports/stm32/powerctrl.c | 6 +- ports/stm32/powerctrlboot.c | 68 +++++++++++ ports/stm32/resethandler_m3.s | 75 ++++++++++++ ports/stm32/rtc.c | 17 +++ ports/stm32/stm32.mk | 3 +- ports/stm32/stm32_it.c | 34 ++++++ ports/stm32/timer.c | 34 ++++-- ports/stm32/uart.c | 17 ++- ports/stm32/uart.h | 2 +- 25 files changed, 657 insertions(+), 37 deletions(-) create mode 100644 ports/stm32/boards/stm32l152_af.csv create mode 100644 ports/stm32/boards/stm32l152xe.ld create mode 100644 ports/stm32/boards/stm32l1xx_hal_conf_base.h create mode 100644 ports/stm32/resethandler_m3.s diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index ee00d7717364..4b4a9f0ce380 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -347,11 +347,18 @@ SRC_O += \ resethandler_m0.o \ shared/runtime/gchelper_m0.o else +ifeq ($(MCU_SERIES),l1) +CFLAGS += -DUSE_HAL_DRIVER +SRC_O += \ + resethandler_m3.o \ + shared/runtime/gchelper_m3.o +else SRC_O += \ system_stm32.o \ resethandler.o \ shared/runtime/gchelper_m3.o endif +endif HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ hal.c \ diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c index 712e9b3adeb2..02bbbb58db9e 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -118,6 +118,14 @@ #define ADC_CAL2 ((uint16_t *)(0x1FF1E840)) #define ADC_CAL_BITS (16) +#elif defined(STM32L1) + +#define ADC_SCALE_V (VREFINT_CAL_VREF / 1000.0f) +#define ADC_CAL_ADDRESS (VREFINT_CAL_ADDR) +#define ADC_CAL1 (TEMPSENSOR_CAL1_ADDR) +#define ADC_CAL2 (TEMPSENSOR_CAL2_ADDR) +#define ADC_CAL_BITS (12) + #elif defined(STM32L4) || defined(STM32WB) #define ADC_SCALE_V (VREFINT_CAL_VREF / 1000.0f) @@ -163,6 +171,8 @@ defined(STM32L476xx) || defined(STM32L496xx) || \ defined(STM32WB55xx) #define VBAT_DIV (3) +#elif defined(STM32L152xE) +// STM32L152xE does not have vbat. #else #error Unsupported processor #endif @@ -179,11 +189,17 @@ #define VREFIN_CAL ((uint16_t *)ADC_CAL_ADDRESS) #ifndef __HAL_ADC_IS_CHANNEL_INTERNAL +#if defined(STM32L1) +#define __HAL_ADC_IS_CHANNEL_INTERNAL(channel) \ + (channel == ADC_CHANNEL_VREFINT \ + || channel == ADC_CHANNEL_TEMPSENSOR) +#else #define __HAL_ADC_IS_CHANNEL_INTERNAL(channel) \ (channel == ADC_CHANNEL_VBAT \ || channel == ADC_CHANNEL_VREFINT \ || channel == ADC_CHANNEL_TEMPSENSOR) #endif +#endif typedef struct _pyb_obj_adc_t { mp_obj_base_t base; @@ -210,6 +226,10 @@ STATIC bool is_adcx_channel(int channel) { return IS_ADC_CHANNEL(channel) || channel == ADC_CHANNEL_TEMPSENSOR; #elif defined(STM32F0) || defined(STM32F4) || defined(STM32F7) return IS_ADC_CHANNEL(channel); + #elif defined(STM32L1) + // The HAL of STM32L1 defines some channels those may not be available on package + return __HAL_ADC_IS_CHANNEL_INTERNAL(channel) + || (channel < MP_ARRAY_SIZE(pin_adcall_table) && pin_adcall_table[channel]); #elif defined(STM32G0) || defined(STM32H7) return __HAL_ADC_IS_CHANNEL_INTERNAL(channel) || IS_ADC_CHANNEL(__HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel)); @@ -225,7 +245,7 @@ STATIC bool is_adcx_channel(int channel) { STATIC void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t timeout) { uint32_t tickstart = HAL_GetTick(); - #if defined(STM32F4) || defined(STM32F7) + #if defined(STM32F4) || defined(STM32F7) || defined(STM32L1) while ((adcHandle->Instance->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) { #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) while (READ_BIT(adcHandle->Instance->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) { @@ -239,7 +259,7 @@ STATIC void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t ti } STATIC void adcx_clock_enable(ADC_HandleTypeDef *adch) { - #if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) + #if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32L1) ADCx_CLK_ENABLE(); #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) __HAL_RCC_ADC12_CLK_ENABLE(); @@ -299,6 +319,12 @@ STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) { adch->Init.OversamplingMode = DISABLE; adch->Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; adch->Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; + #elif defined(STM32L1) + adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; + adch->Init.ScanConvMode = ADC_SCAN_DISABLE; + adch->Init.LowPowerAutoWait = DISABLE; + adch->Init.DataAlign = ADC_DATAALIGN_RIGHT; + adch->Init.DMAContinuousRequests = DISABLE; #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; adch->Init.ScanConvMode = ADC_SCAN_DISABLE; @@ -367,6 +393,12 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel) sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.OffsetRightShift = DISABLE; sConfig.OffsetSignedSaturation = DISABLE; + #elif defined(STM32L1) + if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) { + sConfig.SamplingTime = ADC_SAMPLETIME_384CYCLES; + } else { + sConfig.SamplingTime = ADC_SAMPLETIME_384CYCLES; + } #elif defined(STM32G0) if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) { sConfig.SamplingTime = ADC_SAMPLETIME_160CYCLES_5; @@ -555,7 +587,7 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_ HAL_ADC_Start(&self->handle); } else { // for subsequent samples we can just set the "start sample" bit - #if defined(STM32F4) || defined(STM32F7) + #if defined(STM32F4) || defined(STM32F7) || defined(STM32L1) self->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) SET_BIT(self->handle.Instance->CR, ADC_CR_ADSTART); @@ -665,7 +697,7 @@ STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i adc_config_channel(&adc->handle, adc->channel); // for the first sample we need to turn the ADC on // ADC is started: set the "start sample" bit - #if defined(STM32F4) || defined(STM32F7) + #if defined(STM32F4) || defined(STM32F7) || defined(STM32L1) adc->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) SET_BIT(adc->handle.Instance->CR, ADC_CR_ADSTART); @@ -720,6 +752,8 @@ typedef struct _pyb_adc_all_obj_t { ADC_HandleTypeDef handle; } pyb_adc_all_obj_t; +float adc_read_core_vref(ADC_HandleTypeDef *adcHandle); + void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_mask) { switch (resolution) { @@ -762,7 +796,11 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m } int adc_get_resolution(ADC_HandleTypeDef *adcHandle) { + #if defined(STM32L1) + uint32_t res_reg = adcHandle->Instance->CR1 & ADC_CR1_RES_Msk; + #else uint32_t res_reg = ADC_GET_RESOLUTION(adcHandle); + #endif switch (res_reg) { #if !defined(STM32H7) @@ -814,6 +852,11 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) { return 0; } #else + #if defined(STM32L1) + // Update the reference correction factor before reading tempsensor + // because TS_CAL1 and TS_CAL2 of STM32L1 are at VDDA=3.0V + adc_read_core_vref(adcHandle); + #endif int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR); #endif float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 80.0f; @@ -821,8 +864,12 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) { } float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) { + #if defined(STM32L152xE) + mp_raise_NotImplementedError(MP_ERROR_TEXT("read_core_vbat not supported")); + #else uint32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_VBAT); return raw_value * VBAT_DIV * ADC_SCALE * adc_refcor; + #endif } float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) { diff --git a/ports/stm32/boards/stm32l152_af.csv b/ports/stm32/boards/stm32l152_af.csv new file mode 100644 index 000000000000..a6f8e80c3028 --- /dev/null +++ b/ports/stm32/boards/stm32l152_af.csv @@ -0,0 +1,117 @@ +Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15, +,,SYS_AF,TIM2,TIM3/TIM4/TIM5,TIM9/TIM10/TIM11,I2C1/I2C2,SPI1/SPI2,SPI3,USART1/USART2/USART3,UART4/UART5,,,,,,,,ADC +PortA,PA0,,TIM2_CH1_ETR,TIM5_CH1,,,,,USART2_CTS,,,,,,,,EVENTOUT,ADC1_IN0 +PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,,,,,,,,EVENTOUT,ADC1_IN1 +PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,,,,,,,,EVENTOUT,ADC1_IN2 +PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,,,,,,,EVENTOUT,ADC1_IN3 +PortA,PA4,,,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,,,,EVENTOUT,ADC1_IN4 +PortA,PA5,,TIM2_CH1_ETR,,,,SPI1_SCK,,,,,,,,,,EVENTOUT,ADC1_IN5 +PortA,PA6,,,TIM3_CH1,TIM10_CH1,,SPI1_MISO,,,,,,,,,,EVENTOUT,ADC1_IN6 +PortA,PA7,,,TIM3_CH2,TIM11_CH1,,SPI1_MOSI,,,,,,,,,,EVENTOUT,ADC1_IN7 +PortA,PA8,MCO,,,,,,,USART1_CK,,,,,,,,EVENTOUT, +PortA,PA9,,,,,,,,USART1_TX,,,,,,,,EVENTOUT, +PortA,PA10,,,,,,,,USART1_RX,,,,,,,,EVENTOUT, +PortA,PA11,,,,,,SPI1_MISO,,USART1_CTS,,,,,,,,EVENTOUT, +PortA,PA12,,,,,,SPI1_MOSI,,USART1_RTS,,,,,,,,EVENTOUT, +PortA,PA13,JTMS/SWDIO,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA14,JTCK/SWCLK,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA15,JTDI,TIM2_CH1_ETR,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,,,,,,,,,EVENTOUT, +PortB,PB0,,,TIM3_CH3,,,,,,,,,,,,,EVENTOUT,ADC1_IN8 +PortB,PB1,,,TIM3_CH4,,,,,,,,,,,,,EVENTOUT,ADC1_IN9 +PortB,PB2,BOOT1,,,,,,,,,,,,,,,EVENTOUT, +PortB,PB3,JTDO,TIM2_CH2,,,,SPI1_SCK,SPI3_SCK/I2S3_CK,,,,,,,,,EVENTOUT, +PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,,,,,,,,,EVENTOUT, +PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI,SPI3_MOSI/I2S3_SD,,,,,,,,,EVENTOUT, +PortB,PB6,,,TIM4_CH1,,I2C1_SCL,,,USART1_TX,,,,,,,,EVENTOUT, +PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,,,,EVENTOUT, +PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,,,,,,,EVENTOUT, +PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,,,,,,,,,,,EVENTOUT, +PortB,PB10,,TIM2_CH3,,,I2C2_SCL,,,USART3_TX,,,,,,,,EVENTOUT, +PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,,,,,,EVENTOUT, +PortB,PB12,,,,TIM10_CH1,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,,,,,,,EVENTOUT,ADC1_IN18 +PortB,PB13,,,,TIM9_CH1,,SPI2_SCK/I2S2_CK,,USART3_CTS,,,,,,,,EVENTOUT,ADC1_IN19 +PortB,PB14,,,,TIM9_CH2,,SPI2_MISO,,USART3_RTS,,,,,,,,EVENTOUT,ADC1_IN20 +PortB,PB15,,,,TIM11_CH1,,SPI2_MOSI/I2S2_SD,,,,,,,,,,EVENTOUT,ADC1_IN21 +PortC,PC0,,,,,,,,,,,,,,,,EVENTOUT,ADC1_IN10 +PortC,PC1,,,,,,,,,,,,,,,,EVENTOUT,ADC1_IN11 +PortC,PC2,,,,,,,,,,,,,,,,EVENTOUT,ADC1_IN12 +PortC,PC3,,,,,,,,,,,,,,,,EVENTOUT,ADC1_IN13 +PortC,PC4,,,,,,,,,,,,,,,,EVENTOUT,ADC1_IN14 +PortC,PC5,,,,,,,,,,,,,,,,EVENTOUT,ADC1_IN15 +PortC,PC6,,,TIM3_CH1,,,I2S2_MCK,,,,,,,,,,EVENTOUT, +PortC,PC7,,,TIM3_CH2,,,,I2S3_MCK,,,,,,,,,EVENTOUT, +PortC,PC8,,,TIM3_CH3,,,,,,,,,,,,,EVENTOUT, +PortC,PC9,,,TIM3_CH4,,,,,,,,,,,,,EVENTOUT, +PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,,,,,,,EVENTOUT, +PortC,PC11,,,,,,,SPI3_MISO,USART3_RX,UART4_RX,,,,,,,EVENTOUT, +PortC,PC12,,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,,,,EVENTOUT, +PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT, +PortD,PD0,,,,TIM9_CH1,,SPI2_NSS/I2S2_WS,,,,,,,,,,EVENTOUT, +PortD,PD1,,,,,,SPI2_SCK/I2S2_CK,,,,,,,,,,EVENTOUT, +PortD,PD2,,,TIM3_ETR,,,,,,UART5_RX,,,,,,,EVENTOUT, +PortD,PD3,,,,,,SPI2_MISO,,USART2_CTS,,,,,,,,EVENTOUT, +PortD,PD4,,,,,,SPI2_MOSI/I2S2_SD,,USART2_RTS,,,,,,,,EVENTOUT, +PortD,PD5,,,,,,,,USART2_TX,,,,,,,,EVENTOUT, +PortD,PD6,,,,,,,,USART2_RX,,,,,,,,EVENTOUT, +PortD,PD7,,,,TIM9_CH2,,,,USART2_CK,,,,,,,,EVENTOUT, +PortD,PD8,,,,,,,,USART3_TX,,,,,,,,EVENTOUT, +PortD,PD9,,,,,,,,USART3_RX,,,,,,,,EVENTOUT, +PortD,PD10,,,,,,,,USART3_CK,,,,,,,,EVENTOUT, +PortD,PD11,,,,,,,,USART3_CTS,,,,,,,,EVENTOUT, +PortD,PD12,,,TIM4_CH1,,,,,USART3_RTS,,,,,,,,EVENTOUT, +PortD,PD13,,,TIM4_CH2,,,,,,,,,,,,,EVENTOUT, +PortD,PD14,,,TIM4_CH3,,,,,,,,,,,,,EVENTOUT, +PortD,PD15,,,TIM4_CH4,,,,,,,,,,,,,EVENTOUT, +PortE,PE0,,,TIM4_ETR,TIM10_CH1,,,,,,,,,,,,EVENTOUT, +PortE,PE1,,,,TIM11_CH1,,,,,,,,,,,,EVENTOUT, +PortE,PE2,TRACECK,,TIM3_ETR,,,,,,,,,,,,,EVENTOUT, +PortE,PE3,TRACED0,,TIM3_CH1,,,,,,,,,,,,,EVENTOUT, +PortE,PE4,TRACED1,,TIM3_CH2,,,,,,,,,,,,,EVENTOUT, +PortE,PE5,TRACED2,,,TIM9_CH1,,,,,,,,,,,,EVENTOUT, +PortE,PE6,TRACED3,,,TIM9_CH2,,,,,,,,,,,,EVENTOUT, +PortE,PE7,,,,,,,,,,,,,,,,EVENTOUT, +PortE,PE8,,,,,,,,,,,,,,,,EVENTOUT, +PortE,PE9,,TIM2_CH1_ETR,,,,,,,,,,,,,,EVENTOUT, +PortE,PE10,,TIM2_CH2,,,,,,,,,,,,,,EVENTOUT, +PortE,PE11,,TIM2_CH3,,,,,,,,,,,,,,EVENTOUT, +PortE,PE12,,TIM2_CH4,,,,SPI1_NSS,,,,,,,,,,EVENTOUT, +PortE,PE13,,,,,,SPI1_SCK,,,,,,,,,,EVENTOUT, +PortE,PE14,,,,,,SPI1_MISO,,,,,,,,,,EVENTOUT, +PortE,PE15,,,,,,SPI1_MOSI,,,,,,,,,,EVENTOUT, +PortF,PF0,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF1,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF2,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF3,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF4,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF5,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF6,,,TIM5_ETR,,,,,,,,,,,,,EVENTOUT, +PortF,PF7,,,TIM5_CH2,,,,,,,,,,,,,EVENTOUT, +PortF,PF8,,,TIM5_CH3,,,,,,,,,,,,,EVENTOUT, +PortF,PF9,,,TIM5_CH4,,,,,,,,,,,,,EVENTOUT, +PortF,PF10,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF11,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF12,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF13,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF14,,,,,,,,,,,,,,,,EVENTOUT, +PortF,PF15,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG0,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG1,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG2,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG3,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG4,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG5,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG6,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG7,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG8,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG9,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG10,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG11,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG12,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG13,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG14,,,,,,,,,,,,,,,,EVENTOUT, +PortG,PG15,,,,,,,,,,,,,,,,EVENTOUT, +PortH,PH0,,,,,,,,,,,,,,,,, +PortH,PH1,,,,,,,,,,,,,,,,, +PortH,PH2,,,,,,,,,,,,,,,,, diff --git a/ports/stm32/boards/stm32l152xe.ld b/ports/stm32/boards/stm32l152xe.ld new file mode 100644 index 000000000000..32f8444947e2 --- /dev/null +++ b/ports/stm32/boards/stm32l152xe.ld @@ -0,0 +1,37 @@ +/* + GNU linker script for STM32L152xE +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */ + FLASH_FS (rx) : ORIGIN = 0x08064000, LENGTH = 112K /* sectors 100-127 */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 81408 + FS_CACHE (xrw) : ORIGIN = 0x20013e00, LENGTH = 512 +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); + +/* Define the stack. The stack is full descending so begins just above last byte + of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; +_sstack = _estack - 16K; /* tunable */ + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = _sstack; + +/* Filesystem cache in RAM, and storage in flash */ +_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(FS_CACHE); +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(FS_CACHE) + LENGTH(FS_CACHE); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32l1xx_hal_conf_base.h b/ports/stm32/boards/stm32l1xx_hal_conf_base.h new file mode 100644 index 000000000000..b839fd29f0a3 --- /dev/null +++ b/ports/stm32/boards/stm32l1xx_hal_conf_base.h @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_STM32L1XX_HAL_CONF_BASE_H +#define MICROPY_INCLUDED_STM32L1XX_HAL_CONF_BASE_H + +// Include various HAL modules for convenience +#include "stm32l1xx_hal_rcc.h" +#include "stm32l1xx_hal_gpio.h" +#include "stm32l1xx_hal_dma.h" +#include "stm32l1xx_hal_cortex.h" +#include "stm32l1xx_hal_adc.h" +#include "stm32l1xx_hal_comp.h" +#include "stm32l1xx_hal_crc.h" +#include "stm32l1xx_hal_dac.h" +#include "stm32l1xx_hal_flash.h" +#include "stm32l1xx_hal_i2c.h" +#include "stm32l1xx_hal_iwdg.h" +#include "stm32l1xx_hal_pwr.h" +#include "stm32l1xx_hal_rtc.h" +#include "stm32l1xx_hal_spi.h" +#include "stm32l1xx_hal_tim.h" +#include "stm32l1xx_hal_uart.h" +#include "stm32l1xx_hal_usart.h" +#include "stm32l1xx_hal_wwdg.h" +#include "stm32l1xx_hal_exti.h" +#include "stm32l1xx_ll_adc.h" +#include "stm32l1xx_ll_pwr.h" +#include "stm32l1xx_ll_rtc.h" +#include "stm32l1xx_ll_usart.h" + +// Enable various HAL modules +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED + +// Oscillator values in Hz +#define HSE_VALUE (8000000) +#define HSI_VALUE (16000000) +#define HSI48_VALUE (48000000) +#define LSI_VALUE (37000) +#define LSE_VALUE (32768) +#define MSI_VALUE (2097000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +// SysTick has the highest priority +#define TICK_INT_PRIORITY (0x00) + +// Miscellaneous HAL settings +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define PREFETCH_ENABLE 1 +#define USE_SPI_CRC 0 +#define USE_RTOS 0 + +// HAL parameter assertions are disabled +#define assert_param(expr) ((void)0) + +#endif // MICROPY_INCLUDED_STM32L1XX_HAL_CONF_BASE_H diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index 36ef9387f873..feadbe5c5817 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -261,6 +261,8 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp __HAL_RCC_DAC12_CLK_ENABLE(); #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L4) __HAL_RCC_DAC1_CLK_ENABLE(); + #elif defined(STM32L1) + __HAL_RCC_DAC_CLK_ENABLE(); #else #error Unsupported Processor #endif diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 2dc6e8e8b463..29306f1b271c 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -80,7 +80,7 @@ typedef union { struct _dma_descr_t { #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) DMA_Stream_TypeDef *instance; - #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) + #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) DMA_Channel_TypeDef *instance; #else #error "Unsupported Processor" @@ -398,6 +398,57 @@ static const uint8_t dma_irqn[NSTREAM] = { DMA1_Channel4_5_6_7_IRQn, }; +#elif defined(STM32L1) + +#define NCONTROLLERS (2) +#define NSTREAMS_PER_CONTROLLER (7) +#define NSTREAM (NCONTROLLERS * NSTREAMS_PER_CONTROLLER) + +#define DMA_SUB_INSTANCE_AS_UINT8(dma_request) (dma_request) + +#define DMA1_ENABLE_MASK (0x007f) // Bits in dma_enable_mask corresponding to DMA1 +#define DMA2_ENABLE_MASK (0x0f80) // Bits in dma_enable_mask corresponding to DMA2 + +// These descriptors are ordered by DMAx_Channel number, and within a channel by request +// number. The duplicate streams are ok as long as they aren't used at the same time. + +// DMA1 streams +const dma_descr_t dma_SPI_1_RX = { DMA1_Channel2, 2, dma_id_1, &dma_init_struct_spi_i2c }; +#if MICROPY_HW_ENABLE_DAC +const dma_descr_t dma_DAC_1_TX = { DMA1_Channel2, 2, dma_id_1, &dma_init_struct_dac }; +#endif +const dma_descr_t dma_SPI_1_TX = { DMA1_Channel3, 3, dma_id_2, &dma_init_struct_spi_i2c }; +#if MICROPY_HW_ENABLE_DAC +const dma_descr_t dma_DAC_2_TX = { DMA1_Channel3, 3, dma_id_2, &dma_init_struct_dac }; +#endif +const dma_descr_t dma_SPI_2_RX = { DMA1_Channel4, 4, dma_id_3, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_2_TX = { DMA1_Channel4, 4, dma_id_3, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_TX = { DMA1_Channel5, 5, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_2_RX = { DMA1_Channel5, 5, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_1_TX = { DMA1_Channel6, 6, dma_id_5, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_1_RX = { DMA1_Channel7, 7, dma_id_6, &dma_init_struct_spi_i2c }; + +// DMA2 streams +const dma_descr_t dma_SPI_3_RX = { DMA2_Channel1, 3, dma_id_7, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_TX = { DMA2_Channel2, 3, dma_id_8, &dma_init_struct_spi_i2c }; + +static const uint8_t dma_irqn[NSTREAM] = { + DMA1_Channel1_IRQn, + DMA1_Channel2_IRQn, + DMA1_Channel3_IRQn, + DMA1_Channel4_IRQn, + DMA1_Channel5_IRQn, + DMA1_Channel6_IRQn, + DMA1_Channel7_IRQn, + DMA2_Channel1_IRQn, + DMA2_Channel2_IRQn, + DMA2_Channel3_IRQn, + DMA2_Channel4_IRQn, + DMA2_Channel5_IRQn, + 0, + 0 +}; + #elif defined(STM32L4) #define NCONTROLLERS (2) @@ -705,7 +756,7 @@ volatile dma_idle_count_t dma_idle; #define DMA_INVALID_CHANNEL 0xff // Value stored in dma_last_channel which means invalid -#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) +#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32L1) #define DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & RCC_AHBENR_DMA1EN) != 0) #if defined(DMA2) #define DMA2_IS_CLK_ENABLED() ((RCC->AHBENR & RCC_AHBENR_DMA2EN) != 0) @@ -1080,7 +1131,7 @@ void DMA1_Channel4_5_6_7_IRQHandler(void) { IRQ_EXIT(DMA1_Channel4_5_6_7_IRQn); } -#elif defined(STM32L4) || defined(STM32WB) +#elif defined(STM32L1) || defined(STM32L4) || defined(STM32WB) void DMA1_Channel1_IRQHandler(void) { IRQ_ENTER(DMA1_Channel1_IRQn); @@ -1166,6 +1217,7 @@ void DMA2_Channel5_IRQHandler(void) { } IRQ_EXIT(DMA2_Channel5_IRQn); } +#if !defined(STM32L1) void DMA2_Channel6_IRQHandler(void) { IRQ_ENTER(DMA2_Channel6_IRQn); if (dma_handle[dma_id_12] != NULL) { @@ -1180,6 +1232,7 @@ void DMA2_Channel7_IRQHandler(void) { } IRQ_EXIT(DMA2_Channel7_IRQn); } +#endif #endif @@ -1260,7 +1313,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3 #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) dma->Init.Request = dma_descr->sub_instance; #else - #if !defined(STM32F0) + #if !defined(STM32F0) && !defined(STM32L1) dma->Init.Channel = dma_descr->sub_instance; #endif #endif @@ -1284,7 +1337,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir dma_enable_clock(dma_id); - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) // Always reset and configure the H7 and G0/G4/H7/L0/L4/WB/WL DMA peripheral // (dma->State is set to HAL_DMA_STATE_RESET by memset above) // TODO: understand how L0/L4 DMA works so this is not needed @@ -1410,7 +1463,7 @@ static void dma_idle_handler(uint32_t tick) { } #endif -#if defined(STM32F0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) +#if defined(STM32F0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) void dma_nohal_init(const dma_descr_t *descr, uint32_t config) { DMA_Channel_TypeDef *dma = descr->instance; @@ -1436,6 +1489,7 @@ void dma_nohal_init(const dma_descr_t *descr, uint32_t config) { #elif defined(STM32G4) uint32_t *dmamux_ctrl = (void *)(DMAMUX1_Channel0_BASE + 0x04 * descr->id); *dmamux_ctrl = (*dmamux_ctrl & ~(0x7f)) | descr->sub_instance; + #elif defined(STM32L1) #else DMA_Request_TypeDef *dma_ctrl = (void *)(((uint32_t)dma & ~0xff) + (DMA1_CSELR_BASE - DMA1_BASE)); // DMA1_CSELR or DMA2_CSELR uint32_t channel_number = (((uint32_t)dma & 0xff) - 0x08) / 20; // 0 through 6 diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index 70c7e6a00523..37b8710c214c 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -100,6 +100,20 @@ extern const dma_descr_t dma_I2C_2_RX; extern const dma_descr_t dma_I2C_1_TX; extern const dma_descr_t dma_I2C_1_RX; +#elif defined(STM32L1) +extern const dma_descr_t dma_SPI_1_RX; +extern const dma_descr_t dma_SPI_3_TX; +extern const dma_descr_t dma_SPI_1_TX; +extern const dma_descr_t dma_SPI_3_RX; +extern const dma_descr_t dma_DAC_1_TX; +extern const dma_descr_t dma_SPI_2_RX; +extern const dma_descr_t dma_I2C_2_TX; +extern const dma_descr_t dma_DAC_2_TX; +extern const dma_descr_t dma_SPI_2_TX; +extern const dma_descr_t dma_I2C_2_RX; +extern const dma_descr_t dma_I2C_1_TX; +extern const dma_descr_t dma_I2C_1_RX; + #elif defined(STM32L4) || defined(STM32WB) || defined(STM32WL) extern const dma_descr_t dma_ADC_1_RX; diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index ca23261ca736..fd7950de3e95 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -210,7 +210,11 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = { #endif ETH_WKUP_IRQn, OTG_HS_WKUP_IRQn, + #if defined(STM32L1) + TAMPER_STAMP_IRQn, + #else TAMP_STAMP_IRQn, + #endif RTC_WKUP_IRQn, #endif diff --git a/ports/stm32/extint.h b/ports/stm32/extint.h index 95e29c97fdc7..fddcc2ae7a01 100644 --- a/ports/stm32/extint.h +++ b/ports/stm32/extint.h @@ -43,7 +43,7 @@ #endif #define EXTI_ETH_WAKEUP (19) #define EXTI_USB_OTG_HS_WAKEUP (20) -#if defined(STM32F0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WL) +#if defined(STM32F0) || defined(STM32G4) || defined(STM32L1) || defined(STM32L4) || defined(STM32WL) #define EXTI_RTC_TIMESTAMP (19) #define EXTI_RTC_WAKEUP (20) #elif defined(STM32H7) || defined(STM32WB) diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c index de537aba212d..16af49c3cfb8 100644 --- a/ports/stm32/flash.c +++ b/ports/stm32/flash.c @@ -117,6 +117,12 @@ static const flash_layout_t flash_layout[] = { { (uint32_t)FLASH_BASE, (uint32_t)FLASH_PAGE_SIZE, 512 }, }; +#elif defined(STM32L1) + +static const flash_layout_t flash_layout[] = { + { (uint32_t)FLASH_BASE, 0x200, 1024 }, +}; + #elif defined(STM32H7) static const flash_layout_t flash_layout[] = { @@ -264,7 +270,7 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) { EraseInitStruct.Page = get_page(flash_dest); EraseInitStruct.Banks = get_bank(flash_dest); EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE; - #elif defined(STM32L0) + #elif defined(STM32L0) || defined(STM32L1) __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR); EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = flash_dest; @@ -286,6 +292,8 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) { #if defined(STM32H7) __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2); + #elif defined(STM32L1) + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR); #else __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index 000b478f86b0..1a478cd1cffb 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -42,7 +42,7 @@ #define ADCx_COMMON __LL_ADC_COMMON_INSTANCE(0) #endif -#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL) +#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32L1) || defined(STM32WL) #define ADC_STAB_DELAY_US (1) #define ADC_TEMPSENSOR_DELAY_US (10) #elif defined(STM32G4) @@ -68,6 +68,9 @@ #elif defined(STM32G0) || defined(STM32L0) || defined(STM32WL) #define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_12CYCLES_5 #define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_160CYCLES_5 +#elif defined(STM32L1) +#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_384CYCLES +#define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_384CYCLES #elif defined(STM32L4) || defined(STM32WB) #define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_12CYCLES_5 #define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_247CYCLES_5 @@ -239,7 +242,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { STATIC int adc_get_bits(ADC_TypeDef *adc) { #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL) uint32_t res = (adc->CFGR1 & ADC_CFGR1_RES) >> ADC_CFGR1_RES_Pos; - #elif defined(STM32F4) || defined(STM32F7) + #elif defined(STM32F4) || defined(STM32F7) || defined(STM32L1) uint32_t res = (adc->CR1 & ADC_CR1_RES) >> ADC_CR1_RES_Pos; #elif defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) uint32_t res = (adc->CFGR & ADC_CFGR_RES) >> ADC_CFGR_RES_Pos; diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index acedac7a599a..e1796d1cf025 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -138,7 +138,7 @@ void machine_init(void) { if (state & RCC_SR_IWDGRSTF || state & RCC_SR_WWDGRSTF) { reset_cause = PYB_RESET_WDT; } else if (state & RCC_SR_PORRSTF - #if !defined(STM32F0) && !defined(STM32F412Zx) + #if !defined(STM32F0) && !defined(STM32F412Zx) && !defined(STM32L1) || state & RCC_SR_BORRSTF #endif ) { @@ -309,7 +309,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { return mp_obj_new_tuple(MP_ARRAY_SIZE(tuple), tuple); } else { // set - #if defined(STM32F0) || defined(STM32L0) || defined(STM32L4) || defined(STM32G0) + #if defined(STM32F0) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32G0) mp_raise_NotImplementedError(MP_ERROR_TEXT("machine.freq set not supported yet")); #else mp_int_t sysclk = mp_obj_get_int(args[0]); diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 51bad18dd53e..b538f7823548 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -370,6 +370,16 @@ #define MICROPY_HW_MAX_UART (5) #define MICROPY_HW_MAX_LPUART (1) +// Configuration for STM32L1 series +#elif defined(STM32L1) +#define MP_HAL_UNIQUE_ID_ADDRESS (UID_BASE) +#define PYB_EXTI_NUM_VECTORS (23) +#define MICROPY_HW_MAX_I2C (2) +// TODO: L1 has 9 timers but tim0 and tim1 don't exist. +#define MICROPY_HW_MAX_TIMER (11) +#define MICROPY_HW_MAX_UART (5) +#define MICROPY_HW_MAX_LPUART (0) + // Configuration for STM32L4 series #elif defined(STM32L4) diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c index 619bde69bf06..092d63e1bb19 100644 --- a/ports/stm32/mphalport.c +++ b/ports/stm32/mphalport.c @@ -87,7 +87,7 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) { // This logic assumes that all the GPIOx_EN bits are adjacent and ordered in one register - #if defined(STM32F0) + #if defined(STM32F0) || defined(STM32L1) #define AHBxENR AHBENR #define AHBxENR_GPIOAEN_Pos RCC_AHBENR_GPIOAEN_Pos #elif defined(STM32F4) || defined(STM32F7) diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index 358d9cd25d0d..5c587c016d04 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -17,6 +17,8 @@ #define MICROPY_PLATFORM_VERSION "HAL1.6.0" #elif defined(STM32L0) #define MICROPY_PLATFORM_VERSION "HAL1.11.2" +#elif defined(STM32L1) +#define MICROPY_PLATFORM_VERSION "HAL1.10.3" #elif defined(STM32L4) #define MICROPY_PLATFORM_VERSION "HAL1.17.0" #elif defined(STM32WB) diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index f3f1837ece65..c0a0595e5d31 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -143,7 +143,7 @@ void powerctrl_check_enter_bootloader(void) { if (BL_STATE_GET_KEY(bl_state) == BL_STATE_KEY && (RCC->RCC_SR & RCC_SR_SFTRSTF)) { // Reset by NVIC_SystemReset with bootloader data set -> branch to bootloader RCC->RCC_SR = RCC_SR_RMVF; - #if defined(STM32F0) || defined(STM32F4) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) + #if defined(STM32F0) || defined(STM32F4) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32WB) __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); #endif branch_to_bootloader(BL_STATE_GET_REG(bl_state), BL_STATE_GET_ADDR(bl_state)); @@ -286,7 +286,7 @@ int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk #endif -#if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32L0) && !defined(STM32L4) +#if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32L0) && !defined(STM32L1) && !defined(STM32L4) STATIC uint32_t calc_ahb_div(uint32_t wanted_div) { #if defined(STM32H7) @@ -708,7 +708,7 @@ void powerctrl_enter_stop_mode(void) { __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI); #endif - #if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB) && !defined(STM32WL) + #if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L1) && !defined(STM32L4) && !defined(STM32WB) && !defined(STM32WL) // takes longer to wake but reduces stop current HAL_PWREx_EnableFlashPowerDown(); #endif diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c index 555457c582e2..61d48ffe5c95 100644 --- a/ports/stm32/powerctrlboot.c +++ b/ports/stm32/powerctrlboot.c @@ -228,6 +228,74 @@ void SystemClock_Config(void) { #endif } +#elif defined(STM32L1) + +void SystemClock_Config(void) { + // Enable power control peripheral + __HAL_RCC_PWR_CLK_ENABLE(); + + // Set power voltage scaling + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + // Enable the FLASH 64-bit access + FLASH->ACR = FLASH_ACR_ACC64; + // Set flash latency to 1 because SYSCLK > 16MHz + FLASH->ACR |= MICROPY_HW_FLASH_LATENCY; + + #if MICROPY_HW_CLK_USE_HSI + // Enable the 16MHz internal oscillator + RCC->CR |= RCC_CR_HSION; + while (!(RCC->CR & RCC_CR_HSIRDY)) { + } + RCC->CFGR = RCC_CFGR_PLLSRC_HSI; + #else + // Enable the 8MHz external oscillator + RCC->CR |= RCC_CR_HSEBYP; + RCC->CR |= RCC_CR_HSEON; + while (!(RCC->CR & RCC_CR_HSERDY)) { + } + RCC->CFGR = RCC_CFGR_PLLSRC_HSE; + #endif + // Use HSI16 and the PLL to get a 32MHz SYSCLK + RCC->CFGR |= MICROPY_HW_CLK_PLLMUL | MICROPY_HW_CLK_PLLDIV; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) { + // Wait for PLL to lock + } + RCC->CFGR |= RCC_CFGR_SW_PLL; + + while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL) { + // Wait for SYSCLK source to change + } + + SystemCoreClockUpdate(); + powerctrl_config_systick(); + + #if MICROPY_HW_ENABLE_USB + // Enable the 48MHz internal oscillator + RCC->CRRCR |= RCC_CRRCR_HSI48ON; + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + SYSCFG->CFGR3 |= SYSCFG_CFGR3_ENREF_HSI48; + while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) { + // Wait for HSI48 to be ready + } + + // Select RC48 as HSI48 for USB and RNG + RCC->CCIPR |= RCC_CCIPR_HSI48SEL; + + // Synchronise HSI48 with 1kHz USB SoF + __HAL_RCC_CRS_CLK_ENABLE(); + CRS->CR = 0x20 << CRS_CR_TRIM_Pos; + CRS->CFGR = 2 << CRS_CFGR_SYNCSRC_Pos | 0x22 << CRS_CFGR_FELIM_Pos + | __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000) << CRS_CFGR_RELOAD_Pos; + #endif + + // Disable the Debug Module in low-power mode due to prevent + // unexpected HardFault after __WFI(). + #if !defined(NDEBUG) + DBGMCU->CR &= ~(DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY); + #endif +} #elif defined(STM32WB) #include "stm32wbxx_ll_hsem.h" diff --git a/ports/stm32/resethandler_m3.s b/ports/stm32/resethandler_m3.s new file mode 100644 index 000000000000..05a44306e1eb --- /dev/null +++ b/ports/stm32/resethandler_m3.s @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + .syntax unified + .cpu cortex-m3 + .fpu softvfp + .thumb + + .section .text.Reset_Handler + .global Reset_Handler + .type Reset_Handler, %function + +Reset_Handler: + /* Save the first argument to pass through to stm32_main */ + mov r4, r0 + + /* Load the stack pointer */ + ldr r0, =_estack + mov sp, r0 + + /* Initialise the data section */ + ldr r1, =_sidata + ldr r2, =_sdata + ldr r3, =_edata + b .data_copy_entry +.data_copy_loop: + ldr r0, [r1] + adds r1, #4 + str r0, [r2] + adds r2, #4 +.data_copy_entry: + cmp r2, r3 + bcc .data_copy_loop + + /* Zero out the BSS section */ + movs r0, #0 + ldr r1, =_sbss + ldr r2, =_ebss + b .bss_zero_entry +.bss_zero_loop: + str r0, [r1] + adds r1, #4 +.bss_zero_entry: + cmp r1, r2 + bcc .bss_zero_loop + + /* Initialise the system and jump to the main code */ + bl SystemInit + mov r0, r4 + bl stm32_main + + .size Reset_Handler, .-Reset_Handler diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c index aacfc3805e97..874e427cffa0 100644 --- a/ports/stm32/rtc.c +++ b/ports/stm32/rtc.c @@ -91,6 +91,15 @@ STATIC bool rtc_need_init_finalise = false; #define RCC_BDCR_LSEON RCC_CSR_LSEON #define RCC_BDCR_LSERDY RCC_CSR_LSERDY #define RCC_BDCR_LSEBYP RCC_CSR_LSEBYP +#elif defined(STM32L1) +#define BDCR CR +#define RCC_BDCR_RTCEN RCC_CSR_RTCEN +#define RCC_BDCR_RTCSEL RCC_CSR_RTCSEL +#define RCC_BDCR_RTCSEL_0 RCC_CSR_RTCSEL_0 +#define RCC_BDCR_RTCSEL_1 RCC_CSR_RTCSEL_1 +#define RCC_BDCR_LSEON RCC_CSR_LSEON +#define RCC_BDCR_LSERDY RCC_CSR_LSERDY +#define RCC_BDCR_LSEBYP RCC_CSR_LSEBYP #endif void rtc_init_start(bool force_init) { @@ -664,7 +673,15 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) { wucksel -= 1; } if (div <= 16) { + #if defined(STM32L1) + if (rtc_use_lse) { + wut = LSE_VALUE / div * ms / 1000; + } else { + wut = LSI_VALUE / div * ms / 1000; + } + #else wut = 32768 / div * ms / 1000; + #endif } else { // use 1Hz clock wucksel = 4; diff --git a/ports/stm32/stm32.mk b/ports/stm32/stm32.mk index c55b243fe573..b4f73a67f381 100644 --- a/ports/stm32/stm32.mk +++ b/ports/stm32/stm32.mk @@ -48,7 +48,7 @@ CFLAGS_CORTEX_M += -mfpu=fpv5-d16 -mfloat-abi=hard SUPPORTS_HARDWARE_FP_SINGLE = 1 SUPPORTS_HARDWARE_FP_DOUBLE = 1 else -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 g0 l0 wl)) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 g0 l0 l1 wl)) CFLAGS_CORTEX_M += -msoft-float else CFLAGS_CORTEX_M += -mfpu=fpv4-sp-d16 -mfloat-abi=hard @@ -64,6 +64,7 @@ CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7 CFLAGS_MCU_g0 = $(CFLAGS_CORTEX_M) -mtune=cortex-m0plus -mcpu=cortex-m0plus CFLAGS_MCU_g4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 CFLAGS_MCU_l0 = $(CFLAGS_CORTEX_M) -mtune=cortex-m0plus -mcpu=cortex-m0plus +CFLAGS_MCU_l1 = $(CFLAGS_CORTEX_M) -mtune=cortex-m3 -mcpu=cortex-m3 CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 CFLAGS_MCU_h7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7 CFLAGS_MCU_wb = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 2f89f67deb53..c2604992186f 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -520,11 +520,19 @@ void ETH_WKUP_IRQHandler(void) { } #endif +#if defined(STM32L1) +void TAMPER_STAMP_IRQHandler(void) { + IRQ_ENTER(TAMPER_STAMP_IRQn); + Handle_EXTI_Irq(EXTI_RTC_TIMESTAMP); + IRQ_EXIT(TAMPER_STAMP_IRQn); +} +#else void TAMP_STAMP_IRQHandler(void) { IRQ_ENTER(TAMP_STAMP_IRQn); Handle_EXTI_Irq(EXTI_RTC_TIMESTAMP); IRQ_EXIT(TAMP_STAMP_IRQn); } +#endif void RTC_WKUP_IRQHandler(void) { IRQ_ENTER(RTC_WKUP_IRQn); @@ -698,6 +706,12 @@ void TIM6_DAC_LPTIM1_IRQHandler(void) { timer_irq_handler(6); IRQ_EXIT(TIM6_DAC_LPTIM1_IRQn); } +#elif defined(STM32L1) +void TIM6_IRQHandler(void) { + IRQ_ENTER(TIM6_IRQn); + timer_irq_handler(6); + IRQ_EXIT(TIM6_IRQn); +} #else void TIM6_DAC_IRQHandler(void) { IRQ_ENTER(TIM6_DAC_IRQn); @@ -764,6 +778,26 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void) { } #endif +#if defined(STM32L1) +void TIM9_IRQHandler(void) { + IRQ_ENTER(TIM9_IRQn); + timer_irq_handler(9); + IRQ_EXIT(TIM9_IRQn); +} + +void TIM10_IRQHandler(void) { + IRQ_ENTER(TIM9_IRQn); + timer_irq_handler(10); + IRQ_EXIT(TIM9_IRQn); +} + +void TIM11_IRQHandler(void) { + IRQ_ENTER(TIM9_IRQn); + timer_irq_handler(11); + IRQ_EXIT(TIM9_IRQn); +} +#endif + #if defined(STM32G0) void TIM14_IRQHandler(void) { IRQ_ENTER(TIM14_IRQn); diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index 7a6ccd4dfd2d..8816c218f5e3 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -431,7 +431,7 @@ STATIC mp_obj_t compute_percent_from_pwm_value(uint32_t period, uint32_t cmp) { #endif } -#if !defined(STM32L0) +#if !defined(STM32L0) && !defined(STM32L1) // Computes the 8-bit value for the DTG field in the BDTR register. // @@ -522,7 +522,7 @@ STATIC void pyb_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ self->tim.Init.ClockDivision == TIM_CLOCKDIVISION_DIV4 ? 4 : self->tim.Init.ClockDivision == TIM_CLOCKDIVISION_DIV2 ? 2 : 1); - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) #if defined(IS_TIM_ADVANCED_INSTANCE) if (IS_TIM_ADVANCED_INSTANCE(self->tim.Instance)) #elif defined(IS_TIM_BREAK_INSTANCE) @@ -640,7 +640,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons args[ARG_div].u_int == 4 ? TIM_CLOCKDIVISION_DIV4 : TIM_CLOCKDIVISION_DIV1; - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) init->RepetitionCounter = 0; #endif @@ -772,7 +772,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons // init TIM HAL_TIM_Base_Init(&self->tim); - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) #if defined(IS_TIM_ADVANCED_INSTANCE) if (IS_TIM_ADVANCED_INSTANCE(self->tim.Instance)) #elif defined(IS_TIM_BREAK_INSTANCE) @@ -833,7 +833,7 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = { TIM_ENTRY(5, TIM5_IRQn), #endif #if defined(TIM6) - #if defined(STM32F412Zx) + #if defined(STM32F412Zx) || defined(STM32L1) TIM_ENTRY(6, TIM6_IRQn), #elif defined(STM32G0) TIM_ENTRY(6, TIM6_DAC_LPTIM1_IRQn), @@ -858,14 +858,26 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = { #endif #endif #if defined(TIM9) + #if defined(STM32L1) + TIM_ENTRY(9, TIM9_IRQn), + #else TIM_ENTRY(9, TIM1_BRK_TIM9_IRQn), #endif + #endif #if defined(TIM10) + #if defined(STM32L1) + TIM_ENTRY(10, TIM10_IRQn), + #else TIM_ENTRY(10, TIM1_UP_TIM10_IRQn), #endif + #endif #if defined(TIM11) + #if defined(STM32L1) + TIM_ENTRY(11, TIM11_IRQn), + #else TIM_ENTRY(11, TIM1_TRG_COM_TIM11_IRQn), #endif + #endif #if defined(TIM12) TIM_ENTRY(12, TIM8_BRK_TIM12_IRQn), #endif @@ -936,7 +948,11 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, siz memset(tim, 0, sizeof(*tim)); tim->base.type = &pyb_timer_type; tim->tim_id = tim_id; + #if defined(STM32L1) + tim->is_32bit = tim_id == 5; + #else tim->is_32bit = tim_id == 2 || tim_id == 5; + #endif tim->callback = mp_const_none; uint32_t ti = tim_instance_table[tim_id - 1]; tim->tim.Instance = (TIM_TypeDef *)(ti & 0xffffff00); @@ -1168,7 +1184,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma } oc_config.OCPolarity = TIM_OCPOLARITY_HIGH; oc_config.OCFastMode = TIM_OCFAST_DISABLE; - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH; oc_config.OCIdleState = TIM_OCIDLESTATE_SET; oc_config.OCNIdleState = TIM_OCNIDLESTATE_SET; @@ -1180,7 +1196,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma } else { pyb_timer_channel_callback(MP_OBJ_FROM_PTR(chan), chan->callback); } - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) // Start the complimentary channel too (if its supported) if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) { HAL_TIMEx_PWMN_Start(&self->tim, TIMER_CHANNEL(chan)); @@ -1203,7 +1219,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma oc_config.OCPolarity = TIM_OCPOLARITY_HIGH; } oc_config.OCFastMode = TIM_OCFAST_DISABLE; - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) if (oc_config.OCPolarity == TIM_OCPOLARITY_HIGH) { oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH; } else { @@ -1222,7 +1238,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma } else { pyb_timer_channel_callback(MP_OBJ_FROM_PTR(chan), chan->callback); } - #if !defined(STM32L0) + #if !defined(STM32L0) && !defined(STM32L1) // Start the complimentary channel too (if its supported) if (IS_TIM_CCXN_INSTANCE(self->tim.Instance, TIMER_CHANNEL(chan))) { HAL_TIMEx_OCN_Start(&self->tim, TIMER_CHANNEL(chan)); diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index cea49f4ba1c9..6d1240cf8d5a 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -38,7 +38,7 @@ #include "irq.h" #include "pendsv.h" -#if defined(STM32F4) +#if defined(STM32F4) || defined(STM32L1) #define UART_RXNE_IS_SET(uart) ((uart)->SR & USART_SR_RXNE) #else #if defined(STM32G0) || defined(STM32H7) || defined(STM32WL) @@ -101,6 +101,11 @@ #define USART_CR2_IE_ALL (USART_CR2_IE_BASE) #define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_WUFIE) +#elif defined(STM32L1) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE) + #elif defined(STM32L4) || defined(STM32WB) || defined(STM32WL) #define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) #define USART_CR2_IE_ALL (USART_CR2_IE_BASE) @@ -580,7 +585,7 @@ bool uart_init(pyb_uart_obj_t *uart_obj, huart.FifoMode = UART_FIFOMODE_ENABLE; #endif - #if !defined(STM32F4) + #if !defined(STM32F4) && !defined(STM32L1) huart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; #endif @@ -1016,7 +1021,7 @@ STATIC bool uart_wait_flag_set(pyb_uart_obj_t *self, uint32_t flag, uint32_t tim // an interrupt and the flag can be set quickly if the baudrate is large. uint32_t start = HAL_GetTick(); for (;;) { - #if defined(STM32F4) + #if defined(STM32F4) || defined(STM32L1) if (self->uartx->SR & flag) { return true; } @@ -1071,7 +1076,7 @@ size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_chars, } else { data = *src++; } - #if defined(STM32F4) + #if defined(STM32F4) || defined(STM32L1) uart->DR = data; #else uart->TDR = data; @@ -1109,7 +1114,7 @@ void uart_irq_handler(mp_uint_t uart_id) { } // Capture IRQ status flags. - #if defined(STM32F4) + #if defined(STM32F4) || defined(STM32L1) self->mp_irq_flags = self->uartx->SR; bool rxne_is_set = self->mp_irq_flags & USART_SR_RXNE; bool did_clear_sr = false; @@ -1153,7 +1158,7 @@ void uart_irq_handler(mp_uint_t uart_id) { } // Clear other interrupt flags that can trigger this IRQ handler. - #if defined(STM32F4) + #if defined(STM32F4) || defined(STM32L1) if (did_clear_sr) { // SR was cleared above. Re-enable IDLE if it should be enabled. if (self->mp_irq_trigger & UART_FLAG_IDLE) { diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h index ec8a27591c1e..61d1ac439790 100644 --- a/ports/stm32/uart.h +++ b/ports/stm32/uart.h @@ -103,7 +103,7 @@ size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_chars, void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len); static inline bool uart_tx_avail(pyb_uart_obj_t *self) { - #if defined(STM32F4) + #if defined(STM32F4) || defined(STM32L1) return self->uartx->SR & USART_SR_TXE; #elif defined(STM32G0) || defined(STM32H7) || defined(STM32WL) return self->uartx->ISR & USART_ISR_TXE_TXFNF; From e6d351318746495bf88d2c4bd7cbd81e94a2290e Mon Sep 17 00:00:00 2001 From: yn386 Date: Mon, 19 Sep 2022 17:57:27 +0900 Subject: [PATCH 1772/4290] stm32/boards/NUCLEO_L152RE: Add NUCLEO-L152RE board support. This change adds NUCLEO-L152RE support to the STM32 port. NUCLEO-L152RE: https://www.st.com/en/evaluation-tools/nucleo-l152re.html This board use STM32L152RE: https://www.st.com/en/microcontrollers-microprocessors/stm32l152re.html --- ports/stm32/boards/NUCLEO_L152RE/board.json | 15 ++++ ports/stm32/boards/NUCLEO_L152RE/deploy.md | 31 ++++++++ .../boards/NUCLEO_L152RE/mpconfigboard.h | 74 ++++++++++++++++++ .../boards/NUCLEO_L152RE/mpconfigboard.mk | 4 + ports/stm32/boards/NUCLEO_L152RE/pins.csv | 76 +++++++++++++++++++ .../boards/NUCLEO_L152RE/stm32l1xx_hal_conf.h | 10 +++ 6 files changed, 210 insertions(+) create mode 100644 ports/stm32/boards/NUCLEO_L152RE/board.json create mode 100644 ports/stm32/boards/NUCLEO_L152RE/deploy.md create mode 100644 ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h create mode 100644 ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.mk create mode 100644 ports/stm32/boards/NUCLEO_L152RE/pins.csv create mode 100644 ports/stm32/boards/NUCLEO_L152RE/stm32l1xx_hal_conf.h diff --git a/ports/stm32/boards/NUCLEO_L152RE/board.json b/ports/stm32/boards/NUCLEO_L152RE/board.json new file mode 100644 index 000000000000..7b3427693755 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L152RE/board.json @@ -0,0 +1,15 @@ +{ + "deploy": [ + "./deploy.md" + ], + "docs": "", + "features": [], + "images": [ + "nucleo_l152re.jpg" + ], + "mcu": "stm32l1", + "product": "Nucleo L152RE", + "thumbnail": "", + "url": "", + "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_L152RE/deploy.md b/ports/stm32/boards/NUCLEO_L152RE/deploy.md new file mode 100644 index 000000000000..0323981d2d66 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L152RE/deploy.md @@ -0,0 +1,31 @@ +### STM32 via ST-Link + +Nucleo and Discovery boards typically include a built-in ST-Link programmer. + +A `.bin` or `.hex` file can be flashed using [st-flash](https://github.com/stlink-org/stlink). + +```bash +# Optional erase to clear existing filesystem. +st-flash erase + +# Flash .bin +st-flash write firmware.bin 0x08000000 +# or, flash .hex +st-flash --format ihex write firmware.hex +``` + +A `.hex` file can be flashed using [STM32 Cube Programmer](https://www.st.com/en/development-tools/stm32cubeprog.html). + +```bash +STM32_Programmer.sh -c port=SWD mode=UR dLPM -d firmware.hex -v -hardRst +``` + +### STM32 via DFU + +Boards with USB support can also be programmed via the ST DFU bootloader, using e.g. [dfu-util](http://dfu-util.sourceforge.net/) or [pydfu.py](https://github.com/micropython/micropython/blob/master/tools/pydfu.py). + +To enter the bootloader the `BOOT0` pin can be connected to `VCC` during reset, or you can use `machine.bootloader()` from the MicroPython REPL. + +```bash +dfu-util --alt 0 -D firmware.dfu +``` diff --git a/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h new file mode 100644 index 000000000000..3609955893fe --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h @@ -0,0 +1,74 @@ +#define MICROPY_HW_BOARD_NAME "NUCLEO-L152RE" +#define MICROPY_HW_MCU_NAME "STM32L152xE" + +#define MICROPY_HW_HAS_SWITCH (1) +#define MICROPY_HW_ENABLE_RTC (1) +// This board has an external 32kHz crystal +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_DAC (1) + +// HSE is 8MHz, HSI is 16MHz CPU freq set to 32MHz +// Default source for the clock is HSI. +// For revisions of the board greater than C-01, HSE can be used as a +// clock source by removing the #define MICROPY_HW_CLK_USE_HSE line +#define MICROPY_HW_CLK_USE_HSI (1) + +#if MICROPY_HW_CLK_USE_HSI +#define MICROPY_HW_CLK_PLLMUL (RCC_CFGR_PLLMUL6) +#define MICROPY_HW_CLK_PLLDIV (RCC_CFGR_PLLDIV3) +#else +#define MICROPY_HW_CLK_PLLMUL (RCC_CFGR_PLLMUL12) +#define MICROPY_HW_CLK_PLLDIV (RCC_CFGR_PLLDIV3) +#endif + +// UART config +#define MICROPY_HW_UART1_TX (pin_A9) +#define MICROPY_HW_UART1_RX (pin_A10) +#define MICROPY_HW_UART2_TX (pin_A2) +#define MICROPY_HW_UART2_RX (pin_A3) +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) +#define MICROPY_HW_UART4_TX (pin_C10) +#define MICROPY_HW_UART4_RX (pin_C11) +#define MICROPY_HW_UART5_TX (pin_C12) +#define MICROPY_HW_UART5_RX (pin_D2) +// UART 2 connects to the STM32F103 (STLINK) on the Nucleo board +// and this is exposed as a USB Serial port. +#define MICROPY_HW_UART_REPL PYB_UART_2 +#define MICROPY_HW_UART_REPL_BAUD 115200 + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 +#define MICROPY_HW_I2C1_SDA (pin_B9) // D14, pin 5 on CN10 +#define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 +#define MICROPY_HW_I2C2_SDA (pin_B11) // Arduino D3, pin 31 on CN10 + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 +#define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 +#define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 +#define MICROPY_HW_SPI1_MOSI (pin_A7) // Arduino D11, pin 15 on CN10 + +#define MICROPY_HW_SPI2_NSS (pin_B12) // pin 16 on CN10 +#define MICROPY_HW_SPI2_SCK (pin_B13) // pin 30 on CN10 +#define MICROPY_HW_SPI2_MISO (pin_B14) // pin 28 on CN10 +#define MICROPY_HW_SPI2_MOSI (pin_B15) // pin 26 on CN10 + +#define MICROPY_HW_SPI3_NSS (pin_A4) // Arduino A2, pin 32 on CN7 +#define MICROPY_HW_SPI3_SCK (pin_C10) // Arduino D3, pin 31 on CN10 +#define MICROPY_HW_SPI3_MISO (pin_C11) // Arduino D5, pin 27 on CN10 +#define MICROPY_HW_SPI3_MOSI (pin_C12) // Arduino D4, pin 29 on CN10 + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN (pin_C13) +#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define MICROPY_HW_USRSW_PRESSED (0) + +// LEDs +#define MICROPY_HW_LED1 (pin_A5) // Green LD2 LED on Nucleo +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) + +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1 diff --git a/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.mk new file mode 100644 index 000000000000..a62a775ac8dd --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.mk @@ -0,0 +1,4 @@ +MCU_SERIES = l1 +CMSIS_MCU = STM32L152xE +AF_FILE = boards/stm32l152_af.csv +LD_FILES = boards/stm32l152xe.ld boards/common_basic.ld diff --git a/ports/stm32/boards/NUCLEO_L152RE/pins.csv b/ports/stm32/boards/NUCLEO_L152RE/pins.csv new file mode 100644 index 000000000000..035d933f5dd4 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L152RE/pins.csv @@ -0,0 +1,76 @@ +D0,PA3 +D1,PA2 +D2,PA10 +D3,PB3 +D4,PB5 +D5,PB4 +D6,PB10 +D7,PA8 +D8,PA9 +D9,PC7 +D10,PB6 +D11,PA7 +D12,PA6 +D13,PA5 +D14,PB9 +D15,PB8 +A0,PA0 +A1,PA1 +A2,PA4 +A3,PB0 +A4,PC1 +A5,PC0 +PA0,PA0 +PA1,PA1 +PA2,PA2 +PA3,PA3 +PA4,PA4 +PA5,PA5 +PA6,PA6 +PA7,PA7 +PA8,PA8 +PA9,PA9 +PA10,PA10 +PA11,PA11 +PA12,PA12 +PA15,PA15 +PB0,PB0 +PB1,PB1 +PB2,PB2 +PB3,PB3 +PB4,PB4 +PB5,PB5 +PB6,PB6 +PB7,PB7 +PB8,PB8 +PB9,PB9 +PB10,PB10 +PB11,PB11 +PB12,PB12 +PB13,PB13 +PB14,PB14 +PB15,PB15 +PC0,PC0 +PC1,PC1 +PC2,PC2 +PC3,PC3 +PC4,PC4 +PC5,PC5 +PC6,PC6 +PC7,PC7 +PC8,PC8 +PC9,PC9 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PC13,PC13 +PC14,PC14 +PC15,PC15 +PD2,PD2 +PH0,PH0 +PH1,PH1 +LED_GREEN,PA5 +LED_ORANGE,PA5 +LED_RED,PA5 +LED_BLUE,PA4 +SW,PC13 diff --git a/ports/stm32/boards/NUCLEO_L152RE/stm32l1xx_hal_conf.h b/ports/stm32/boards/NUCLEO_L152RE/stm32l1xx_hal_conf.h new file mode 100644 index 000000000000..7ee8204cbf06 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_L152RE/stm32l1xx_hal_conf.h @@ -0,0 +1,10 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32L1XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32L1XX_HAL_CONF_H + +#include "boards/stm32l1xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32L1XX_HAL_CONF_H From 3abcfb9aecd567c4c74fd3c99703f23c372b7445 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 26 Sep 2022 00:07:58 +1000 Subject: [PATCH 1773/4290] esp32/modsocket: Use mp_obj_is_integer to test port type. Because the value may be a big integer, which is still a valid type to use. Fixes issue #9410. Signed-off-by: Damien George --- ports/esp32/modsocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/modsocket.c b/ports/esp32/modsocket.c index 334c5bae33c4..9812eb347689 100644 --- a/ports/esp32/modsocket.c +++ b/ports/esp32/modsocket.c @@ -214,7 +214,7 @@ static int _socket_getaddrinfo2(const mp_obj_t host, const mp_obj_t portx, struc }; mp_obj_t port = portx; - if (mp_obj_is_small_int(port)) { + if (mp_obj_is_integer(port)) { // This is perverse, because lwip_getaddrinfo promptly converts it back to an int, but // that's the API we have to work with ... port = mp_obj_str_binary_op(MP_BINARY_OP_MODULO, mp_obj_new_str_via_qstr("%s", 2), port); From dd9dcb594c577cb818c336db59a884fd329c3840 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 25 Sep 2022 22:12:29 +1000 Subject: [PATCH 1774/4290] esp32/machine_pwm: Don't use LEDC_USE_REF_TICK on ESP32-C3 variants. Because it's not supported by this particular MCU (since IDF v4.4.2). Signed-off-by: Damien George --- ports/esp32/machine_pwm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index 0107187a8c98..2a456c71c783 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -97,8 +97,10 @@ STATIC ledc_timer_config_t timers[PWM_TIMER_MAX]; // How much to shift from the HIGHEST_PWM_RES duty resolution to the user interface duty resolution UI_RES_16_BIT #define UI_RES_SHIFT (UI_RES_16_BIT - HIGHEST_PWM_RES) // 0 for ESP32, 2 for S2, S3, C3 +#if SOC_LEDC_SUPPORT_REF_TICK // If the PWM frequency is less than EMPIRIC_FREQ, then LEDC_REF_CLK_HZ(1 MHz) source is used, else LEDC_APB_CLK_HZ(80 MHz) source is used #define EMPIRIC_FREQ (10) // Hz +#endif // Config of timer upon which we run all PWM'ed GPIO pins STATIC bool pwm_inited = false; @@ -208,9 +210,11 @@ STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf if (freq != timer->freq_hz) { // Find the highest bit resolution for the requested frequency unsigned int i = LEDC_APB_CLK_HZ; // 80 MHz + #if SOC_LEDC_SUPPORT_REF_TICK if (freq < EMPIRIC_FREQ) { i = LEDC_REF_CLK_HZ; // 1 MHz } + #endif #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) // original code @@ -243,9 +247,11 @@ STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf timer->duty_resolution = res; timer->freq_hz = freq; timer->clk_cfg = LEDC_USE_APB_CLK; + #if SOC_LEDC_SUPPORT_REF_TICK if (freq < EMPIRIC_FREQ) { timer->clk_cfg = LEDC_USE_REF_TICK; } + #endif // Set frequency esp_err_t err = ledc_timer_config(timer); From 9d6f474ea49fd89b7a1a90b830e6014ef70a89b7 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sun, 25 Sep 2022 22:15:45 +1000 Subject: [PATCH 1775/4290] py/objstr: Don't treat bytes as unicode in str.count. `b'\xaa \xaa'.count(b'\xaa')` now (correctly) returns 2 instead of 1. Fixes issue #9404. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- py/objstr.c | 4 +++- tests/basics/bytes_count.py | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/py/objstr.c b/py/objstr.c index 62d7bfb4cc39..55e737fffc4f 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -1768,6 +1768,8 @@ STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(utf8_charlen(start, end - start) + 1); } + bool is_str = self_type == &mp_type_str; + // count the occurrences mp_int_t num_occurrences = 0; for (const byte *haystack_ptr = start; haystack_ptr + needle_len <= end;) { @@ -1775,7 +1777,7 @@ STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { num_occurrences++; haystack_ptr += needle_len; } else { - haystack_ptr = utf8_next_char(haystack_ptr); + haystack_ptr = is_str ? utf8_next_char(haystack_ptr) : haystack_ptr + 1; } } diff --git a/tests/basics/bytes_count.py b/tests/basics/bytes_count.py index 5fa0730f5cff..e71f09db00e2 100644 --- a/tests/basics/bytes_count.py +++ b/tests/basics/bytes_count.py @@ -48,6 +48,13 @@ print(b"aaaa".count(b'a', -1, 5)) print(b"abbabba".count(b"abba")) +print(b'\xaa \xaa'.count(b'\xaa')) +print(b'\xaa \xaa \xaa \xaa'.count(b'\xaa')) +print(b'\xaa \xaa \xaa \xaa'.count(b'\xaa'), 1) +print(b'\xaa \xaa \xaa \xaa'.count(b'\xaa'), 2) +print(b'\xaa \xaa \xaa \xaa'.count(b'\xaa'), 1, 3) +print(b'\xaa \xaa \xaa \xaa'.count(b'\xaa'), 2, 3) + def t(): return True From 0bc1d1055748dd41a2db10a4c6cab32499c488f9 Mon Sep 17 00:00:00 2001 From: Matt Trentini Date: Sun, 11 Sep 2022 11:40:59 +1000 Subject: [PATCH 1776/4290] rp2/Makefile: Add support for BOARD_VARIANTS. Following stm32. This allows a single board definition to define variants of its configuration. --- ports/rp2/Makefile | 9 +++++++++ py/mkrules.cmake | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/ports/rp2/Makefile b/ports/rp2/Makefile index c603f5403fca..7057021bfccb 100644 --- a/ports/rp2/Makefile +++ b/ports/rp2/Makefile @@ -22,6 +22,10 @@ ifeq ($(DEBUG),1) CMAKE_ARGS += -DCMAKE_BUILD_TYPE=Debug endif +ifdef BOARD_VARIANT +CMAKE_ARGS += -DBOARD_VARIANT=${BOARD_VARIANT} +endif + HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" all: @@ -38,3 +42,8 @@ submodules: GIT_SUBMODULES=$$(cmake -B $(BUILD)/submodules -DECHO_SUBMODULES=1 ${CMAKE_ARGS} -S . 2>&1 | \ grep '^GIT_SUBMODULES=' | cut -d= -f2); \ $(MAKE) -f ../../py/mkrules.mk GIT_SUBMODULES="$${GIT_SUBMODULES}" submodules + +query-variants: + @BOARD_VARIANTS=$$(cmake -B $(BUILD)/variants -DECHO_BOARD_VARIANTS=1 ${CMAKE_ARGS} -S . 2>&1 | \ + grep '^BOARD_VARIANTS=' | cut -d= -f2); \ + echo "VARIANTS: $${BOARD_VARIANTS}" diff --git a/py/mkrules.cmake b/py/mkrules.cmake index e7c4101ddb72..b29986585a79 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -223,3 +223,9 @@ if(ECHO_SUBMODULES) execute_process(COMMAND ${CMAKE_COMMAND} -E echo "GIT_SUBMODULES=${GIT_SUBMODULES}") message(FATAL_ERROR "Done") endif() + +# Display BOARD_VARIANTS +if(ECHO_BOARD_VARIANTS) + execute_process(COMMAND ${CMAKE_COMMAND} -E echo "BOARD_VARIANTS=${BOARD_VARIANTS}") + message(FATAL_ERROR "Done") +endif() From bdbc44474f92db19a40b5f710a140a0bf70fb0ec Mon Sep 17 00:00:00 2001 From: Matt Trentini Date: Thu, 7 Apr 2022 23:33:36 +1000 Subject: [PATCH 1777/4290] rp2/boards/WEACTSTUDIO: Add WEACTSTUDIO with multiple variants. This supports 2, 4, 8 and 16MB flash variants. --- ports/rp2/boards/WEACTSTUDIO/README.md | 34 ++++++++++ ports/rp2/boards/WEACTSTUDIO/board.json | 23 +++++++ ports/rp2/boards/WEACTSTUDIO/deploy.md | 8 +++ ports/rp2/boards/WEACTSTUDIO/manifest.py | 2 + ports/rp2/boards/WEACTSTUDIO/modules/board.py | 4 ++ .../boards/WEACTSTUDIO/mpconfigboard.cmake | 26 ++++++++ ports/rp2/boards/WEACTSTUDIO/mpconfigboard.h | 4 ++ .../rp2/boards/WEACTSTUDIO/weactstudio_16mb.h | 18 ++++++ .../rp2/boards/WEACTSTUDIO/weactstudio_2mb.h | 18 ++++++ .../rp2/boards/WEACTSTUDIO/weactstudio_4mb.h | 18 ++++++ .../rp2/boards/WEACTSTUDIO/weactstudio_8mb.h | 18 ++++++ .../boards/WEACTSTUDIO/weactstudio_common.h | 62 +++++++++++++++++++ 12 files changed, 235 insertions(+) create mode 100644 ports/rp2/boards/WEACTSTUDIO/README.md create mode 100644 ports/rp2/boards/WEACTSTUDIO/board.json create mode 100644 ports/rp2/boards/WEACTSTUDIO/deploy.md create mode 100644 ports/rp2/boards/WEACTSTUDIO/manifest.py create mode 100644 ports/rp2/boards/WEACTSTUDIO/modules/board.py create mode 100644 ports/rp2/boards/WEACTSTUDIO/mpconfigboard.cmake create mode 100644 ports/rp2/boards/WEACTSTUDIO/mpconfigboard.h create mode 100644 ports/rp2/boards/WEACTSTUDIO/weactstudio_16mb.h create mode 100644 ports/rp2/boards/WEACTSTUDIO/weactstudio_2mb.h create mode 100644 ports/rp2/boards/WEACTSTUDIO/weactstudio_4mb.h create mode 100644 ports/rp2/boards/WEACTSTUDIO/weactstudio_8mb.h create mode 100644 ports/rp2/boards/WEACTSTUDIO/weactstudio_common.h diff --git a/ports/rp2/boards/WEACTSTUDIO/README.md b/ports/rp2/boards/WEACTSTUDIO/README.md new file mode 100644 index 000000000000..ae0acfd2c7b0 --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/README.md @@ -0,0 +1,34 @@ +# WeAct Studio RP2040 + +The WeAct Studio RP2040 Board is based on the Raspberry Pi RP2040 and can be +purchased with 2/4/8/16 MiB of flash. + +These boards are available from a number of resellers and often have the name +"Pico Board RP2040". WeAct maintain the [WeActStudio.RP2040CoreBoard](https://github.com/WeActTC/WeActStudio.RP2040CoreBoard/tree/master) +repository containing information on the board. + +## Build notes + +Builds can be configured with the `BOARD_VARIANT` parameter. Valid variants +can be displayed with the `query-variant` target. An example: + +```bash +> cd ports/rp2 +> make BOARD=WEACTSTUDIO query-variants +VARIANTS: flash_2mb flash_4mb flash_8mb flash_16mb +> make BOARD=WEACTSTUDIO BOARD_VARIANT=flash_8mb submodules all # Build the 8 MiB variant +``` + +`flash_16mb` is the default if `BOARD_VARIANT` is not supplied. + +## Board-specific modules + +The `board` module contains definitions for the onboard LED and user button. + +Example: + +```python +> import board +> board.led.toggle() # Toggles the state of the on-board LED +> board.key.value() # Returns 0 or 1 corresponding to the state of the user key +``` diff --git a/ports/rp2/boards/WEACTSTUDIO/board.json b/ports/rp2/boards/WEACTSTUDIO/board.json new file mode 100644 index 000000000000..bac5263627ba --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/board.json @@ -0,0 +1,23 @@ +{ + "deploy": [ + "deploy.md" + ], + "docs": "", + "features": [ + "Breadboard Friendly", + "SPI Flash", + "USB-C" + ], + "images": [ + "weact_rp2040.jpg" + ], + "mcu": "rp2040", + "product": "WeAct Studio RP2040", + "url": "https://github.com/WeActTC/WeActStudio.RP2040CoreBoard", + "variants": { + "flash_2mb": "2 MiB Flash", + "flash_4mb": "4 MiB Flash", + "flash_8mb": "8 MiB Flash" + }, + "vendor": "WeAct" +} diff --git a/ports/rp2/boards/WEACTSTUDIO/deploy.md b/ports/rp2/boards/WEACTSTUDIO/deploy.md new file mode 100644 index 000000000000..b4db7675ebb5 --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/deploy.md @@ -0,0 +1,8 @@ +### Flashing via UF2 bootloader + +To get the board in bootloader mode ready for the firmware update, execute +`machine.bootloader()` at the MicroPython REPL. Alternatively, hold +down the BOOTSEL button while pressing reset (NRST). The uf2 file below +should then be copied to the USB mass storage device that appears. Once +programming of the new firmware is complete the device will automatically reset +and be ready for use. diff --git a/ports/rp2/boards/WEACTSTUDIO/manifest.py b/ports/rp2/boards/WEACTSTUDIO/manifest.py new file mode 100644 index 000000000000..f993d4fa6bd2 --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/manifest.py @@ -0,0 +1,2 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("./modules") diff --git a/ports/rp2/boards/WEACTSTUDIO/modules/board.py b/ports/rp2/boards/WEACTSTUDIO/modules/board.py new file mode 100644 index 000000000000..dd3b31b805fd --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/modules/board.py @@ -0,0 +1,4 @@ +from machine import Pin + +led = Pin(25, Pin.OUT, value=0) +key = Pin(23, Pin.IN, Pin.PULL_UP) diff --git a/ports/rp2/boards/WEACTSTUDIO/mpconfigboard.cmake b/ports/rp2/boards/WEACTSTUDIO/mpconfigboard.cmake new file mode 100644 index 000000000000..5fd3eec897b3 --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/mpconfigboard.cmake @@ -0,0 +1,26 @@ +# CMake file for WeAct Studio RP2040 boards + +# The WeAct Studio boards don't have official pico-sdk support so we define it +# See also: https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards +list(APPEND PICO_BOARD_HEADER_DIRS ${MICROPY_BOARD_DIR}) + +# Freeze board.py +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) + +# Provide different variants for the downloads page +set(BOARD_VARIANTS "flash_2mb flash_4mb flash_8mb flash_16mb") + +# Select the 16MB variant as the default +set(PICO_BOARD "weactstudio_16mb") + +if("${BOARD_VARIANT}" STREQUAL "flash_2mb") + set(PICO_BOARD "weactstudio_2mb") +endif() + +if("${BOARD_VARIANT}" STREQUAL "flash_4mb") +set(PICO_BOARD "weactstudio_4mb") +endif() + +if("${BOARD_VARIANT}" STREQUAL "flash_8mb") +set(PICO_BOARD "weactstudio_8mb") +endif() diff --git a/ports/rp2/boards/WEACTSTUDIO/mpconfigboard.h b/ports/rp2/boards/WEACTSTUDIO/mpconfigboard.h new file mode 100644 index 000000000000..3c72ef4fca0b --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/mpconfigboard.h @@ -0,0 +1,4 @@ +#define MICROPY_HW_BOARD_NAME "WeAct Studio RP2040" + +// Allow 1MB for the firmware image itself, allocate the remainder to the filesystem +#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (1 * 1024 * 1024)) diff --git a/ports/rp2/boards/WEACTSTUDIO/weactstudio_16mb.h b/ports/rp2/boards/WEACTSTUDIO/weactstudio_16mb.h new file mode 100644 index 000000000000..b6208c68972c --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/weactstudio_16mb.h @@ -0,0 +1,18 @@ +// A pico-sdk board definition is required since the WeAct Studio boards are +// not officially supported. +// +// Officially supported boards: +// https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards + +#ifndef _BOARDS_WEACTSTUDIO_16MB_H +#define _BOARDS_WEACTSTUDIO_16MB_H + +#include "weactstudio_common.h" + +#define WEACTSTUDIO_16MB + +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +#endif diff --git a/ports/rp2/boards/WEACTSTUDIO/weactstudio_2mb.h b/ports/rp2/boards/WEACTSTUDIO/weactstudio_2mb.h new file mode 100644 index 000000000000..e6a21ea3bc3f --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/weactstudio_2mb.h @@ -0,0 +1,18 @@ +// A pico-sdk board definition is required since the WeAct Studio boards are +// not officially supported. +// +// Officially supported boards: +// https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards + +#ifndef _BOARDS_WEACTSTUDIO_2MB_H +#define _BOARDS_WEACTSTUDIO_2MB_H + +#include "weactstudio_common.h" + +#define WEACTSTUDIO_2MB + +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) +#endif + +#endif diff --git a/ports/rp2/boards/WEACTSTUDIO/weactstudio_4mb.h b/ports/rp2/boards/WEACTSTUDIO/weactstudio_4mb.h new file mode 100644 index 000000000000..7a2836ab4a3f --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/weactstudio_4mb.h @@ -0,0 +1,18 @@ +// A pico-sdk board definition is required since the WeAct Studio boards are +// not officially supported. +// +// Officially supported boards: +// https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards + +#ifndef _BOARDS_WEACTSTUDIO_4MB_H +#define _BOARDS_WEACTSTUDIO_4MB_H + +#include "weactstudio_common.h" + +#define WEACTSTUDIO_4MB + +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) +#endif + +#endif diff --git a/ports/rp2/boards/WEACTSTUDIO/weactstudio_8mb.h b/ports/rp2/boards/WEACTSTUDIO/weactstudio_8mb.h new file mode 100644 index 000000000000..82baf6688e83 --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/weactstudio_8mb.h @@ -0,0 +1,18 @@ +// A pico-sdk board definition is required since the WeAct Studio boards are +// not officially supported. +// +// Officially supported boards: +// https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards + +#ifndef _BOARDS_WEACTSTUDIO_8MB_H +#define _BOARDS_WEACTSTUDIO_8MB_H + +#include "weactstudio_common.h" + +#define WEACTSTUDIO_8MB + +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) +#endif + +#endif diff --git a/ports/rp2/boards/WEACTSTUDIO/weactstudio_common.h b/ports/rp2/boards/WEACTSTUDIO/weactstudio_common.h new file mode 100644 index 000000000000..f1c690360133 --- /dev/null +++ b/ports/rp2/boards/WEACTSTUDIO/weactstudio_common.h @@ -0,0 +1,62 @@ +// Common configuration to all WeAct Studio boards (only flash size differs) + +#ifndef _BOARDS_WEACTSTUDIO_COMMON_H +#define _BOARDS_WEACTSTUDIO_COMMON_H + +// --- UART --- +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 0 +#endif +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + +// --- I2C --- +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 4 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 5 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 0 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 18 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 19 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 16 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 17 +#endif + +// --- FLASH --- +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +// All boards have B1 RP2040 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif From 71050870b81a8dbf3c3fac93bd2d86f0ff9a37d2 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 28 Sep 2022 01:04:05 +1000 Subject: [PATCH 1778/4290] mpy-cross/mpy_cross: Fix default path to mpy-cross binary. Needed to be updated to use build/mpy-cross. Also fixes some other issues in the Python wrapper: - Rename find_mpy_cross_binary to _find_mpy_cross_binary - Fix passing of -march arg. - Decode stdout from subprocess. - Print stdout from mpy-cross in __main__.py. Signed-off-by: Jim Mussared --- mpy-cross/mpy_cross/__init__.py | 12 +++++++----- mpy-cross/mpy_cross/__main__.py | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/mpy-cross/mpy_cross/__init__.py b/mpy-cross/mpy_cross/__init__.py index d4c0930bb919..235271d2ce17 100644 --- a/mpy-cross/mpy_cross/__init__.py +++ b/mpy-cross/mpy_cross/__init__.py @@ -62,9 +62,11 @@ class CrossCompileError(Exception): def find_mpy_cross_binary(mpy_cross): + +def _find_mpy_cross_binary(mpy_cross): if mpy_cross: return mpy_cross - return os.path.abspath(os.path.join(os.path.dirname(__file__), "../mpy-cross")) + return os.path.abspath(os.path.join(os.path.dirname(__file__), "../build/mpy-cross")) def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, extra_args=None): @@ -82,7 +84,7 @@ def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, args += ["-o", dest] if march: - args += ["-march", march] + args += ["-march=" + march] if opt is not None: args += ["-O{}".format(opt)] @@ -96,7 +98,7 @@ def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, def run(args, mpy_cross=None): - mpy_cross = find_mpy_cross_binary(mpy_cross) + mpy_cross = _find_mpy_cross_binary(mpy_cross) if not os.path.exists(mpy_cross): raise CrossCompileError("mpy-cross binary not found at {}.".format(mpy_cross)) @@ -108,6 +110,6 @@ def run(args, mpy_cross=None): pass try: - subprocess.check_output([mpy_cross] + args, stderr=subprocess.STDOUT) + return subprocess.check_output([mpy_cross] + args, stderr=subprocess.STDOUT).decode() except subprocess.CalledProcessError as er: - raise CrossCompileError(er.output) + raise CrossCompileError(er.output.decode()) diff --git a/mpy-cross/mpy_cross/__main__.py b/mpy-cross/mpy_cross/__main__.py index 9d957bca025d..2b6b81c33336 100644 --- a/mpy-cross/mpy_cross/__main__.py +++ b/mpy-cross/mpy_cross/__main__.py @@ -32,7 +32,7 @@ from . import run, CrossCompileError try: - run(sys.argv[1:]) + print(run(sys.argv[1:])) except CrossCompileError as er: print(er.args[0], file=sys.stderr) raise SystemExit(1) From ee1b4a2026e79b662142f0d985643dadf7fff87b Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 28 Sep 2022 01:05:09 +1000 Subject: [PATCH 1779/4290] mpy-cross/mpy_cross: Add a way to query the mpy version. This returns the mpy version and sub-version for files compiled with this mpy-cross binary. Signed-off-by: Jim Mussared --- mpy-cross/mpy_cross/__init__.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mpy-cross/mpy_cross/__init__.py b/mpy-cross/mpy_cross/__init__.py index 235271d2ce17..01fe550a93ce 100644 --- a/mpy-cross/mpy_cross/__init__.py +++ b/mpy-cross/mpy_cross/__init__.py @@ -27,6 +27,7 @@ from __future__ import print_function import os +import re import stat import subprocess @@ -54,14 +55,15 @@ NATIVE_ARCH_XTENSAWIN, ] -__all__ = ["compile", "run", "CrossCompileError"] +__all__ = ["version", "compile", "run", "CrossCompileError"] class CrossCompileError(Exception): pass -def find_mpy_cross_binary(mpy_cross): +_VERSION_RE = re.compile("mpy-cross emitting mpy v([0-9]+)(?:.([0-9]+))?") + def _find_mpy_cross_binary(mpy_cross): if mpy_cross: @@ -69,6 +71,16 @@ def _find_mpy_cross_binary(mpy_cross): return os.path.abspath(os.path.join(os.path.dirname(__file__), "../build/mpy-cross")) +def mpy_version(mpy_cross=None): + version_info = run(["--version"], mpy_cross=mpy_cross) + match = re.search(_VERSION_RE, version_info) + mpy_version, mpy_sub_version = int(match.group(1)), int(match.group(2) or "0") + return ( + mpy_version, + mpy_sub_version, + ) + + def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, extra_args=None): if not src: raise ValueError("src is required") From 370a87dd12b92722ba8fac5f3562384d31a864ce Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 28 Sep 2022 11:33:24 +1000 Subject: [PATCH 1780/4290] mpy-cross/mpy_cross: Add list of architectures to `__all__`. Signed-off-by: Jim Mussared --- mpy-cross/mpy_cross/__init__.py | 42 +++++++++++++-------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/mpy-cross/mpy_cross/__init__.py b/mpy-cross/mpy_cross/__init__.py index 01fe550a93ce..22d175c89cf3 100644 --- a/mpy-cross/mpy_cross/__init__.py +++ b/mpy-cross/mpy_cross/__init__.py @@ -31,31 +31,23 @@ import stat import subprocess -NATIVE_ARCH_X86 = "x86" -NATIVE_ARCH_X64 = "x64" -NATIVE_ARCH_ARMV6 = "armv6" -NATIVE_ARCH_ARMV6M = "armv6m" -NATIVE_ARCH_ARMV7M = "armv7m" -NATIVE_ARCH_ARMV7EM = "armv7em" -NATIVE_ARCH_ARMV7EMSP = "armv7emsp" -NATIVE_ARCH_ARMV7EMDP = "armv7emdp" -NATIVE_ARCH_XTENSA = "xtensa" -NATIVE_ARCH_XTENSAWIN = "xtensawin" - -NATIVE_ARCHS = [ - NATIVE_ARCH_X86, - NATIVE_ARCH_X64, - NATIVE_ARCH_ARMV6, - NATIVE_ARCH_ARMV6M, - NATIVE_ARCH_ARMV7M, - NATIVE_ARCH_ARMV7EM, - NATIVE_ARCH_ARMV7EMSP, - NATIVE_ARCH_ARMV7EMDP, - NATIVE_ARCH_XTENSA, - NATIVE_ARCH_XTENSAWIN, -] - -__all__ = ["version", "compile", "run", "CrossCompileError"] +NATIVE_ARCHS = { + "NATIVE_ARCH_NONE": "", + "NATIVE_ARCH_X86": "x86", + "NATIVE_ARCH_X64": "x64", + "NATIVE_ARCH_ARMV6": "armv6", + "NATIVE_ARCH_ARMV6M": "armv6m", + "NATIVE_ARCH_ARMV7M": "armv7m", + "NATIVE_ARCH_ARMV7EM": "armv7em", + "NATIVE_ARCH_ARMV7EMSP": "armv7emsp", + "NATIVE_ARCH_ARMV7EMDP": "armv7emdp", + "NATIVE_ARCH_XTENSA": "xtensa", + "NATIVE_ARCH_XTENSAWIN": "xtensawin", +} + +globals().update(NATIVE_ARCHS) + +__all__ = ["version", "compile", "run", "CrossCompileError"] + list(NATIVE_ARCHS.keys()) class CrossCompileError(Exception): From e4d90be680b0a8933daf1bad03a1fa2632e0136e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 28 Sep 2022 11:46:45 +1000 Subject: [PATCH 1781/4290] mpy-cross/mpy_cross: Add docstrings to public methods. --- mpy-cross/mpy_cross/__init__.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/mpy-cross/mpy_cross/__init__.py b/mpy-cross/mpy_cross/__init__.py index 22d175c89cf3..8eadbc8352c7 100644 --- a/mpy-cross/mpy_cross/__init__.py +++ b/mpy-cross/mpy_cross/__init__.py @@ -64,6 +64,13 @@ def _find_mpy_cross_binary(mpy_cross): def mpy_version(mpy_cross=None): + """ + Get the version and sub-version of the .mpy file format generated by this version of mpy-cross. + + Returns: A tuple of `(mpy_version, mpy_sub_version)` + Optional keyword arguments: + - mpy_cross: Specific mpy-cross binary to use + """ version_info = run(["--version"], mpy_cross=mpy_cross) match = re.search(_VERSION_RE, version_info) mpy_version, mpy_sub_version = int(match.group(1)), int(match.group(2) or "0") @@ -74,6 +81,22 @@ def mpy_version(mpy_cross=None): def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, extra_args=None): + """ + Compile the specified .py file with mpy-cross. + + Returns: Standard output from mpy-cross as a string. + + Required arguments: + - src: The path to the .py file + + Optional keyword arguments: + - dest: The output .mpy file. Defaults to `src` (with .mpy extension) + - src_path: The path to embed in the .mpy file (defaults to `src`) + - opt: Optimisation level (0-3, default 0) + - march: One of the `NATIVE_ARCH_*` constants (defaults to NATIVE_ARCH_NONE) + - mpy_cross: Specific mpy-cross binary to use + - extra_args: Additional arguments to pass to mpy-cross (e.g. `["-X", "emit=native"]`) + """ if not src: raise ValueError("src is required") if not os.path.exists(src): @@ -102,6 +125,15 @@ def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, def run(args, mpy_cross=None): + """ + Run mpy-cross with the specified command line arguments. + Prefer to use `compile()` instead. + + Returns: Standard output from mpy-cross as a string. + + Optional keyword arguments: + - mpy_cross: Specific mpy-cross binary to use + """ mpy_cross = _find_mpy_cross_binary(mpy_cross) if not os.path.exists(mpy_cross): From fecfbc3f678c8f2f6c450abf840bbefca48a57d0 Mon Sep 17 00:00:00 2001 From: stijn Date: Thu, 29 Sep 2022 14:17:37 +0200 Subject: [PATCH 1782/4290] py/mkenv.mk: Make CPP definition explicit for consistency. --- py/mkenv.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/py/mkenv.mk b/py/mkenv.mk index ea2e34f3b64d..5368279e2908 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -45,6 +45,7 @@ PYTHON = python3 AS = $(CROSS_COMPILE)as CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E CXX = $(CROSS_COMPILE)g++ GDB = $(CROSS_COMPILE)gdb LD = $(CROSS_COMPILE)ld From b76ddcbc83b7235ab373e764ae033c1e5cecddd1 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 29 Sep 2022 22:31:35 +1000 Subject: [PATCH 1783/4290] docs/Makefile: Enable parallel compilation for Sphinx. This has a fairly dramatic (nearly 3x on a 6-core machine) speedup for docs compilation, with no impact on correctness. Signed-off-by: Jim Mussared --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 05709617c35b..766a669a500d 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,7 +3,7 @@ # You can set these variables from the command line. PYTHON = python3 -SPHINXOPTS = -W --keep-going +SPHINXOPTS = -W --keep-going -j auto SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build/$(MICROPY_PORT) From 65ab0ec91cffe5d39ff2e253ac5cc898ecc3c5ce Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 29 Sep 2022 23:13:52 +1000 Subject: [PATCH 1784/4290] tools/manifestfile.py: Add `author` kwarg to metadata(). This allows future micropython-lib packages to specify an author. Signed-off-by: Jim Mussared --- tools/manifestfile.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/manifestfile.py b/tools/manifestfile.py index a4d056137ffc..f7966ccb8045 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -87,14 +87,17 @@ def __init__(self): self.version = None self.description = None self.license = None + self.author = None - def update(self, description=None, version=None, license=None): + def update(self, description=None, version=None, license=None, author=None): if description: self.description = description if version: self.version = version if license: self.license = version + if author: + self.author = author # Turns a dict of options into a object with attributes used to turn the @@ -228,7 +231,7 @@ def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=F if base_path: os.chdir(prev_cwd) - def metadata(self, description=None, version=None, license=None): + def metadata(self, description=None, version=None, license=None, author=None): """ From within a manifest file, use this to set the metadata for the package described by current manifest. @@ -237,7 +240,7 @@ def metadata(self, description=None, version=None, license=None): to obtain the metadata for the top-level manifest file. """ - self._metadata[-1].update(description, version, license) + self._metadata[-1].update(description, version, license, author) return self._metadata[-1] def include(self, manifest_path, top_level=False, **kwargs): From ba3652f15d96d9dca0f84522639ea2005b07fcb4 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 30 Sep 2022 00:46:16 +1000 Subject: [PATCH 1785/4290] lib/micropython-lib: Update submodule to latest. This brings in the `mip` tool for installing packages. Signed-off-by: Jim Mussared --- lib/micropython-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/micropython-lib b/lib/micropython-lib index 58f8bec54d5b..d0f97fc218f0 160000 --- a/lib/micropython-lib +++ b/lib/micropython-lib @@ -1 +1 @@ -Subproject commit 58f8bec54d5b3b959247b73a6e8f28e8493bd30b +Subproject commit d0f97fc218f07c381c835d9f632904c1ae1c9d6b From 924a3e03ec167c4417d89b531794c75ce5a631a3 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 29 Sep 2022 17:49:58 +1000 Subject: [PATCH 1786/4290] top: Replace upip with mip everywhere. Updates all README.md and docs, and manifests to `require("mip")`. Also extend and improve the documentation on freezing and packaging. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- docs/develop/gettingstarted.rst | 3 +- docs/develop/optimizations.rst | 2 + docs/esp8266/tutorial/intro.rst | 2 +- docs/pyboard/tutorial/lcd160cr_skin.rst | 2 +- docs/reference/glossary.rst | 30 +- docs/reference/manifest.rst | 271 ++++++++++---- docs/reference/packages.rst | 463 ++++++++---------------- examples/hwapi/README.md | 2 +- ports/esp32/boards/manifest.py | 3 +- ports/esp8266/README.md | 18 +- ports/esp8266/boards/manifest.py | 7 +- ports/rp2/boards/PICO_W/manifest.py | 4 +- ports/unix/README.md | 26 +- ports/unix/variants/manifest.py | 3 +- tools/upip.py | 351 ------------------ tools/upip_utarfile.py | 95 ----- 16 files changed, 404 insertions(+), 878 deletions(-) delete mode 100644 tools/upip.py delete mode 100644 tools/upip_utarfile.py diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst index 000b7d61390c..c2d3816d425a 100644 --- a/docs/develop/gettingstarted.rst +++ b/docs/develop/gettingstarted.rst @@ -322,7 +322,8 @@ tests tools - Contains helper tools including the ``upip`` and the ``pyboard.py`` module. + Contains scripts used by the build and CI process, as well as user tools such + as ``pyboard.py`` and ``mpremote``. examples diff --git a/docs/develop/optimizations.rst b/docs/develop/optimizations.rst index d972cde66616..7f2c8cbe7282 100644 --- a/docs/develop/optimizations.rst +++ b/docs/develop/optimizations.rst @@ -25,6 +25,8 @@ into the firmware image as part of the main firmware compilation process, which the bytecode will be executed from ROM. This can lead to a significant memory saving, and reduce heap fragmentation. +See :ref:`manifest` for more information. + Variables --------- diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst index ac46e68b5a5c..75739bd6f96f 100644 --- a/docs/esp8266/tutorial/intro.rst +++ b/docs/esp8266/tutorial/intro.rst @@ -23,7 +23,7 @@ convertor to make the UART available to your PC. The minimum requirement for flash size is 1Mbyte. There is also a special build for boards with 512KB, but it is highly limited comparing to the normal build: there is no support for filesystem, and thus features which -depend on it won't work (WebREPL, upip, etc.). As such, 512KB build will +depend on it won't work (WebREPL, mip, etc.). As such, 512KB build will be more interesting for users who build from source and fine-tune parameters for their particular application. diff --git a/docs/pyboard/tutorial/lcd160cr_skin.rst b/docs/pyboard/tutorial/lcd160cr_skin.rst index fa0debcb1ce3..a0fe88a2e692 100644 --- a/docs/pyboard/tutorial/lcd160cr_skin.rst +++ b/docs/pyboard/tutorial/lcd160cr_skin.rst @@ -42,7 +42,7 @@ There is a test program which you can use to test the features of the display, and which also serves as a basis to start creating your own code that uses the LCD. This test program is available on GitHub `here `__. -Copy it to the board over USB mass storage, or by using `mpremote`. +Copy it to the board over USB mass storage, or by using :ref:`mpremote`. To run the test from the MicroPython prompt do:: diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index da951189e204..4c66f70319ba 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -52,7 +52,7 @@ Glossary cross-compiler Also known as ``mpy-cross``. This tool runs on your PC and converts a :term:`.py file` containing MicroPython code into a :term:`.mpy file` - containing MicroPython bytecode. This means it loads faster (the board + containing MicroPython :term:`bytecode`. This means it loads faster (the board doesn't have to compile the code), and uses less space on flash (the bytecode is more space efficient). @@ -128,7 +128,7 @@ Glossary Unlike the :term:`CPython` stdlib, micropython-lib modules are intended to be installed individually - either using manual copying or - using :term:`upip`. + using :term:`mip`. MicroPython port MicroPython supports different :term:`boards `, RTOSes, and @@ -151,16 +151,26 @@ Glossary machine-independent features. It can also function in a similar way to :term:`CPython`'s ``python`` executable. + mip + A package installer for MicroPython (mip - "mip installs packages"). It + installs MicroPython packages either from :term:`micropython-lib`, + GitHub, or arbitrary URLs. mip can be used on-device on + network-capable boards, and internally by tools such + as :term:`mpremote`. + + mpremote + A tool for interacting with a MicroPython device. See :ref:`mpremote`. + .mpy file The output of the :term:`cross-compiler`. A compiled form of a - :term:`.py file` that contains MicroPython bytecode instead of Python - source code. + :term:`.py file` that contains MicroPython :term:`bytecode` instead of + Python source code. native Usually refers to "native code", i.e. machine code for the target microcontroller (such as ARM Thumb, Xtensa, x86/x64). The ``@native`` decorator can be applied to a MicroPython function to generate native - code instead of bytecode for that function, which will likely be + code instead of :term:`bytecode` for that function, which will likely be faster but use more RAM. port @@ -193,8 +203,10 @@ Glossary as a serial port over USB. upip - (Literally, "micro pip"). A package manager for MicroPython, inspired + A now-obsolete package manager for MicroPython, inspired by :term:`CPython`'s pip, but much smaller and with reduced - functionality. - upip runs both on the :term:`Unix port ` and on - :term:`baremetal` ports which offer filesystem and networking support. + functionality. See its replacement, :term:`mip`. + + webrepl + A way of connecting to the REPL (and transferring files) on a device + over the internet from a browser. See https://micropython.org/webrepl diff --git a/docs/reference/manifest.rst b/docs/reference/manifest.rst index b756de47ed03..9bcafd5839ca 100644 --- a/docs/reference/manifest.rst +++ b/docs/reference/manifest.rst @@ -1,35 +1,177 @@ +.. _manifest: + MicroPython manifest files ========================== -When building firmware for a device the following components are included in -the compilation process: +Summary +------- + +MicroPython has a feature that allows Python code to be "frozen" into the +firmware, as an alternative to loading code from the filesystem. + +This has the following benefits: + +- the code is pre-compiled to bytecode, avoiding the need for the Python + source to be compiled at load-time. +- the bytecode can be executed directly from ROM (i.e. flash memory) rather than + being copied into RAM. Similarly any constant objects (strings, tuples, etc) + are loaded from ROM also. This can lead to significantly more memory being + available for your application. +- on devices that do not have a filesystem, this is the only way to + load Python code. + +During development, freezing is generally not recommended as it will +significantly slow down your development cycle, as each update will require +re-flashing the entire firmware. However, it can still be useful to +selectively freeze some rarely-changing dependencies (such as third-party +libraries). + +The way to list the Python files to be be frozen into the firmware is via +a "manifest", which is a Python file that will be interpreted by the build +process. Typically you would write a manifest file as part of a board +definition, but you can also write a stand-alone manifest file and use it with +an existing board definition. + +Manifest files can define dependencies on libraries from :term:`micropython-lib` +as well as Python files on the filesystem, and also on other manifest files. + +Writing manifest files +---------------------- + +A manifest file is a Python file containing a series of function calls. See the +available functions defined below. + +Any paths used in manifest files can include the following variables. These all +resolve to absolute paths. + +- ``$(MPY_DIR)`` -- path to the micropython repo. +- ``$(MPY_LIB_DIR)`` -- path to the micropython-lib submodule. Prefer to use + ``require()``. +- ``$(PORT_DIR)`` -- path to the current port (e.g. ``ports/stm32``) +- ``$(BOARD_DIR)`` -- path to the current board + (e.g. ``ports/stm32/boards/PYBV11``) + +Custom manifest files should not live in the main MicroPython repository. You +should keep them in version control with the rest of your project. + +Typically a manifest used for compiling firmware will need to include the port +manifest, which might include frozen modules that are required for the board to +function. If you just want to add additional modules to an existing board, then +include the board manifest (which will in turn include the port manifest). + +Building with a custom manifest +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Your manifest can be specified on the ``make`` command line with: + +.. code-block:: bash + + $ make BOARD=MYBOARD FROZEN_MANIFEST=/path/to/my/project/manifest.py + +This applies to all ports, including CMake-based ones (e.g. esp32, rp2), as the +Makefile wrapper that will pass this into the CMake build. + +Adding a manifest to a board definition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you have a custom board definition, you can make it include your custom +manifest automatically. On make-based ports (most ports), in your +``mpconfigboard.mk`` set the ``FROZEN_MANIFEST`` variable. + +.. code-block:: makefile + + FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py + +On CMake-based ports (e.g. esp32, rp2), instead use ``mpconfigboard.cmake`` + +.. code-block:: cmake + + set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) + +High-level functions +~~~~~~~~~~~~~~~~~~~~ + +Note: The ``opt`` keyword argument can be set on the various functions, this controls +the optimisation level used by the cross-compiler. +See :func:`micropython.opt_level`. + +.. function:: package(package_path, files=None, base_path=".", opt=None) + + This is equivalent to copying the "package_path" directory to the device + (except as frozen code). + + In the simplest case, to freeze a package "foo" in the current directory: + + .. code-block:: python3 + + package("foo") + + will recursively include all .py files in foo, and will be frozen as + ``foo/**/*.py``. + + If the package isn't in the same directory as the manifest file, use ``base_path``: + + .. code-block:: python3 + + package("foo", base_path="path/to/libraries") + + You can use the variables above, such as ``$(PORT_DIR)`` in ``base_path``. + + To restrict to certain files in the package use ``files`` (note: paths + should be relative to the package): ``package("foo", files=["bar/baz.py"])``. + +.. function:: module(module_path, base_path=".", opt=None) + + Include a single Python file as a module. + + If the file is in the current directory: + + .. code-block:: python3 + + module("foo.py") + + Otherwise use base_path to locate the file: + + .. code-block:: python3 + + module("foo.py", base_path="src/drivers") + + You can use the variables above, such as ``$(PORT_DIR)`` in ``base_path``. + +.. function:: require(name, unix_ffi=False) + + Require a package by name (and its dependencies) from :term:`micropython-lib`. + + Optionally specify unix_ffi=True to use a module from the unix-ffi directory. + +.. function:: include(manifest_path) -- the core MicroPython virtual machine and runtime -- port-specific system code and drivers to interface with the - microcontroller/device that the firmware is targeting -- standard built-in modules, like ``sys`` -- extended built-in modules, like ``json`` and ``machine`` -- extra modules written in C/C++ -- extra modules written in Python + Include another manifest. + + Typically a manifest used for compiling firmware will need to include the + port manifest, which might include frozen modules that are required for + the board to function. + + The *manifest* argument can be a string (filename) or an iterable of + strings. -All the modules included in the firmware are available via ``import`` from -Python code. The extra modules written in Python that are included in a build -(the last point above) are called *frozen modules*, and are specified by a -``manifest.py`` file. Changing this manifest requires rebuilding the firmware. + Relative paths are resolved with respect to the current manifest file. -It's also possible to add additional modules to the filesystem of the device -once it is up and running. Adding and removing modules to/from the filesystem -does not require rebuilding the firmware so is a simpler process than rebuilding -firmware. The benefit of using a manifest is that frozen modules are more -efficient: they are faster to import and take up less RAM once imported. + If the path is to a directory, then it implicitly includes the + manifest.py file inside that directory. -MicroPython manifest files are Python files and can contain arbitrary Python -code. There are also a set of commands (predefined functions) which are used -to specify the Python source files to include. These commands are described -below. + You can use the variables above, such as ``$(PORT_DIR)`` in ``manifest_path``. -Freezing source code --------------------- +.. function:: metadata(description=None, version=None, license=None, author=None) + + Define metadata for this manifest file. This is useful for manifests for + micropython-lib packages. + +Low-level functions +~~~~~~~~~~~~~~~~~~~ + +These functions are documented for completeness, but with the exception of +``freeze_as_str`` all functionality can be accessed via the high-level functions. .. function:: freeze(path, script=None, opt=0) @@ -42,9 +184,7 @@ Freezing source code module will start after *path*, i.e. *path* is excluded from the module name. - If *path* is relative, it is resolved to the current ``manifest.py``. Use - ``$(MPY_DIR)``, ``$(MPY_LIB_DIR)``, ``$(PORT_DIR)``, ``$(BOARD_DIR)`` if you - need to access specific paths. + If *path* is relative, it is resolved to the current ``manifest.py``. If *script* is None, all files in *path* will be frozen. @@ -75,71 +215,48 @@ Freezing source code Freeze the input, which must be ``.mpy`` files that are frozen directly. See ``freeze()`` for further details on the arguments. - -Including other manifest files ------------------------------- - -.. function:: include(manifest, **kwargs) - - Include another manifest. - - The *manifest* argument can be a string (filename) or an iterable of - strings. - - Relative paths are resolved with respect to the current manifest file. - - Optional *kwargs* can be provided which will be available to the included - script via the *options* variable. - - For example: - - .. code-block:: python3 - - include("path.py", extra_features=True) - - then in path.py: - - .. code-block:: python3 - - options.defaults(standard_features=True) - # freeze minimal modules. - if options.standard_features: - # freeze standard modules. - if options.extra_features: - # freeze extra modules. - - Examples -------- -To freeze a single file which is available as ``import mydriver``, use: +To freeze a single file from the current directory which will be available as +``import mydriver``, use: .. code-block:: python3 - freeze(".", "mydriver.py") + module("mydriver.py") -To freeze a set of files which are available as ``import test1`` and -``import test2``, and which are compiled with optimisation level 3, use: +To freeze a directory of files in a subdirectory "mydriver" of the current +directory which will be available as ``import mydriver``, use: .. code-block:: python3 - freeze("/path/to/tests", ("test1.py", "test2.py"), opt=3) + package("mydriver") -To freeze a module which can be imported as ``import mymodule``, use: +To freeze the "hmac" library from :term:`micropython-lib`, use: .. code-block:: python3 - freeze( - "../relative/path", - ( - "mymodule/__init__.py", - "mymodule/core.py", - "mymodule/extra.py", - ), - ) + require("hmac") -To include a manifest from the MicroPython repository, use: +A more complete example of a custom ``manifest.py`` file for the ``PYBD_SF2`` +board is: .. code-block:: python3 - include("$(MPY_DIR)/extmod/uasyncio/manifest.py") + # Include the board's default manifest. + include("$(BOARD_DIR)/manifest.py") + # Add a custom driver + module("mydriver.py") + # Add aiorepl from micropython-lib + require("aiorepl") + +Then the board can be compiled with + +.. code-block:: bash + + $ cd ports/stm32 + $ make BOARD=PYBD_SF2 FROZEN_MANIFEST=~/src/myproject/manifest.py + +Note that most boards do not have their own ``manifest.py``, rather they use the +port one directly, in which case your manifest should just +``include("$(PORT_DIR)/boards/manifest.py")`` instead. diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index eb44992ed632..0c049d1fb2fc 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -1,314 +1,153 @@ .. _packages: -Distribution packages, package management, and deploying applications -===================================================================== - -Just as the "big" Python, MicroPython supports creation of "third party" -packages, distributing them, and easily installing them in each user's -environment. This chapter discusses how these actions are achieved. -Some familiarity with Python packaging is recommended. - -Overview --------- - -Steps below represent a high-level workflow when creating and consuming -packages: - -1. Python modules and packages are turned into distribution package - archives, and published at the Python Package Index (PyPI). -2. :term:`upip` package manager can be used to install a distribution package - on a :term:`MicroPython port` with networking capabilities (for example, - on the Unix port). -3. For ports without networking capabilities, an "installation image" - can be prepared on the Unix port, and transferred to a device by - suitable means. -4. For low-memory ports, the installation image can be frozen as the - bytecode into MicroPython executable, thus minimizing the memory - storage overheads. - -The sections below describe this process in details. - -Distribution packages ---------------------- - -Python modules and packages can be packaged into archives suitable for -transfer between systems, storing at the well-known location (PyPI), -and downloading on demand for deployment. These archives are known as -*distribution packages* (to differentiate them from Python packages -(means to organize Python source code)). - -The MicroPython distribution package format is a well-known tar.gz -format, with some adaptations however. The Gzip compressor, used as -an external wrapper for TAR archives, by default uses 32KB dictionary -size, which means that to uncompress a compressed stream, 32KB of -contiguous memory needs to be allocated. This requirement may be not -satisfiable on low-memory devices, which may have total memory available -less than that amount, and even if not, a contiguous block like that -may be hard to allocate due to memory fragmentation. To accommodate -these constraints, MicroPython distribution packages use Gzip compression -with the dictionary size of 4K, which should be a suitable compromise -with still achieving some compression while being able to uncompressed -even by the smallest devices. - -Besides the small compression dictionary size, MicroPython distribution -packages also have other optimizations, like removing any files from -the archive which aren't used by the installation process. In particular, -:term:`upip` package manager doesn't execute ``setup.py`` during installation -(see below), and thus that file is not included in the archive. - -At the same time, these optimizations make MicroPython distribution -packages not compatible with :term:`CPython`'s package manager, ``pip``. -This isn't considered a big problem, because: - -1. Packages can be installed with :term:`upip`, and then can be used with - CPython (if they are compatible with it). -2. In the other direction, majority of CPython packages would be - incompatible with MicroPython by various reasons, first of all, - the reliance on features not implemented by MicroPython. - -Summing up, the MicroPython distribution package archives are highly -optimized for MicroPython's target environments, which are highly -resource constrained devices. - - -``upip`` package manager ------------------------- - -MicroPython distribution packages are intended to be installed using -the :term:`upip` package manager. :term:`upip` is a Python application which is -usually distributed (as frozen bytecode) with network-enabled -:term:`MicroPython ports `. At the very least, -:term:`upip` is available in the :term:`MicroPython Unix port`. - -On any :term:`MicroPython port` providing :term:`upip`, it can be accessed as -following:: - - import upip - upip.help() - upip.install(package_or_package_list, [path]) - -Where *package_or_package_list* is the name of a distribution -package to install, or a list of such names to install multiple -packages. Optional *path* parameter specifies filesystem -location to install under and defaults to the standard library -location (see below). - -An example of installing a specific package and then using it:: - - >>> import upip - >>> upip.install("micropython-pystone_lowmem") - [...] - >>> import pystone_lowmem - >>> pystone_lowmem.main() - -Note that the name of Python package and the name of distribution -package for it in general don't have to match, and oftentimes they -don't. This is because PyPI provides a central package repository -for all different Python implementations and versions, and thus -distribution package names may need to be namespaced for a particular -implementation. For example, all packages from `micropython-lib` -follow this naming convention: for a Python module or package named -``foo``, the distribution package name is ``micropython-foo``. - -For the ports which run MicroPython executable from the OS command -prompts (like the Unix port), `upip` can be (and indeed, usually is) -run from the command line instead of MicroPython's own REPL. The -commands which corresponds to the example above are:: - - micropython -m upip -h - micropython -m upip install [-p ] ... - micropython -m upip install micropython-pystone_lowmem - -[TODO: Describe installation path.] - - -Cross-installing packages -------------------------- - -For :term:`MicroPython ports ` without native networking -capabilities, the recommend process is "cross-installing" them into a -"directory image" using the :term:`MicroPython Unix port`, and then -transferring this image to a device by suitable means. - -Installing to a directory image involves using ``-p`` switch to :term:`upip`:: - - micropython -m upip install -p install_dir micropython-pystone_lowmem - -After this command, the package content (and contents of every dependency -packages) will be available in the ``install_dir/`` subdirectory. You -would need to transfer contents of this directory (without the -``install_dir/`` prefix) to the device, at the suitable location, where -it can be found by the Python ``import`` statement (see discussion of -the :term:`upip` installation path above). - - -Cross-installing packages with freezing ---------------------------------------- - -For the low-memory :term:`MicroPython ports `, the process -described in the previous section does not provide the most efficient -resource usage,because the packages are installed in the source form, -so need to be compiled to the bytecome on each import. This compilation -requires RAM, and the resulting bytecode is also stored in RAM, reducing -its amount available for storing application data. Moreover, the process -above requires presence of the filesystem on a device, and the most -resource-constrained devices may not even have it. - -The bytecode freezing is a process which resolves all the issues -mentioned above: - -* The source code is pre-compiled into bytecode and store as such. -* The bytecode is stored in ROM, not RAM. -* Filesystem is not required for frozen packages. - -Using frozen bytecode requires building the executable (firmware) -for a given :term:`MicroPython port` from the C source code. Consequently, -the process is: - -1. Follow the instructions for a particular port on setting up a - toolchain and building the port. For example, for ESP8266 port, - study instructions in ``ports/esp8266/README.md`` and follow them. - Make sure you can build the port and deploy the resulting - executable/firmware successfully before proceeding to the next steps. -2. Build :term:`MicroPython Unix port` and make sure it is in your PATH and - you can execute ``micropython``. -3. Change to port's directory (e.g. ``ports/esp8266/`` for ESP8266). -4. Run ``make clean-frozen``. This step cleans up any previous - modules which were installed for freezing (consequently, you need - to skip this step to add additional modules, instead of starting - from scratch). -5. Run ``micropython -m upip install -p modules ...`` to - install packages you want to freeze. -6. Run ``make clean``. -7. Run ``make``. - -After this, you should have the executable/firmware with modules as -the bytecode inside, which you can deploy the usual way. - -Few notes: - -1. Step 5 in the sequence above assumes that the distribution package - is available from PyPI. If that is not the case, you would need - to copy Python source files manually to ``modules/`` subdirectory - of the port directory. (Note that upip does not support - installing from e.g. version control repositories). -2. The firmware for baremetal devices usually has size restrictions, - so adding too many frozen modules may overflow it. Usually, you - would get a linking error if this happens. However, in some cases, - an image may be produced, which is not runnable on a device. Such - cases are in general bugs, and should be reported and further - investigated. If you face such a situation, as an initial step, - you may want to decrease the amount of frozen modules included. - - -Creating distribution packages ------------------------------- - -Distribution packages for MicroPython are created in the same manner -as for CPython or any other Python implementation, see references at -the end of chapter. Setuptools (instead of distutils) should be used, -because distutils do not support dependencies and other features. "Source -distribution" (``sdist``) format is used for packaging. The post-processing -discussed above, (and pre-processing discussed in the following section) -is achieved by using custom ``sdist`` command for setuptools. Thus, packaging -steps remain the same as for the standard setuptools, the user just -needs to override ``sdist`` command implementation by passing the -appropriate argument to ``setup()`` call:: - - from setuptools import setup - import sdist_upip - - setup( - ..., - cmdclass={'sdist': sdist_upip.sdist} - ) - -The sdist_upip.py module as referenced above can be found in -`micropython-lib`: -https://github.com/micropython/micropython-lib/blob/master/sdist_upip.py - - -Application resources ---------------------- - -A complete application, besides the source code, oftentimes also consists -of data files, e.g. web page templates, game images, etc. It's clear how -to deal with those when application is installed manually - you just put -those data files in the filesystem at some location and use the normal -file access functions. - -The situation is different when deploying applications from packages - this -is more advanced, streamlined and flexible way, but also requires more -advanced approach to accessing data files. This approach is treating -the data files as "resources", and abstracting away access to them. - -Python supports resource access using its "setuptools" library, using -``pkg_resources`` module. MicroPython, following its usual approach, -implements subset of the functionality of that module, specifically -``pkg_resources.resource_stream(package, resource)`` function. -The idea is that an application calls this function, passing a -resource identifier, which is a relative path to data file within -the specified package (usually top-level application package). It -returns a stream object which can be used to access resource contents. -Thus, the ``resource_stream()`` emulates interface of the standard -`open()` function. - -Implementation-wise, ``resource_stream()`` uses file operations -underlyingly, if distribution package is install in the filesystem. -However, it also supports functioning without the underlying filesystem, -e.g. if the package is frozen as the bytecode. This however requires -an extra intermediate step when packaging application - creation of -"Python resource module". - -The idea of this module is to convert binary data to a Python bytes -object, and put it into the dictionary, indexed by the resource name. -This conversion is done automatically using overridden ``sdist`` command -described in the previous section. - -Let's trace the complete process using the following example. Suppose -your application has the following structure:: - - my_app/ - __main__.py - utils.py - data/ - page.html - image.png - -``__main__.py`` and ``utils.py`` should access resources using the -following calls:: - - import pkg_resources - - pkg_resources.resource_stream(__name__, "data/page.html") - pkg_resources.resource_stream(__name__, "data/image.png") - -You can develop and debug using the :term:`MicroPython Unix port` as usual. -When time comes to make a distribution package out of it, just use -overridden "sdist" command from sdist_upip.py module as described in -the previous section. - -This will create a Python resource module named ``R.py``, based on the -files declared in ``MANIFEST`` or ``MANIFEST.in`` files (any non-``.py`` -file will be considered a resource and added to ``R.py``) - before -proceeding with the normal packaging steps. - -Prepared like this, your application will work both when deployed to -filesystem and as frozen bytecode. - -If you would like to debug ``R.py`` creation, you can run:: - - python3 setup.py sdist --manifest-only - -Alternatively, you can use tools/mpy_bin2res.py script from the -MicroPython distribution, in which can you will need to pass paths -to all resource files:: - - mpy_bin2res.py data/page.html data/image.png - -References ----------- - -* Python Packaging User Guide: https://packaging.python.org/ -* Setuptools documentation: https://setuptools.readthedocs.io/ -* Distutils documentation: https://docs.python.org/3/library/distutils.html +Package management +================== + +Installing packages with ``mip`` +-------------------------------- + +Network-capable boards include the ``mip`` module, which can install packages +from :term:`micropython-lib` and from third-party sites (including GitHub). + +``mip`` ("mip installs packages") is similar in concept to Python's ``pip`` tool, +however it does not use the PyPI index, rather it uses :term:`micropython-lib` +as its index by default. ``mip`` will automatically fetch compiled +:term:`.mpy file` when downloading from micropython-lib. + +The most common way to use ``mip`` is from the REPL:: + + >>> import mip + >>> mip.install("pkgname") # Installs the latest version of "pkgname" (and dependencies) + >>> mip.install("pkgname", version="x.y") # Installs version x.y of "pkgname" + >>> mip.install("pkgname", mpy=False) # Installs the source version (i.e. .py rather than .mpy files) + +``mip`` will detect an appropriate location on the filesystem by searching +``sys.path`` for the first entry ending in ``/lib``. You can override the +destination using ``target``, but note that this path must be in ``sys.path`` to be +able to subsequently import it.:: + + >>> mip.install("pkgname", target="third-party") + >>> sys.path.append("third-party") + +As well as downloading packages from the micropython-lib index, ``mip`` can also +install third-party libraries. The simplest way is to download a file directly:: + + >>> mip.install("http://example.com/x/y/foo.py") + >>> mip.install("http://example.com/x/y/foo.mpy") + +When installing a file directly, the ``target`` argument is still supported to set +the destination path, but ``mpy`` and ``version`` are ignored. + +The URL can also start with ``github:`` as a simple way of pointing to content +hosted on GitHub:: + + >>> mip.install("github:org/repo/path/foo.py") # Uses default branch + >>> mip.install("github:org/repo/path/foo.py", version="branch-or-tag") # Optionally specify the branch or tag + +More sophisticated packages (i.e. with more than one file, or with dependencies) +can be downloaded by specifying the path to their ``package.json``. + + >>> mip.install("http://example.com/x/package.json") + >>> mip.install("github:org/user/path/package.json") + +If no json file is specified, then "package.json" is implicitly added:: + + >>> mip.install("http://example.com/x/") + >>> mip.install("github:org/repo") + >>> mip.install("github:org/repo", version="branch-or-tag") + + +Using ``mip`` on the Unix port +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On the Unix port, ``mip`` can be used at the REPL as above, and also by using ``-m``:: + + $ ./micropython -m mip install pkgname-or-url + $ ./micropython -m mip install pkgname-or-url@version + +The ``--target=path``, ``--no-mpy``, and ``--index`` arguments can be set:: + + $ ./micropython -m mip install --target=third-party pkgname + $ ./micropython -m mip install --no-mpy pkgname + $ ./micropython -m mip install --index https://host/pi pkgname + +Installing packages with ``mpremote`` +------------------------------------- + +The :term:`mpremote` tool also includes the same functionality as ``mip`` and +can be used from a host PC to install packages to a locally connected device +(e.g. via USB or UART):: + + $ mpremote install pkgname + $ mpremote install pkgname@x.y + $ mpremote install http://example.com/x/y/foo.py + $ mpremote install github:org/repo + $ mpremote install github:org/repo@branch-or-tag + +The ``--target=path``, ``--no-mpy``, and ``--index`` arguments can be set:: + + $ mpremote install --target=/flash/third-party pkgname + $ mpremote install --no-mpy pkgname + $ mpremote install --index https://host/pi pkgname + +Installing packages manually +---------------------------- + +Packages can also be installed (in either .py or .mpy form) by manually copying +the files to the device. Depending on the board this might be via USB Mass Storage, +the :term:`mpremote` tool (e.g. ``mpremote fs cp path/to/package.py :package.py``), +:term:`webrepl`, etc. + +Writing & publishing packages +----------------------------- + +Publishing to :term:`micropython-lib` is the easiest way to make your package +broadly accessible to MicroPython users, and automatically available via +``mip`` and ``mpremote`` and compiled to bytecode. See +https://github.com/micropython/micropython-lib for more information. + +To write a "self-hosted" package that can be downloaded by ``mip`` or +``mpremote``, you need a static webserver (or GitHub) to host either a +single .py file, or a package.json file alongside your .py files. + +A typical package.json for an example ``mlx90640`` library looks like:: + + { + "urls": [ + ["mlx90640/__init__.py", "github:org/micropython-mlx90640/mlx90640/__init__.py"], + ["mlx90640/utils.py", "github:org/micropython-mlx90640/mlx90640/utils.py"] + ], + "deps": [ + ["collections-defaultdict", "latest"], + ["os-path", "latest"] + ], + "version": "0.2" + } + +This includes two files, hosted at a GitHub repo named +``org/micropython-mlx90640``, which install into the ``mlx90640`` directory on +the device. It depends on ``collections-defaultdict`` and ``os-path`` which will +be installed automatically. + +Freezing packages +----------------- + +When a Python module or package is imported from the device filesystem, it is +compiled into :term:`bytecode` in RAM, ready to be executed by the VM. For +a :term:`.mpy file`, this conversion has been done already, but the bytecode +still ends up in RAM. + +For low-memory devices, or for large applications, it can be advantageous to +instead run the bytecode from ROM (i.e. flash memory). This can be done +by "freezing" the bytecode into the MicroPython firmware, which is then flashed +to the device. The runtime performance is the same (although importing is +faster), but it can free up significant amounts of RAM for your program to +use. + +The downside of this approach is that it's much slower to develop, because you +have to flash the firmware each time, but it can be still useful to freeze +dependencies that don't change often. + +Freezing is done by writing a manifest file and using it in the build, often as +part of a custom board definition. See the :ref:`manifest` guide for more +information. diff --git a/examples/hwapi/README.md b/examples/hwapi/README.md index 1992eb66094e..df16b4c86be5 100644 --- a/examples/hwapi/README.md +++ b/examples/hwapi/README.md @@ -116,7 +116,7 @@ For example, one may invent a "configuration manager" helper module which will try to detect current board (among well-known ones), and load appropriate `hwconfig_*.py` - this assumes that a user would lazily deploy them all (or that application will be automatically installed, e.g. using MicroPython's -`upip` package manager). The key point in this case remains the same as +`mip` package manager). The key point in this case remains the same as elaborated above - always assume there can, and will be a custom configuration, and it should be well supported. So, any automatic detection should be overridable by a user, and instructions how to do so are among the most diff --git a/ports/esp32/boards/manifest.py b/ports/esp32/boards/manifest.py index fcc48d721805..3f6c8cfde5a9 100644 --- a/ports/esp32/boards/manifest.py +++ b/ports/esp32/boards/manifest.py @@ -1,11 +1,10 @@ freeze("$(PORT_DIR)/modules") -module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) -module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) include("$(MPY_DIR)/extmod/uasyncio") # Require some micropython-lib modules. require("dht") require("ds18x20") +require("mip") require("neopixel") require("ntptime") require("onewire") diff --git a/ports/esp8266/README.md b/ports/esp8266/README.md index dd50fc1af943..b54d8958d77d 100644 --- a/ports/esp8266/README.md +++ b/ports/esp8266/README.md @@ -200,20 +200,22 @@ Python prompt over WiFi, connecting through a browser. - GitHub repository https://github.com/micropython/webrepl. Please follow the instructions there. -__upip__ +__mip__ -The ESP8266 port comes with builtin `upip` package manager, which can -be used to install additional modules (see the main README for more -information): +The ESP8266 port comes with the built-in `mip` package manager, which can +be used to install additional modules: ``` ->>> import upip ->>> upip.install("micropython-pystone_lowmem") +>>> import mip +>>> mip.install("hmac") [...] ->>> import pystone_lowmem ->>> pystone_lowmem.main() +>>> import hmac +>>> hmac.new(b"1234567890", msg="hello world").hexdigest() ``` +See [Package management](https://docs.micropython.org/en/latest/reference/packages.html) for more +information about `mip`. + Downloading and installing packages may requite a lot of free memory, if you get an error, retry immediately after the hard reset. diff --git a/ports/esp8266/boards/manifest.py b/ports/esp8266/boards/manifest.py index e7defd0bb70f..53975f6a6baf 100644 --- a/ports/esp8266/boards/manifest.py +++ b/ports/esp8266/boards/manifest.py @@ -1,9 +1,8 @@ freeze("$(PORT_DIR)/modules") -module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) -module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) -require("ntptime") require("dht") -require("onewire") require("ds18x20") +require("mip") require("neopixel") +require("ntptime") +require("onewire") require("webrepl") diff --git a/ports/rp2/boards/PICO_W/manifest.py b/ports/rp2/boards/PICO_W/manifest.py index 4d9eb87f20f3..8a74006c64f7 100644 --- a/ports/rp2/boards/PICO_W/manifest.py +++ b/ports/rp2/boards/PICO_W/manifest.py @@ -1,7 +1,5 @@ include("../manifest.py") -module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) -module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) - +require("mip") require("ntptime") require("urequests") diff --git a/ports/unix/README.md b/ports/unix/README.md index efc68b2455f9..a3a0dba75a13 100644 --- a/ports/unix/README.md +++ b/ports/unix/README.md @@ -24,21 +24,26 @@ Use `CTRL-D` (i.e. EOF) to exit the shell. Learn about command-line options (in particular, how to increase heap size which may be needed for larger applications): - $ ./micropython -h + $ ./build-standard/micropython -h To run the complete testsuite, use: $ make test -The Unix port comes with a builtin package manager called upip, e.g.: +The Unix port comes with a built-in package manager called `mip`, e.g.: - $ ./micropython -m upip install micropython-pystone - $ ./micropython -m pystone + $ ./build-standard/micropython -m mip install hmac -Browse available modules on -[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython). -Standard library modules come from the -[micropython-lib](https://github.com/micropython/micropython-lib) project. +or + + $ ./build-standard/micropython + >>> import mip + >>> mip.install("hmac") + +Browse available modules at [micropython-lib] +(https://github.com/micropython/micropython-lib). See +[Package management](https://docs.micropython.org/en/latest/reference/packages.html) +for more information about `mip`. External dependencies --------------------- @@ -65,6 +70,5 @@ or not). If you intend to build MicroPython with additional options (like cross-compiling), the same set of options should be passed to `make deplibs`. To actually enable/disable use of dependencies, edit the `ports/unix/mpconfigport.mk` file, which has inline descriptions of the -options. For example, to build SSL module (required for the `upip` tool -described above, and so enabled by default), `MICROPY_PY_USSL` should be set -to 1. +options. For example, to build the SSL module, `MICROPY_PY_USSL` should be +set to 1. diff --git a/ports/unix/variants/manifest.py b/ports/unix/variants/manifest.py index bf7ce992ade0..e7fe747cb797 100644 --- a/ports/unix/variants/manifest.py +++ b/ports/unix/variants/manifest.py @@ -1,2 +1 @@ -module("upip.py", base_path="$(MPY_DIR)/tools", opt=3) -module("upip_utarfile.py", base_path="$(MPY_DIR)/tools", opt=3) +require("mip") diff --git a/tools/upip.py b/tools/upip.py deleted file mode 100644 index 2932cca50cc9..000000000000 --- a/tools/upip.py +++ /dev/null @@ -1,351 +0,0 @@ -# -# upip - Package manager for MicroPython -# -# Copyright (c) 2015-2018 Paul Sokolovsky -# -# Licensed under the MIT license. -# -import sys -import gc -import uos as os -import uerrno as errno -import ujson as json -import uzlib -import upip_utarfile as tarfile - -gc.collect() - - -debug = False -index_urls = ["https://micropython.org/pi", "https://pypi.org/pypi"] -install_path = None -cleanup_files = [] -gzdict_sz = 16 + 15 - -file_buf = bytearray(512) - - -class NotFoundError(Exception): - pass - - -def op_split(path): - if path == "": - return ("", "") - r = path.rsplit("/", 1) - if len(r) == 1: - return ("", path) - head = r[0] - if not head: - head = "/" - return (head, r[1]) - - -# Expects *file* name -def _makedirs(name, mode=0o777): - ret = False - s = "" - comps = name.rstrip("/").split("/")[:-1] - if comps[0] == "": - s = "/" - for c in comps: - if s and s[-1] != "/": - s += "/" - s += c - try: - os.mkdir(s) - ret = True - except OSError as e: - if e.errno != errno.EEXIST and e.errno != errno.EISDIR: - raise e - ret = False - return ret - - -def save_file(fname, subf): - global file_buf - with open(fname, "wb") as outf: - while True: - sz = subf.readinto(file_buf) - if not sz: - break - outf.write(file_buf, sz) - - -def install_tar(f, prefix): - meta = {} - for info in f: - # print(info) - fname = info.name - try: - fname = fname[fname.index("/") + 1 :] - except ValueError: - fname = "" - - save = True - for p in ("setup.", "PKG-INFO", "README"): - # print(fname, p) - if fname.startswith(p) or ".egg-info" in fname: - if fname.endswith("/requires.txt"): - meta["deps"] = f.extractfile(info).read() - save = False - if debug: - print("Skipping", fname) - break - - if save: - outfname = prefix + fname - if info.type != tarfile.DIRTYPE: - if debug: - print("Extracting " + outfname) - _makedirs(outfname) - subf = f.extractfile(info) - save_file(outfname, subf) - return meta - - -def expandhome(s): - if "~/" in s: - h = os.getenv("HOME") - s = s.replace("~/", h + "/") - return s - - -import ussl -import usocket - -warn_ussl = True - - -def url_open(url): - global warn_ussl - - if debug: - print(url) - - proto, _, host, urlpath = url.split("/", 3) - try: - port = 443 - if ":" in host: - host, port = host.split(":") - port = int(port) - ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM) - except OSError as e: - fatal("Unable to resolve %s (no Internet?)" % host, e) - # print("Address infos:", ai) - ai = ai[0] - - s = usocket.socket(ai[0], ai[1], ai[2]) - try: - # print("Connect address:", addr) - s.connect(ai[-1]) - - if proto == "https:": - s = ussl.wrap_socket(s, server_hostname=host) - if warn_ussl: - print("Warning: %s SSL certificate is not validated" % host) - warn_ussl = False - - # MicroPython rawsocket module supports file interface directly - s.write("GET /%s HTTP/1.0\r\nHost: %s:%s\r\n\r\n" % (urlpath, host, port)) - l = s.readline() - protover, status, msg = l.split(None, 2) - if status != b"200": - if status == b"404" or status == b"301": - raise NotFoundError("Package not found") - raise ValueError(status) - while 1: - l = s.readline() - if not l: - raise ValueError("Unexpected EOF in HTTP headers") - if l == b"\r\n": - break - except Exception as e: - s.close() - raise e - - return s - - -def get_pkg_metadata(name): - for url in index_urls: - try: - f = url_open("%s/%s/json" % (url, name)) - except NotFoundError: - continue - try: - return json.load(f) - finally: - f.close() - raise NotFoundError("Package not found") - - -def fatal(msg, exc=None): - print("Error:", msg) - if exc and debug: - raise exc - sys.exit(1) - - -def install_pkg(pkg_spec, install_path): - package = pkg_spec.split("==") - data = get_pkg_metadata(package[0]) - - if len(package) == 1: - latest_ver = data["info"]["version"] - else: - latest_ver = package[1] - packages = data["releases"][latest_ver] - del data - gc.collect() - assert len(packages) == 1 - package_url = packages[0]["url"] - print("Installing %s %s from %s" % (pkg_spec, latest_ver, package_url)) - f1 = url_open(package_url) - try: - f2 = uzlib.DecompIO(f1, gzdict_sz) - f3 = tarfile.TarFile(fileobj=f2) - meta = install_tar(f3, install_path) - finally: - f1.close() - del f3 - del f2 - gc.collect() - return meta - - -def install(to_install, install_path=None): - # Calculate gzip dictionary size to use - global gzdict_sz - sz = gc.mem_free() + gc.mem_alloc() - if sz <= 65536: - gzdict_sz = 16 + 12 - - if install_path is None: - install_path = get_install_path() - if install_path[-1] != "/": - install_path += "/" - if not isinstance(to_install, list): - to_install = [to_install] - print("Installing to: " + install_path) - # sets would be perfect here, but don't depend on them - installed = [] - try: - while to_install: - if debug: - print("Queue:", to_install) - pkg_spec = to_install.pop(0) - if pkg_spec in installed: - continue - meta = install_pkg(pkg_spec, install_path) - installed.append(pkg_spec) - if debug: - print(meta) - deps = meta.get("deps", "").rstrip() - if deps: - deps = deps.decode("utf-8").split("\n") - to_install.extend(deps) - except Exception as e: - print( - "Error installing '{}': {}, packages may be partially installed".format(pkg_spec, e), - file=sys.stderr, - ) - - -def get_install_path(): - global install_path - if install_path is None: - # sys.path[0] is current module's path - install_path = sys.path[1] - if install_path == ".frozen": - install_path = sys.path[2] - install_path = expandhome(install_path) - return install_path - - -def cleanup(): - for fname in cleanup_files: - try: - os.unlink(fname) - except OSError: - print("Warning: Cannot delete " + fname) - - -def help(): - print( - """\ -upip - Simple PyPI package manager for MicroPython -Usage: micropython -m upip install [-p ] ... | -r -import upip; upip.install(package_or_list, []) - -If isn't given, packages will be installed to sys.path[1], or -sys.path[2] if the former is .frozen (path can be set from MICROPYPATH -environment variable if supported).""" - ) - print("Default install path:", get_install_path()) - print( - """\ - -Note: only MicroPython packages (usually, named micropython-*) are supported -for installation, upip does not support arbitrary code in setup.py. -""" - ) - - -def main(): - global debug - global index_urls - global install_path - install_path = None - - if len(sys.argv) < 2 or sys.argv[1] == "-h" or sys.argv[1] == "--help": - help() - return - - if sys.argv[1] != "install": - fatal("Only 'install' command supported") - - to_install = [] - - i = 2 - while i < len(sys.argv) and sys.argv[i][0] == "-": - opt = sys.argv[i] - i += 1 - if opt == "-h" or opt == "--help": - help() - return - elif opt == "-p": - install_path = sys.argv[i] - i += 1 - elif opt == "-r": - list_file = sys.argv[i] - i += 1 - with open(list_file) as f: - while True: - l = f.readline() - if not l: - break - if l[0] == "#": - continue - to_install.append(l.rstrip()) - elif opt == "-i": - index_urls = [sys.argv[i]] - i += 1 - elif opt == "--debug": - debug = True - else: - fatal("Unknown/unsupported option: " + opt) - - to_install.extend(sys.argv[i:]) - if not to_install: - help() - return - - install(to_install) - - if not debug: - cleanup() - - -if __name__ == "__main__": - main() diff --git a/tools/upip_utarfile.py b/tools/upip_utarfile.py deleted file mode 100644 index 21b899f020a9..000000000000 --- a/tools/upip_utarfile.py +++ /dev/null @@ -1,95 +0,0 @@ -import uctypes - -# http://www.gnu.org/software/tar/manual/html_node/Standard.html -TAR_HEADER = { - "name": (uctypes.ARRAY | 0, uctypes.UINT8 | 100), - "size": (uctypes.ARRAY | 124, uctypes.UINT8 | 11), -} - -DIRTYPE = "dir" -REGTYPE = "file" - - -def roundup(val, align): - return (val + align - 1) & ~(align - 1) - - -class FileSection: - def __init__(self, f, content_len, aligned_len): - self.f = f - self.content_len = content_len - self.align = aligned_len - content_len - - def read(self, sz=65536): - if self.content_len == 0: - return b"" - if sz > self.content_len: - sz = self.content_len - data = self.f.read(sz) - sz = len(data) - self.content_len -= sz - return data - - def readinto(self, buf): - if self.content_len == 0: - return 0 - if len(buf) > self.content_len: - buf = memoryview(buf)[: self.content_len] - sz = self.f.readinto(buf) - self.content_len -= sz - return sz - - def skip(self): - sz = self.content_len + self.align - if sz: - buf = bytearray(16) - while sz: - s = min(sz, 16) - self.f.readinto(buf, s) - sz -= s - - -class TarInfo: - def __str__(self): - return "TarInfo(%r, %s, %d)" % (self.name, self.type, self.size) - - -class TarFile: - def __init__(self, name=None, fileobj=None): - if fileobj: - self.f = fileobj - else: - self.f = open(name, "rb") - self.subf = None - - def next(self): - if self.subf: - self.subf.skip() - buf = self.f.read(512) - if not buf: - return None - - h = uctypes.struct(uctypes.addressof(buf), TAR_HEADER, uctypes.LITTLE_ENDIAN) - - # Empty block means end of archive - if h.name[0] == 0: - return None - - d = TarInfo() - d.name = str(h.name, "utf-8").rstrip("\0") - d.size = int(bytes(h.size), 8) - d.type = [REGTYPE, DIRTYPE][d.name[-1] == "/"] - self.subf = d.subf = FileSection(self.f, d.size, roundup(d.size, 512)) - return d - - def __iter__(self): - return self - - def __next__(self): - v = self.next() - if v is None: - raise StopIteration - return v - - def extractfile(self, tarinfo): - return tarinfo.subf From 282401da5c6e689e63af7b9858cf9b0d23a24b2b Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 30 Sep 2022 15:33:43 +1000 Subject: [PATCH 1787/4290] tools/manifestfile.py: Replace recursive glob with os.walk. Recursive glob isn't supported before Python 3.5. Signed-off-by: Jim Mussared --- tools/manifestfile.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/manifestfile.py b/tools/manifestfile.py index f7966ccb8045..fb9691d2931a 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -311,14 +311,14 @@ def require(self, name, version=None, unix_ffi=False, **kwargs): lib_dirs = ["unix-ffi"] + lib_dirs for lib_dir in lib_dirs: - for manifest_path in glob.glob( - os.path.join( - self._path_vars["MPY_LIB_DIR"], lib_dir, "**", name, "manifest.py" - ), - recursive=True, + # Search for {lib_dir}/**/{name}/manifest.py. + for root, dirnames, filenames in os.walk( + os.path.join(self._path_vars["MPY_LIB_DIR"], lib_dir) ): - self.include(manifest_path, **kwargs) - return + if os.path.basename(root) == name and "manifest.py" in filenames: + self.include(root, **kwargs) + return + raise ValueError("Library not found in local micropython-lib: {}".format(name)) else: # TODO: HTTP request to obtain URLs from manifest.json. From 413a69b94b92d1ae1cdd132e41d460259d22b9b8 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 30 Sep 2022 11:46:23 +1000 Subject: [PATCH 1788/4290] tools/mpremote: Simplify dispatch of commands. No functional change. This makes each built-in command defined by just a handler method and simplifies a lot of the logic around tracking the board state. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- tools/mpremote/mpremote/commands.py | 261 +++++++++++++ tools/mpremote/mpremote/main.py | 557 ++++++++-------------------- tools/mpremote/mpremote/repl.py | 101 +++++ 3 files changed, 510 insertions(+), 409 deletions(-) create mode 100644 tools/mpremote/mpremote/commands.py create mode 100644 tools/mpremote/mpremote/repl.py diff --git a/tools/mpremote/mpremote/commands.py b/tools/mpremote/mpremote/commands.py new file mode 100644 index 000000000000..60a625d5e854 --- /dev/null +++ b/tools/mpremote/mpremote/commands.py @@ -0,0 +1,261 @@ +import os +import sys +import tempfile + +import serial.tools.list_ports + +from . import pyboardextended as pyboard + + +class CommandError(Exception): + pass + + do_disconnect(state) + + try: + if dev == "list": + # List attached devices. + for p in sorted(serial.tools.list_ports.comports()): + print( + "{} {} {:04x}:{:04x} {} {}".format( + p.device, + p.serial_number, + p.vid if isinstance(p.vid, int) else 0, + p.pid if isinstance(p.pid, int) else 0, + p.manufacturer, + p.product, + ) + ) + # Don't do implicit REPL command. + state.did_action() + elif dev == "auto": + # Auto-detect and auto-connect to the first available device. + for p in sorted(serial.tools.list_ports.comports()): + try: + state.pyb = pyboard.PyboardExtended(p.device, baudrate=115200) + return + except pyboard.PyboardError as er: + if not er.args[0].startswith("failed to access"): + raise er + raise pyboard.PyboardError("no device found") + elif dev.startswith("id:"): + # Search for a device with the given serial number. + serial_number = dev[len("id:") :] + dev = None + for p in serial.tools.list_ports.comports(): + if p.serial_number == serial_number: + state.pyb = pyboard.PyboardExtended(p.device, baudrate=115200) + return + raise pyboard.PyboardError("no device with serial number {}".format(serial_number)) + else: + # Connect to the given device. + if dev.startswith("port:"): + dev = dev[len("port:") :] + state.pyb = pyboard.PyboardExtended(dev, baudrate=115200) + return + except pyboard.PyboardError as er: + msg = er.args[0] + if msg.startswith("failed to access"): + msg += " (it may be in use by another program)" + print(msg) + sys.exit(1) + + +def do_disconnect(state, _args=None): + if not state.pyb: + return + + try: + if state.pyb.mounted: + if not state.pyb.in_raw_repl: + state.pyb.enter_raw_repl(soft_reset=False) + state.pyb.umount_local() + if state.pyb.in_raw_repl: + state.pyb.exit_raw_repl() + except OSError: + # Ignore any OSError exceptions when shutting down, eg: + # - pyboard.filesystem_command will close the connecton if it had an error + # - umounting will fail if serial port disappeared + pass + state.pyb.close() + state.pyb = None + state._auto_soft_reset = True + + +def show_progress_bar(size, total_size, op="copying"): + if not sys.stdout.isatty(): + return + verbose_size = 2048 + bar_length = 20 + if total_size < verbose_size: + return + elif size >= total_size: + # Clear progress bar when copy completes + print("\r" + " " * (13 + len(op) + bar_length) + "\r", end="") + else: + bar = size * bar_length // total_size + progress = size * 100 // total_size + print( + "\r ... {} {:3d}% [{}{}]".format(op, progress, "#" * bar, "-" * (bar_length - bar)), + end="", + ) + + +# Get all args up to the terminator ("+"). +# The passed args will be updated with these ones removed. +def _get_fs_args(args): + n = 0 + for src in args: + if src == "+": + break + n += 1 + fs_args = args[:n] + args[:] = args[n + 1 :] + return fs_args + + +def do_filesystem(state, args): + state.ensure_raw_repl() + state.did_action() + + def _list_recursive(files, path): + if os.path.isdir(path): + for entry in os.listdir(path): + _list_recursive(files, "/".join((path, entry))) + else: + files.append(os.path.split(path)) + + fs_args = _get_fs_args(args) + + # Don't be verbose when using cat, so output can be redirected to something. + verbose = fs_args[0] != "cat" + + if fs_args[0] == "cp" and fs_args[1] == "-r": + fs_args.pop(0) + fs_args.pop(0) + if fs_args[-1] != ":": + print(f"{_PROG}: 'cp -r' destination must be ':'") + sys.exit(1) + fs_args.pop() + src_files = [] + for path in fs_args: + if path.startswith(":"): + raise CommandError("'cp -r' source files must be local") + _list_recursive(src_files, path) + known_dirs = {""} + state.pyb.exec_("import uos") + for dir, file in src_files: + dir_parts = dir.split("/") + for i in range(len(dir_parts)): + d = "/".join(dir_parts[: i + 1]) + if d not in known_dirs: + state.pyb.exec_("try:\n uos.mkdir('%s')\nexcept OSError as e:\n print(e)" % d) + known_dirs.add(d) + pyboard.filesystem_command( + state.pyb, + ["cp", "/".join((dir, file)), ":" + dir + "/"], + progress_callback=show_progress_bar, + verbose=verbose, + ) + else: + try: + pyboard.filesystem_command( + state.pyb, fs_args, progress_callback=show_progress_bar, verbose=verbose + ) + except OSError as er: + raise CommandError(er) + + +def do_edit(state, args): + state.ensure_raw_repl() + state.did_action() + + if not os.getenv("EDITOR"): + raise pyboard.PyboardError("edit: $EDITOR not set") + for src in _get_fs_args(args): + src = src.lstrip(":") + dest_fd, dest = tempfile.mkstemp(suffix=os.path.basename(src)) + try: + print("edit :%s" % (src,)) + os.close(dest_fd) + state.pyb.fs_touch(src) + state.pyb.fs_get(src, dest, progress_callback=show_progress_bar) + if os.system("$EDITOR '%s'" % (dest,)) == 0: + state.pyb.fs_put(dest, src, progress_callback=show_progress_bar) + finally: + os.unlink(dest) + + +def _get_follow_arg(args): + if args[0] == "--no-follow": + args.pop(0) + return False + else: + return True + + +def _do_execbuffer(state, buf, follow): + state.ensure_raw_repl() + state.did_action() + + try: + state.pyb.exec_raw_no_follow(buf) + if follow: + ret, ret_err = state.pyb.follow(timeout=None, data_consumer=pyboard.stdout_write_bytes) + if ret_err: + pyboard.stdout_write_bytes(ret_err) + sys.exit(1) + except pyboard.PyboardError as er: + print(er) + sys.exit(1) + except KeyboardInterrupt: + sys.exit(1) + + +def do_exec(state, args): + follow = _get_follow_arg(args) + buf = args.pop(0) + _do_execbuffer(state, buf, follow) + + +def do_eval(state, args): + follow = _get_follow_arg(args) + buf = "print(" + args.pop(0) + ")" + _do_execbuffer(state, buf, follow) + + +def do_run(state, args): + follow = _get_follow_arg(args) + filename = args.pop(0) + try: + with open(filename, "rb") as f: + buf = f.read() + except OSError: + raise CommandError(f"could not read file '{filename}'") + sys.exit(1) + _do_execbuffer(state, buf, follow) + + +def do_mount(state, args): + state.ensure_raw_repl() + + unsafe_links = False + if args[0] == "--unsafe-links" or args[0] == "-l": + args.pop(0) + unsafe_links = True + path = args.pop(0) + state.pyb.mount_local(path, unsafe_links=unsafe_links) + print(f"Local directory {path} is mounted at /remote") + + +def do_umount(state, path): + state.ensure_raw_repl() + state.pyb.umount_local() + + +def do_resume(state, _args=None): + state._auto_soft_reset = False + + +def do_soft_reset(state, _args=None): + state.ensure_raw_repl(soft_reset=True) diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index bd98da88248c..b96e3f46b1bf 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -19,45 +19,101 @@ import os, sys from collections.abc import Mapping -import tempfile from textwrap import dedent -import serial.tools.list_ports - -from . import pyboardextended as pyboard -from .console import Console, ConsolePosix +from .commands import ( + CommandError, + do_connect, + do_disconnect, + do_edit, + do_filesystem, + do_mount, + do_umount, + do_exec, + do_eval, + do_run, + do_resume, + do_soft_reset, +) +from .repl import do_repl _PROG = "mpremote" -# (need_raw_repl, is_action, num_args_min, help_text) + +def do_help(state, _args=None): + def print_commands_help(cmds, help_idx): + max_command_len = max(len(cmd) for cmd in cmds.keys()) + for cmd in sorted(cmds.keys()): + help_message_lines = dedent(cmds[cmd][help_idx]).split("\n") + help_message = help_message_lines[0] + for line in help_message_lines[1:]: + help_message = "{}\n{}{}".format(help_message, " " * (max_command_len + 4), line) + print(" ", cmd, " " * (max_command_len - len(cmd) + 2), help_message, sep="") + + print(_PROG, "-- MicroPython remote control") + print("See https://docs.micropython.org/en/latest/reference/mpremote.html") + + print("\nList of commands:") + print_commands_help(_COMMANDS, 1) + + print("\nList of shortcuts:") + print_commands_help(_command_expansions, 2) + + sys.exit(0) + + +def do_version(state, _args=None): + from . import __version__ + + print(f"{_PROG} {__version__}") + sys.exit(0) + + +# Map of "command" to tuple of (num_args_min, help_text, handler). _COMMANDS = { "connect": ( - False, - False, 1, """\ connect to given device device may be: list, auto, id:x, port:x or any valid device name/path""", + do_connect, + ), + "disconnect": ( + 0, + "disconnect current device", + do_disconnect, + ), + "edit": ( + 1, + "edit files on the device", + do_edit, + ), + "resume": ( + 0, + "resume a previous mpremote session (will not auto soft-reset)", + do_resume, + ), + "soft-reset": ( + 0, + "perform a soft-reset of the device", + do_soft_reset, ), - "disconnect": (False, False, 0, "disconnect current device"), - "edit": (True, True, 1, "edit files on the device"), - "resume": (False, False, 0, "resume a previous mpremote session (will not auto soft-reset)"), - "soft-reset": (False, True, 0, "perform a soft-reset of the device"), "mount": ( - True, - False, 1, """\ mount local directory on device options: --unsafe-links, -l follow symbolic links pointing outside of local directory""", + do_mount, + ), + "umount": ( + 0, + "unmount the local directory", + do_umount, ), - "umount": (True, False, 0, "unmount the local directory"), "repl": ( - False, - True, 0, """\ enter REPL @@ -65,15 +121,45 @@ --capture --inject-code --inject-file """, + do_repl, + ), + "eval": ( + 1, + "evaluate and print the string", + do_eval, + ), + "exec": ( + 1, + "execute the string", + do_exec, + ), + "run": ( + 1, + "run the given local script", + do_run, + ), + "fs": ( + 1, + "execute filesystem commands on the device", + do_filesystem, + ), + "help": ( + 0, + "print help and exit", + do_help, + ), + "version": ( + 0, + "print version and exit", + do_version, ), - "eval": (True, True, 1, "evaluate and print the string"), - "exec": (True, True, 1, "execute the string"), - "run": (True, True, 1, "run the given local script"), - "fs": (True, True, 1, "execute filesystem commands on the device"), - "help": (False, False, 0, "print help and exit"), - "version": (False, False, 0, "print version and exit"), } +# Additional commands aliases. +# The value can either be: +# - A command string. +# - A list of command strings, each command will be executed sequentially. +# - A dict of command: { [], help: ""} _BUILTIN_COMMAND_EXPANSIONS = { # Device connection shortcuts. "devs": { @@ -117,6 +203,8 @@ "--version": "version", } +# Add "a0", "a1", ..., "u0", "u1", ..., "c0", "c1", ... as aliases +# for "connect /dev/ttyACMn" (and /dev/ttyUSBn, COMn) etc. for port_num in range(4): for prefix, port in [("a", "/dev/ttyACM"), ("u", "/dev/ttyUSB"), ("c", "COM")]: _BUILTIN_COMMAND_EXPANSIONS["{}{}".format(prefix, port_num)] = { @@ -220,307 +308,33 @@ def usage_error(cmd, exp_args, msg): args[0:0] = ["exec", ";".join(pre)] -def do_connect(args): - dev = args.pop(0) - try: - if dev == "list": - # List attached devices. - for p in sorted(serial.tools.list_ports.comports()): - print( - "{} {} {:04x}:{:04x} {} {}".format( - p.device, - p.serial_number, - p.vid if isinstance(p.vid, int) else 0, - p.pid if isinstance(p.pid, int) else 0, - p.manufacturer, - p.product, - ) - ) - return None - elif dev == "auto": - # Auto-detect and auto-connect to the first available device. - for p in sorted(serial.tools.list_ports.comports()): - try: - return pyboard.PyboardExtended(p.device, baudrate=115200) - except pyboard.PyboardError as er: - if not er.args[0].startswith("failed to access"): - raise er - raise pyboard.PyboardError("no device found") - elif dev.startswith("id:"): - # Search for a device with the given serial number. - serial_number = dev[len("id:") :] - dev = None - for p in serial.tools.list_ports.comports(): - if p.serial_number == serial_number: - return pyboard.PyboardExtended(p.device, baudrate=115200) - raise pyboard.PyboardError("no device with serial number {}".format(serial_number)) - else: - # Connect to the given device. - if dev.startswith("port:"): - dev = dev[len("port:") :] - return pyboard.PyboardExtended(dev, baudrate=115200) - except pyboard.PyboardError as er: - msg = er.args[0] - if msg.startswith("failed to access"): - msg += " (it may be in use by another program)" - print(msg) - sys.exit(1) +class State: + def __init__(self): + self.pyb = None + self._did_action = False + self._auto_soft_reset = True + def did_action(self): + self._did_action = True -def do_disconnect(pyb): - try: - if pyb.mounted: - if not pyb.in_raw_repl: - pyb.enter_raw_repl(soft_reset=False) - pyb.umount_local() - if pyb.in_raw_repl: - pyb.exit_raw_repl() - except OSError: - # Ignore any OSError exceptions when shutting down, eg: - # - pyboard.filesystem_command will close the connecton if it had an error - # - umounting will fail if serial port disappeared - pass - pyb.close() - - -def show_progress_bar(size, total_size): - if not sys.stdout.isatty(): - return - verbose_size = 2048 - bar_length = 20 - if total_size < verbose_size: - return - elif size >= total_size: - # Clear progress bar when copy completes - print("\r" + " " * (20 + bar_length) + "\r", end="") - else: - progress = size / total_size - bar = round(progress * bar_length) - print( - "\r ... copying {:3.0f}% [{}{}]".format( - progress * 100, "#" * bar, "-" * (bar_length - bar) - ), - end="", - ) - - -# Get all args up to the terminator ("+"). -# The passed args will be updated with these ones removed. -def get_fs_args(args): - n = 0 - for src in args: - if src == "+": - break - n += 1 - fs_args = args[:n] - args[:] = args[n + 1 :] - return fs_args - - -def do_filesystem(pyb, args): - def _list_recursive(files, path): - if os.path.isdir(path): - for entry in os.listdir(path): - _list_recursive(files, "/".join((path, entry))) - else: - files.append(os.path.split(path)) - - fs_args = get_fs_args(args) - - # Don't be verbose when using cat, so output can be redirected to something. - verbose = fs_args[0] != "cat" - - if fs_args[0] == "cp" and fs_args[1] == "-r": - fs_args.pop(0) - fs_args.pop(0) - if fs_args[-1] != ":": - print(f"{_PROG}: 'cp -r' destination must be ':'") - sys.exit(1) - fs_args.pop() - src_files = [] - for path in fs_args: - if path.startswith(":"): - print(f"{_PROG}: 'cp -r' source files must be local") - sys.exit(1) - _list_recursive(src_files, path) - known_dirs = {""} - pyb.exec_("import uos") - for dir, file in src_files: - dir_parts = dir.split("/") - for i in range(len(dir_parts)): - d = "/".join(dir_parts[: i + 1]) - if d not in known_dirs: - pyb.exec_("try:\n uos.mkdir('%s')\nexcept OSError as e:\n print(e)" % d) - known_dirs.add(d) - pyboard.filesystem_command( - pyb, - ["cp", "/".join((dir, file)), ":" + dir + "/"], - progress_callback=show_progress_bar, - verbose=verbose, - ) - else: - try: - pyboard.filesystem_command( - pyb, fs_args, progress_callback=show_progress_bar, verbose=verbose - ) - except OSError as er: - print(f"{_PROG}: {er}") - sys.exit(1) - - -def do_edit(pyb, args): - if not os.getenv("EDITOR"): - raise pyboard.PyboardError("edit: $EDITOR not set") - for src in get_fs_args(args): - src = src.lstrip(":") - dest_fd, dest = tempfile.mkstemp(suffix=os.path.basename(src)) - try: - print("edit :%s" % (src,)) - os.close(dest_fd) - pyb.fs_touch(src) - pyb.fs_get(src, dest, progress_callback=show_progress_bar) - if os.system("$EDITOR '%s'" % (dest,)) == 0: - pyb.fs_put(dest, src, progress_callback=show_progress_bar) - finally: - os.unlink(dest) - - -def do_repl_main_loop(pyb, console_in, console_out_write, *, code_to_inject, file_to_inject): - while True: - console_in.waitchar(pyb.serial) - c = console_in.readchar() - if c: - if c == b"\x1d": # ctrl-], quit - break - elif c == b"\x04": # ctrl-D - # special handling needed for ctrl-D if filesystem is mounted - pyb.write_ctrl_d(console_out_write) - elif c == b"\x0a" and code_to_inject is not None: # ctrl-j, inject code - pyb.serial.write(code_to_inject) - elif c == b"\x0b" and file_to_inject is not None: # ctrl-k, inject script - console_out_write(bytes("Injecting %s\r\n" % file_to_inject, "utf8")) - pyb.enter_raw_repl(soft_reset=False) - with open(file_to_inject, "rb") as f: - pyfile = f.read() - try: - pyb.exec_raw_no_follow(pyfile) - except pyboard.PyboardError as er: - console_out_write(b"Error:\r\n") - console_out_write(er) - pyb.exit_raw_repl() - else: - pyb.serial.write(c) - - try: - n = pyb.serial.inWaiting() - except OSError as er: - if er.args[0] == 5: # IO error, device disappeared - print("device disconnected") - break - - if n > 0: - c = pyb.serial.read(1) - if c is not None: - # pass character through to the console - oc = ord(c) - if oc in (8, 9, 10, 13, 27) or 32 <= oc <= 126: - console_out_write(c) - else: - console_out_write(b"[%02x]" % ord(c)) - - -def do_repl(pyb, args): - capture_file = None - code_to_inject = None - file_to_inject = None - - while len(args): - if args[0] == "--capture": - args.pop(0) - capture_file = args.pop(0) - elif args[0] == "--inject-code": - args.pop(0) - code_to_inject = bytes(args.pop(0).replace("\\n", "\r\n"), "utf8") - elif args[0] == "--inject-file": - args.pop(0) - file_to_inject = args.pop(0) - else: - break - - print("Connected to MicroPython at %s" % pyb.device_name) - print("Use Ctrl-] to exit this shell") - if capture_file is not None: - print('Capturing session to file "%s"' % capture_file) - capture_file = open(capture_file, "wb") - if code_to_inject is not None: - print("Use Ctrl-J to inject", code_to_inject) - if file_to_inject is not None: - print('Use Ctrl-K to inject file "%s"' % file_to_inject) - - console = Console() - console.enter() - - def console_out_write(b): - console.write(b) - if capture_file is not None: - capture_file.write(b) - capture_file.flush() + def run_repl_on_completion(self): + return not self._did_action - try: - do_repl_main_loop( - pyb, - console, - console_out_write, - code_to_inject=code_to_inject, - file_to_inject=file_to_inject, - ) - finally: - console.exit() - if capture_file is not None: - capture_file.close() + def ensure_connected(self): + if self.pyb is None: + do_connect(self, ["auto"]) + def ensure_raw_repl(self, soft_reset=None): + self.ensure_connected() + soft_reset = self._auto_soft_reset if soft_reset is None else soft_reset + if soft_reset or not self.pyb.in_raw_repl: + self.pyb.enter_raw_repl(soft_reset=soft_reset) + self._auto_soft_reset = False -def execbuffer(pyb, buf, follow): - ret_val = 0 - try: - pyb.exec_raw_no_follow(buf) - if follow: - ret, ret_err = pyb.follow(timeout=None, data_consumer=pyboard.stdout_write_bytes) - if ret_err: - pyboard.stdout_write_bytes(ret_err) - ret_val = 1 - except pyboard.PyboardError as er: - print(er) - ret_val = 1 - except KeyboardInterrupt: - ret_val = 1 - return ret_val - - -def print_help(): - def print_commands_help(cmds, help_idx): - max_command_len = max(len(cmd) for cmd in cmds.keys()) - for cmd in sorted(cmds.keys()): - help_message_lines = dedent(cmds[cmd][help_idx]).split("\n") - help_message = help_message_lines[0] - for line in help_message_lines[1:]: - help_message = "{}\n{}{}".format(help_message, " " * (max_command_len + 4), line) - print(" ", cmd, " " * (max_command_len - len(cmd) + 2), help_message, sep="") - - print(_PROG, "-- MicroPython remote control") - print("See https://docs.micropython.org/en/latest/reference/mpremote.html") - - print("\nList of commands:") - print_commands_help(_COMMANDS, 3) - - print("\nList of shortcuts:") - print_commands_help(_command_expansions, 2) - - -def print_version(): - from . import __version__ - - print(f"{_PROG} {__version__}") + def ensure_friendly_repl(self): + self.ensure_connected() + if self.pyb.in_raw_repl: + self.pyb.exit_raw_repl() def main(): @@ -528,106 +342,31 @@ def main(): prepare_command_expansions(config) args = sys.argv[1:] - pyb = None - auto_soft_reset = True - did_action = False + state = State() try: while args: do_command_expansion(args) cmd = args.pop(0) try: - need_raw_repl, is_action, num_args_min, _ = _COMMANDS[cmd] + num_args_min, _help, handler = _COMMANDS[cmd] except KeyError: - print(f"{_PROG}: '{cmd}' is not a command") - return 1 + raise CommandError(f"'{cmd}' is not a command") if len(args) < num_args_min: print(f"{_PROG}: '{cmd}' neads at least {num_args_min} argument(s)") return 1 - if cmd == "connect": - if pyb is not None: - do_disconnect(pyb) - pyb = do_connect(args) - if pyb is None: - did_action = True - continue - elif cmd == "help": - print_help() - sys.exit(0) - elif cmd == "version": - print_version() - sys.exit(0) - elif cmd == "resume": - auto_soft_reset = False - continue - - # The following commands need a connection, and either a raw or friendly REPL. - - if pyb is None: - pyb = do_connect(["auto"]) - - if need_raw_repl: - if not pyb.in_raw_repl: - pyb.enter_raw_repl(soft_reset=auto_soft_reset) - auto_soft_reset = False - else: - if pyb.in_raw_repl: - pyb.exit_raw_repl() - if is_action: - did_action = True - - if cmd == "disconnect": - do_disconnect(pyb) - pyb = None - auto_soft_reset = True - elif cmd == "soft-reset": - pyb.enter_raw_repl(soft_reset=True) - auto_soft_reset = False - elif cmd == "mount": - unsafe_links = False - if args[0] == "--unsafe-links" or args[0] == "-l": - args.pop(0) - unsafe_links = True - path = args.pop(0) - pyb.mount_local(path, unsafe_links=unsafe_links) - print(f"Local directory {path} is mounted at /remote") - elif cmd == "umount": - pyb.umount_local() - elif cmd in ("exec", "eval", "run"): - follow = True - if args[0] == "--no-follow": - args.pop(0) - follow = False - if cmd == "exec": - buf = args.pop(0) - elif cmd == "eval": - buf = "print(" + args.pop(0) + ")" - else: - filename = args.pop(0) - try: - with open(filename, "rb") as f: - buf = f.read() - except OSError: - print(f"{_PROG}: could not read file '{filename}'") - return 1 - ret = execbuffer(pyb, buf, follow) - if ret: - return ret - elif cmd == "fs": - do_filesystem(pyb, args) - elif cmd == "edit": - do_edit(pyb, args) - elif cmd == "repl": - do_repl(pyb, args) - - if not did_action: - if pyb is None: - pyb = do_connect(["auto"]) - if pyb.in_raw_repl: - pyb.exit_raw_repl() - do_repl(pyb, args) + handler(state, args) + + + # If no commands were "actions" then implicitly finish with the REPL. + if state.run_repl_on_completion(): + do_repl(state, args) + + return 0 + except CommandError as e: + print(f"{_PROG}: {e}", file=sys.stderr) + return 1 finally: - if pyb is not None: - do_disconnect(pyb) + do_disconnect(state) diff --git a/tools/mpremote/mpremote/repl.py b/tools/mpremote/mpremote/repl.py new file mode 100644 index 000000000000..f92d20ae7972 --- /dev/null +++ b/tools/mpremote/mpremote/repl.py @@ -0,0 +1,101 @@ +from .console import Console, ConsolePosix + +from . import pyboardextended as pyboard + + +def do_repl_main_loop(state, console_in, console_out_write, *, code_to_inject, file_to_inject): + while True: + console_in.waitchar(state.pyb.serial) + c = console_in.readchar() + if c: + if c == b"\x1d": # ctrl-], quit + break + elif c == b"\x04": # ctrl-D + # special handling needed for ctrl-D if filesystem is mounted + state.pyb.write_ctrl_d(console_out_write) + elif c == b"\x0a" and code_to_inject is not None: # ctrl-j, inject code + state.pyb.serial.write(code_to_inject) + elif c == b"\x0b" and file_to_inject is not None: # ctrl-k, inject script + console_out_write(bytes("Injecting %s\r\n" % file_to_inject, "utf8")) + state.pyb.enter_raw_repl(soft_reset=False) + with open(file_to_inject, "rb") as f: + pyfile = f.read() + try: + state.pyb.exec_raw_no_follow(pyfile) + except pyboard.PyboardError as er: + console_out_write(b"Error:\r\n") + console_out_write(er) + state.pyb.exit_raw_repl() + else: + state.pyb.serial.write(c) + + try: + n = state.pyb.serial.inWaiting() + except OSError as er: + if er.args[0] == 5: # IO error, device disappeared + print("device disconnected") + break + + if n > 0: + c = state.pyb.serial.read(1) + if c is not None: + # pass character through to the console + oc = ord(c) + if oc in (8, 9, 10, 13, 27) or 32 <= oc <= 126: + console_out_write(c) + else: + console_out_write(b"[%02x]" % ord(c)) + + +def do_repl(state, args): + state.ensure_friendly_repl() + state.did_action() + + capture_file = None + code_to_inject = None + file_to_inject = None + + while len(args): + if args[0] == "--capture": + args.pop(0) + capture_file = args.pop(0) + elif args[0] == "--inject-code": + args.pop(0) + code_to_inject = bytes(args.pop(0).replace("\\n", "\r\n"), "utf8") + elif args[0] == "--inject-file": + args.pop(0) + file_to_inject = args.pop(0) + else: + break + + print("Connected to MicroPython at %s" % state.pyb.device_name) + print("Use Ctrl-] to exit this shell") + if capture_file is not None: + print('Capturing session to file "%s"' % capture_file) + capture_file = open(capture_file, "wb") + if code_to_inject is not None: + print("Use Ctrl-J to inject", code_to_inject) + if file_to_inject is not None: + print('Use Ctrl-K to inject file "%s"' % file_to_inject) + + console = Console() + console.enter() + + def console_out_write(b): + console.write(b) + if capture_file is not None: + capture_file.write(b) + capture_file.flush() + + try: + do_repl_main_loop( + state, + console, + console_out_write, + code_to_inject=code_to_inject, + file_to_inject=file_to_inject, + ) + finally: + console.exit() + if capture_file is not None: + capture_file.close() From 68d094358ec71aa8cdec97e9e6fc3c6d46dedfbf Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 30 Sep 2022 14:36:39 +1000 Subject: [PATCH 1789/4290] tools/mpremote: Use argparse for command line parsing. No functional change other than to allow slightly more flexibility in how --foo arguments are specified. This removes all custom handling for --foo args in all commands and replaces it with per-command argparse configs. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- tools/mpremote/mpremote/commands.py | 78 ++++------ tools/mpremote/mpremote/main.py | 224 ++++++++++++++++++++-------- tools/mpremote/mpremote/repl.py | 19 +-- 3 files changed, 193 insertions(+), 128 deletions(-) diff --git a/tools/mpremote/mpremote/commands.py b/tools/mpremote/mpremote/commands.py index 60a625d5e854..bf56df69993a 100644 --- a/tools/mpremote/mpremote/commands.py +++ b/tools/mpremote/mpremote/commands.py @@ -10,6 +10,9 @@ class CommandError(Exception): pass + +def do_connect(state, args=None): + dev = args.device[0] if args else "auto" do_disconnect(state) try: @@ -101,19 +104,6 @@ def show_progress_bar(size, total_size, op="copying"): ) -# Get all args up to the terminator ("+"). -# The passed args will be updated with these ones removed. -def _get_fs_args(args): - n = 0 - for src in args: - if src == "+": - break - n += 1 - fs_args = args[:n] - args[:] = args[n + 1 :] - return fs_args - - def do_filesystem(state, args): state.ensure_raw_repl() state.did_action() @@ -125,20 +115,22 @@ def _list_recursive(files, path): else: files.append(os.path.split(path)) - fs_args = _get_fs_args(args) + command = args.command[0] + paths = args.path - # Don't be verbose when using cat, so output can be redirected to something. - verbose = fs_args[0] != "cat" + if command == "cat": + # Don't be verbose by default when using cat, so output can be + # redirected to something. + verbose = args.verbose == True + else: + verbose = args.verbose != False - if fs_args[0] == "cp" and fs_args[1] == "-r": - fs_args.pop(0) - fs_args.pop(0) - if fs_args[-1] != ":": - print(f"{_PROG}: 'cp -r' destination must be ':'") - sys.exit(1) - fs_args.pop() + if command == "cp" and args.recursive: + if paths[-1] != ":": + raise CommandError("'cp -r' destination must be ':'") + paths.pop() src_files = [] - for path in fs_args: + for path in paths: if path.startswith(":"): raise CommandError("'cp -r' source files must be local") _list_recursive(src_files, path) @@ -158,9 +150,11 @@ def _list_recursive(files, path): verbose=verbose, ) else: + if args.recursive: + raise CommandError("'-r' only supported for 'cp'") try: pyboard.filesystem_command( - state.pyb, fs_args, progress_callback=show_progress_bar, verbose=verbose + state.pyb, [command] + paths, progress_callback=show_progress_bar, verbose=verbose ) except OSError as er: raise CommandError(er) @@ -172,7 +166,7 @@ def do_edit(state, args): if not os.getenv("EDITOR"): raise pyboard.PyboardError("edit: $EDITOR not set") - for src in _get_fs_args(args): + for src in args.files: src = src.lstrip(":") dest_fd, dest = tempfile.mkstemp(suffix=os.path.basename(src)) try: @@ -186,14 +180,6 @@ def do_edit(state, args): os.unlink(dest) -def _get_follow_arg(args): - if args[0] == "--no-follow": - args.pop(0) - return False - else: - return True - - def _do_execbuffer(state, buf, follow): state.ensure_raw_repl() state.did_action() @@ -213,38 +199,28 @@ def _do_execbuffer(state, buf, follow): def do_exec(state, args): - follow = _get_follow_arg(args) - buf = args.pop(0) - _do_execbuffer(state, buf, follow) + _do_execbuffer(state, args.expr[0], args.follow) def do_eval(state, args): - follow = _get_follow_arg(args) - buf = "print(" + args.pop(0) + ")" - _do_execbuffer(state, buf, follow) + buf = "print(" + args.expr[0] + ")" + _do_execbuffer(state, buf, args.follow) def do_run(state, args): - follow = _get_follow_arg(args) - filename = args.pop(0) + filename = args.path[0] try: with open(filename, "rb") as f: buf = f.read() except OSError: raise CommandError(f"could not read file '{filename}'") - sys.exit(1) - _do_execbuffer(state, buf, follow) + _do_execbuffer(state, buf, args.follow) def do_mount(state, args): state.ensure_raw_repl() - - unsafe_links = False - if args[0] == "--unsafe-links" or args[0] == "-l": - args.pop(0) - unsafe_links = True - path = args.pop(0) - state.pyb.mount_local(path, unsafe_links=unsafe_links) + path = args.path[0] + state.pyb.mount_local(path, unsafe_links=args.unsafe_links) print(f"Local directory {path} is mounted at /remote") diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index b96e3f46b1bf..17d2b3373834 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -17,6 +17,7 @@ mpremote repl -- enter REPL """ +import argparse import os, sys from collections.abc import Mapping from textwrap import dedent @@ -41,10 +42,10 @@ def do_help(state, _args=None): - def print_commands_help(cmds, help_idx): + def print_commands_help(cmds, help_key): max_command_len = max(len(cmd) for cmd in cmds.keys()) for cmd in sorted(cmds.keys()): - help_message_lines = dedent(cmds[cmd][help_idx]).split("\n") + help_message_lines = dedent(help_key(cmds[cmd])).split("\n") help_message = help_message_lines[0] for line in help_message_lines[1:]: help_message = "{}\n{}{}".format(help_message, " " * (max_command_len + 4), line) @@ -54,10 +55,12 @@ def print_commands_help(cmds, help_idx): print("See https://docs.micropython.org/en/latest/reference/mpremote.html") print("\nList of commands:") - print_commands_help(_COMMANDS, 1) + print_commands_help( + _COMMANDS, lambda x: x[1]().description + ) # extract description from argparse print("\nList of shortcuts:") - print_commands_help(_command_expansions, 2) + print_commands_help(_command_expansions, lambda x: x[2]) # (args, sub, help_message) sys.exit(0) @@ -69,89 +72,157 @@ def do_version(state, _args=None): sys.exit(0) -# Map of "command" to tuple of (num_args_min, help_text, handler). +def _bool_flag(cmd_parser, name, short_name, default, description): + # In Python 3.9+ this can be replaced with argparse.BooleanOptionalAction. + group = cmd_parser.add_mutually_exclusive_group() + group.add_argument( + "--" + name, + "-" + short_name, + action="store_true", + default=default, + help=description, + ) + group.add_argument( + "--no-" + name, + action="store_false", + dest=name, + ) + + +def argparse_connect(): + cmd_parser = argparse.ArgumentParser(description="connect to given device") + cmd_parser.add_argument( + "device", nargs=1, help="Either list, auto, id:x, port:x, or any valid device name/path" + ) + return cmd_parser + + +def argparse_edit(): + cmd_parser = argparse.ArgumentParser(description="edit files on the device") + cmd_parser.add_argument("files", nargs="+", help="list of remote paths") + return cmd_parser + + +def argparse_mount(): + cmd_parser = argparse.ArgumentParser(description="mount local directory on device") + _bool_flag( + cmd_parser, + "unsafe-links", + "l", + False, + "follow symbolic links pointing outside of local directory", + ) + cmd_parser.add_argument("path", nargs=1, help="local path to mount") + return cmd_parser + + +def argparse_repl(): + cmd_parser = argparse.ArgumentParser(description="connect to given device") + cmd_parser.add_argument("--capture", type=str, required=False, help="TODO") + cmd_parser.add_argument("--inject-code", type=str, required=False, help="TODO") + cmd_parser.add_argument("--inject-file", type=str, required=False, help="TODO") + return cmd_parser + + +def argparse_eval(): + cmd_parser = argparse.ArgumentParser(description="evaluate and print the string") + _bool_flag(cmd_parser, "follow", "f", True, "TODO") + cmd_parser.add_argument("expr", nargs=1, help="expression to execute") + return cmd_parser + + +def argparse_exec(): + cmd_parser = argparse.ArgumentParser(description="execute the string") + _bool_flag(cmd_parser, "follow", "f", True, "TODO") + cmd_parser.add_argument("expr", nargs=1, help="expression to execute") + return cmd_parser + + +def argparse_run(): + cmd_parser = argparse.ArgumentParser(description="run the given local script") + _bool_flag(cmd_parser, "follow", "f", False, "TODO") + cmd_parser.add_argument("path", nargs=1, help="expression to execute") + return cmd_parser + + +def argparse_filesystem(): + cmd_parser = argparse.ArgumentParser(description="execute filesystem commands on the device") + _bool_flag(cmd_parser, "recursive", "r", False, "recursive copy (for cp command only)") + _bool_flag( + cmd_parser, + "verbose", + "v", + None, + "enable verbose output (defaults to True for all commands except cat)", + ) + cmd_parser.add_argument( + "command", nargs=1, help="filesystem command (e.g. cat, cp, ls, rm, touch)" + ) + cmd_parser.add_argument("path", nargs="+", help="local and remote paths") + return cmd_parser + + +def argparse_none(description): + return lambda: argparse.ArgumentParser(description=description) + + +# Map of "command" to tuple of (handler_func, argparse_func). _COMMANDS = { "connect": ( - 1, - """\ - connect to given device - device may be: list, auto, id:x, port:x - or any valid device name/path""", do_connect, + argparse_connect, ), "disconnect": ( - 0, - "disconnect current device", do_disconnect, + argparse_none("disconnect current device"), ), "edit": ( - 1, - "edit files on the device", do_edit, + argparse_edit, ), "resume": ( - 0, - "resume a previous mpremote session (will not auto soft-reset)", do_resume, + argparse_none("resume a previous mpremote session (will not auto soft-reset)"), ), "soft-reset": ( - 0, - "perform a soft-reset of the device", do_soft_reset, + argparse_none("perform a soft-reset of the device"), ), "mount": ( - 1, - """\ - mount local directory on device - options: - --unsafe-links, -l - follow symbolic links pointing outside of local directory""", do_mount, + argparse_mount, ), "umount": ( - 0, - "unmount the local directory", do_umount, + argparse_none("unmount the local directory"), ), "repl": ( - 0, - """\ - enter REPL - options: - --capture - --inject-code - --inject-file """, do_repl, + argparse_repl, ), "eval": ( - 1, - "evaluate and print the string", do_eval, + argparse_eval, ), "exec": ( - 1, - "execute the string", do_exec, + argparse_exec, ), "run": ( - 1, - "run the given local script", do_run, + argparse_run, ), "fs": ( - 1, - "execute filesystem commands on the device", do_filesystem, + argparse_filesystem, ), "help": ( - 0, - "print help and exit", do_help, + argparse_none("print help and exit"), ), "version": ( - 0, - "print version and exit", do_version, + argparse_none("print version and exit"), ), } @@ -301,7 +372,6 @@ def usage_error(cmd, exp_args, msg): # Extra unknown arguments given. arg = args[last_arg_idx].split("=", 1)[0] usage_error(cmd, exp_args, f"given unexpected argument {arg}") - sys.exit(1) # Insert expansion with optional setting of arguments. if pre: @@ -322,7 +392,7 @@ def run_repl_on_completion(self): def ensure_connected(self): if self.pyb is None: - do_connect(self, ["auto"]) + do_connect(self) def ensure_raw_repl(self, soft_reset=None): self.ensure_connected() @@ -341,28 +411,60 @@ def main(): config = load_user_config() prepare_command_expansions(config) - args = sys.argv[1:] + remaining_args = sys.argv[1:] state = State() try: - while args: - do_command_expansion(args) - cmd = args.pop(0) + while remaining_args: + # Skip the terminator. + if remaining_args[0] == "+": + remaining_args.pop(0) + continue + + # Rewrite the front of the list with any matching expansion. + do_command_expansion(remaining_args) + + # The (potentially rewritten) command must now be a base command. + cmd = remaining_args.pop(0) try: - num_args_min, _help, handler = _COMMANDS[cmd] + handler_func, parser_func = _COMMANDS[cmd] except KeyError: raise CommandError(f"'{cmd}' is not a command") - if len(args) < num_args_min: - print(f"{_PROG}: '{cmd}' neads at least {num_args_min} argument(s)") - return 1 - - handler(state, args) - - - # If no commands were "actions" then implicitly finish with the REPL. + # If this command (or any down the chain) has a terminator, then + # limit the arguments passed for this command. They will be added + # back after processing this command. + try: + terminator = remaining_args.index("+") + command_args = remaining_args[:terminator] + extra_args = remaining_args[terminator:] + except ValueError: + command_args = remaining_args + extra_args = [] + + # Special case: "fs ls" allowed have no path specified. + if cmd == "fs" and len(command_args) == 1 and command_args[0] == "ls": + command_args.append("") + + # Use the command-specific argument parser. + cmd_parser = parser_func() + cmd_parser.prog = cmd + # Catch all for unhandled positional arguments (this is the next command). + cmd_parser.add_argument( + "next_command", nargs=argparse.REMAINDER, help=f"Next {_PROG} command" + ) + args = cmd_parser.parse_args(command_args) + + # Execute command. + handler_func(state, args) + + # Get any leftover unprocessed args. + remaining_args = args.next_command + extra_args + + # If no commands were "actions" then implicitly finish with the REPL + # using default args. if state.run_repl_on_completion(): - do_repl(state, args) + do_repl(state, argparse_repl().parse_args([])) return 0 except CommandError as e: diff --git a/tools/mpremote/mpremote/repl.py b/tools/mpremote/mpremote/repl.py index f92d20ae7972..7da00c0fdef0 100644 --- a/tools/mpremote/mpremote/repl.py +++ b/tools/mpremote/mpremote/repl.py @@ -51,22 +51,9 @@ def do_repl(state, args): state.ensure_friendly_repl() state.did_action() - capture_file = None - code_to_inject = None - file_to_inject = None - - while len(args): - if args[0] == "--capture": - args.pop(0) - capture_file = args.pop(0) - elif args[0] == "--inject-code": - args.pop(0) - code_to_inject = bytes(args.pop(0).replace("\\n", "\r\n"), "utf8") - elif args[0] == "--inject-file": - args.pop(0) - file_to_inject = args.pop(0) - else: - break + capture_file = args.capture + code_to_inject = args.inject_code + file_to_inject = args.inject_file print("Connected to MicroPython at %s" % state.pyb.device_name) print("Use Ctrl-] to exit this shell") From 12ca918eb2ac062f6e6df0772e528eef9d050cb7 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 29 Sep 2022 00:45:34 +1000 Subject: [PATCH 1790/4290] tools/mpremote: Add `mpremote mip install` to install packages. This supports the same package sources as the new `mip` tool. - micropython-lib (by name) - http(s) & github packages with json description - directly downloading a .py/.mpy file The version is specified with an optional `@version` on the end of the package name. The target dir, index, and mpy/no-mpy can be set through command line args. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- docs/reference/mpremote.rst | 14 +++ docs/reference/packages.rst | 16 +-- tools/mpremote/README.md | 41 ++++--- tools/mpremote/mpremote/main.py | 28 +++++ tools/mpremote/mpremote/mip.py | 191 ++++++++++++++++++++++++++++++++ tools/pyboard.py | 7 ++ 6 files changed, 272 insertions(+), 25 deletions(-) create mode 100644 tools/mpremote/mpremote/mip.py diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index e3902f8e5d7e..bb0686237abd 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -146,6 +146,14 @@ The full list of supported commands are: variable ``$EDITOR``). If the editor exits successfully, the updated file will be copied back to the device. +- install packages from :term:`micropython-lib` (or GitHub) using the ``mip`` tool: + + .. code-block:: bash + + $ mpremote mip install + + See :ref:`packages` for more information. + - mount the local directory on the remote device: .. code-block:: bash @@ -269,3 +277,9 @@ Examples mpremote cp -r dir/ : mpremote cp a.py b.py : + repl + + mpremote mip install aioble + + mpremote mip install github:org/repo@branch + + mpremote mip install --target /flash/third-party functools diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index 0c049d1fb2fc..1ddbecb582b4 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -78,17 +78,17 @@ The :term:`mpremote` tool also includes the same functionality as ``mip`` and can be used from a host PC to install packages to a locally connected device (e.g. via USB or UART):: - $ mpremote install pkgname - $ mpremote install pkgname@x.y - $ mpremote install http://example.com/x/y/foo.py - $ mpremote install github:org/repo - $ mpremote install github:org/repo@branch-or-tag + $ mpremote mip install pkgname + $ mpremote mip install pkgname@x.y + $ mpremote mip install http://example.com/x/y/foo.py + $ mpremote mip install github:org/repo + $ mpremote mip install github:org/repo@branch-or-tag The ``--target=path``, ``--no-mpy``, and ``--index`` arguments can be set:: - $ mpremote install --target=/flash/third-party pkgname - $ mpremote install --no-mpy pkgname - $ mpremote install --index https://host/pi pkgname + $ mpremote mip install --target=/flash/third-party pkgname + $ mpremote mip install --no-mpy pkgname + $ mpremote mip install --index https://host/pi pkgname Installing packages manually ---------------------------- diff --git a/tools/mpremote/README.md b/tools/mpremote/README.md index c294b2081182..7f58788fbe4c 100644 --- a/tools/mpremote/README.md +++ b/tools/mpremote/README.md @@ -11,23 +11,28 @@ This will automatically connect to the device and provide an interactive REPL. The full list of supported commands are: - mpremote connect -- connect to given device - device may be: list, auto, id:x, port:x - or any valid device name/path - mpremote disconnect -- disconnect current device - mpremote mount -- mount local directory on device - mpremote eval -- evaluate and print the string - mpremote exec -- execute the string - mpremote run -- run the given local script - mpremote fs -- execute filesystem commands on the device - command may be: cat, ls, cp, rm, mkdir, rmdir - use ":" as a prefix to specify a file on the device - mpremote repl -- enter REPL - options: - --capture - --inject-code - --inject-file - mpremote help -- print list of commands and exit + mpremote connect -- connect to given device + device may be: list, auto, id:x, port:x + or any valid device name/path + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run -- run the given local script + mpremote fs -- execute filesystem commands on the device + command may be: cat, ls, cp, rm, mkdir, rmdir + use ":" as a prefix to specify a file on the device + mpremote repl -- enter REPL + options: + --capture + --inject-code + --inject-file + mpremote mip install -- Install packages (from micropython-lib or third-party sources) + options: + --target + --index + --no-mpy + mpremote help -- print list of commands and exit Multiple commands can be specified and they will be run sequentially. Connection and disconnection will be done automatically at the start and end of the execution @@ -73,3 +78,5 @@ Examples: mpremote cp :main.py . mpremote cp main.py : mpremote cp -r dir/ : + mpremote mip install aioble + mpremote mip install github:org/repo@branch diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index 17d2b3373834..4f541685a0cf 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -36,6 +36,7 @@ do_resume, do_soft_reset, ) +from .mip import do_mip from .repl import do_repl _PROG = "mpremote" @@ -162,6 +163,29 @@ def argparse_filesystem(): return cmd_parser +def argparse_mip(): + cmd_parser = argparse.ArgumentParser( + description="install packages from micropython-lib or third-party sources" + ) + _bool_flag(cmd_parser, "mpy", "m", True, "download as compiled .mpy files (default)") + cmd_parser.add_argument( + "--target", type=str, required=False, help="destination direction on the device" + ) + cmd_parser.add_argument( + "--index", + type=str, + required=False, + help="package index to use (defaults to micropython-lib)", + ) + cmd_parser.add_argument("command", nargs=1, help="mip command (e.g. install)") + cmd_parser.add_argument( + "packages", + nargs="+", + help="list package specifications, e.g. name, name@version, github:org/repo, github:org/repo@branch", + ) + return cmd_parser + + def argparse_none(description): return lambda: argparse.ArgumentParser(description=description) @@ -216,6 +240,10 @@ def argparse_none(description): do_filesystem, argparse_filesystem, ), + "mip": ( + do_mip, + argparse_mip, + ), "help": ( do_help, argparse_none("print help and exit"), diff --git a/tools/mpremote/mpremote/mip.py b/tools/mpremote/mpremote/mip.py new file mode 100644 index 000000000000..99ca9ff7e387 --- /dev/null +++ b/tools/mpremote/mpremote/mip.py @@ -0,0 +1,191 @@ +# Micropython package installer +# Ported from micropython-lib/micropython/mip/mip.py. +# MIT license; Copyright (c) 2022 Jim Mussared + +import urllib.error +import urllib.request +import json +import tempfile +import os + +from .commands import CommandError, show_progress_bar + + +_PACKAGE_INDEX = "https://micropython.org/pi/v2" +_CHUNK_SIZE = 128 + + +# This implements os.makedirs(os.dirname(path)) +def _ensure_path_exists(pyb, path): + import os + + split = path.split("/") + + # Handle paths starting with "/". + if not split[0]: + split.pop(0) + split[0] = "/" + split[0] + + prefix = "" + for i in range(len(split) - 1): + prefix += split[i] + if not pyb.fs_exists(prefix): + pyb.fs_mkdir(prefix) + prefix += "/" + + +# Copy from src (stream) to dest (function-taking-bytes) +def _chunk(src, dest, length=None, op="downloading"): + buf = memoryview(bytearray(_CHUNK_SIZE)) + total = 0 + if length: + show_progress_bar(0, length, op) + while True: + n = src.readinto(buf) + if n == 0: + break + dest(buf if n == _CHUNK_SIZE else buf[:n]) + total += n + if length: + show_progress_bar(total, length, op) + + +def _rewrite_url(url, branch=None): + if not branch: + branch = "HEAD" + if url.startswith("github:"): + url = url[7:].split("/") + url = ( + "https://raw.githubusercontent.com/" + + url[0] + + "/" + + url[1] + + "/" + + branch + + "/" + + "/".join(url[2:]) + ) + return url + + +def _download_file(pyb, url, dest): + try: + with urllib.request.urlopen(url) as src: + fd, path = tempfile.mkstemp() + try: + print("Installing:", dest) + with os.fdopen(fd, "wb") as f: + _chunk(src, f.write, src.length) + _ensure_path_exists(pyb, dest) + pyb.fs_put(path, dest, progress_callback=show_progress_bar) + finally: + os.unlink(path) + except urllib.error.HTTPError as e: + if e.status == 404: + raise CommandError(f"File not found: {url}") + else: + raise CommandError(f"Error {e.status} requesting {url}") + except urllib.error.URLError as e: + raise CommandError(f"{e.reason} requesting {url}") + + +def _install_json(pyb, package_json_url, index, target, version, mpy): + try: + with urllib.request.urlopen(_rewrite_url(package_json_url, version)) as response: + package_json = json.load(response) + except urllib.error.HTTPError as e: + if e.status == 404: + raise CommandError(f"Package not found: {package_json_url}") + else: + raise CommandError(f"Error {e.status} requesting {package_json_url}") + except urllib.error.URLError as e: + raise CommandError(f"{e.reason} requesting {package_json_url}") + for target_path, short_hash in package_json.get("hashes", ()): + fs_target_path = target + "/" + target_path + file_url = f"{index}/file/{short_hash[:2]}/{short_hash}" + _download_file(pyb, file_url, fs_target_path) + for target_path, url in package_json.get("urls", ()): + fs_target_path = target + "/" + target_path + _download_file(pyb, _rewrite_url(url, version), fs_target_path) + for dep, dep_version in package_json.get("deps", ()): + _install_package(pyb, dep, index, target, dep_version, mpy) + + +def _install_package(pyb, package, index, target, version, mpy): + if ( + package.startswith("http://") + or package.startswith("https://") + or package.startswith("github:") + ): + if package.endswith(".py") or package.endswith(".mpy"): + print(f"Downloading {package} to {target}") + _download_file( + pyb, _rewrite_url(package, version), target + "/" + package.rsplit("/")[-1] + ) + return + else: + if not package.endswith(".json"): + if not package.endswith("/"): + package += "/" + package += "package.json" + print(f"Installing {package} to {target}") + else: + if not version: + version = "latest" + print(f"Installing {package} ({version}) from {index} to {target}") + + mpy_version = "py" + if mpy: + pyb.exec("import sys") + mpy_version = ( + int(pyb.eval("getattr(sys.implementation, '_mpy', 0) & 0xFF").decode()) or "py" + ) + + package = f"{index}/package/{mpy_version}/{package}/{version}.json" + + _install_json(pyb, package, index, target, version, mpy) + + +def do_mip(state, args): + state.did_action() + + if args.command[0] == "install": + state.ensure_raw_repl() + + for package in args.packages: + version = None + if "@" in package: + package, version = package.split("@") + + print("Install", package) + + if args.index is None: + args.index = _PACKAGE_INDEX + + if args.target is None: + state.pyb.exec("import sys") + lib_paths = ( + state.pyb.eval("'\\n'.join(p for p in sys.path if p.endswith('/lib'))") + .decode() + .split("\n") + ) + if lib_paths and lib_paths[0]: + args.target = lib_paths[0] + else: + raise CommandError( + "Unable to find lib dir in sys.path, use --target to override" + ) + + if args.mpy is None: + args.mpy = True + + try: + _install_package( + state.pyb, package, args.index.rstrip("/"), args.target, version, args.mpy + ) + except CommandError: + print("Package may be partially installed") + raise + print("Done") + else: + raise CommandError(f"mip: '{args.command[0]}' is not a command") diff --git a/tools/pyboard.py b/tools/pyboard.py index 60cc06508ebe..043f4f06fb87 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -476,6 +476,13 @@ def get_time(self): t = str(self.eval("pyb.RTC().datetime()"), encoding="utf8")[1:-1].split(", ") return int(t[4]) * 3600 + int(t[5]) * 60 + int(t[6]) + def fs_exists(self, src): + try: + self.exec_("import uos\nuos.stat(%s)" % (("'%s'" % src) if src else "")) + return True + except PyboardError: + return False + def fs_ls(self, src): cmd = ( "import uos\nfor f in uos.ilistdir(%s):\n" From 7705b9b9d50b3665de135f314fd1f8cb5d0641f0 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 30 Sep 2022 23:43:23 +1000 Subject: [PATCH 1791/4290] tools/pyboard.py: Handle unsupported fs command. Signed-off-by: Jim Mussared --- tools/pyboard.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 043f4f06fb87..55c00fbca194 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -621,23 +621,28 @@ def fname_cp_dest(src, dest): dest2 = fname_cp_dest(src2, fname_remote(dest)) op(src2, dest2, progress_callback=progress_callback) else: - op = { + ops = { "cat": pyb.fs_cat, "ls": pyb.fs_ls, "mkdir": pyb.fs_mkdir, "rm": pyb.fs_rm, "rmdir": pyb.fs_rmdir, "touch": pyb.fs_touch, - }[cmd] + } + if cmd not in ops: + raise PyboardError("'{}' is not a filesystem command".format(cmd)) if cmd == "ls" and not args: args = [""] for src in args: src = fname_remote(src) if verbose: print("%s :%s" % (cmd, src)) - op(src) + ops[cmd](src) except PyboardError as er: - print(str(er.args[2], "ascii")) + if len(er.args) > 1: + print(str(er.args[2], "ascii")) + else: + print(er) pyb.exit_raw_repl() pyb.close() sys.exit(1) From 0ee877a20732039e603b41c63a221bfc2c8fbde9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 4 Oct 2022 11:47:06 +1100 Subject: [PATCH 1792/4290] esp32/machine_i2s: Add I2S finaliser which calls deinit(). So that the FreeRTOS resources can be freed, eg on soft reset. Fixes issue #9366. Signed-off-by: Damien George --- ports/esp32/machine_i2s.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index eecf71549871..ce1cb59849dc 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -533,7 +533,8 @@ STATIC mp_obj_t machine_i2s_make_new(const mp_obj_type_t *type, size_t n_pos_arg machine_i2s_obj_t *self; if (MP_STATE_PORT(machine_i2s_obj)[port] == NULL) { - self = mp_obj_malloc(machine_i2s_obj_t, &machine_i2s_type); + self = m_new_obj_with_finaliser(machine_i2s_obj_t); + self->base.type = &machine_i2s_type; MP_STATE_PORT(machine_i2s_obj)[port] = self; self->port = port; } else { @@ -688,6 +689,7 @@ STATIC const mp_rom_map_elem_t machine_i2s_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_i2s_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_i2s_irq_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&machine_i2s_deinit_obj) }, // Static method { MP_ROM_QSTR(MP_QSTR_shift), MP_ROM_PTR(&machine_i2s_shift_obj) }, From bdac8272d8b1a726012bec897dc51dacbe70b295 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 29 Aug 2022 16:50:49 +1000 Subject: [PATCH 1793/4290] tools: Add note about uncrustify versions. Uncrustify versions are not mutually compatible: 1. Version 0.73 or newer produce slightly different formatting. It may be possible to tweak these by adding more config items, but this will cause older versions to error out with 'Unknown option'. 2. Version 0.75 prints a range of deprecation warnings due to config file changes, and returns a non-zero exit code. These are actually fixable as most are the default value, and pp_indent has changed from 'true' to '1' which is backwards compatible. However issue 1 remains, so probably better to have it fail explicitly. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- CODECONVENTIONS.md | 4 ++++ tools/uncrustify.cfg | 3 +++ 2 files changed, 7 insertions(+) diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md index 78fb912a6ab7..bceab746182c 100644 --- a/CODECONVENTIONS.md +++ b/CODECONVENTIONS.md @@ -65,6 +65,10 @@ changes to the correct style. Without arguments this tool will reformat all source code (and may take some time to run). Otherwise pass as arguments to the tool the files that changed and it will only reformat those. +**Important**: Use only [uncrustify](https://github.com/uncrustify/uncrustify) +v0.71 or v0.72 for MicroPython. Different uncrustify versions produce slightly +different formatting, and the configuration file formats are often incompatible. + Python code conventions ======================= diff --git a/tools/uncrustify.cfg b/tools/uncrustify.cfg index 221fb458e913..28eb49faf7e7 100644 --- a/tools/uncrustify.cfg +++ b/tools/uncrustify.cfg @@ -1,5 +1,8 @@ # Uncrustify-0.71.0_f +# IMPORTANT: Output is different if using Uncrustify 0.73 or newer, and config file format has changed in newer versions. +# Use version 0.71 or 0.72 to get matching code formatting. + # # General options # From 0e35c4de9b9d55f9288eeb908efd2f7f577dc13b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 29 Aug 2022 17:30:14 +1000 Subject: [PATCH 1794/4290] tools: Add pre-commit support. Tweak the existing codeformat.py and verifygitlog.py to allow them to be easily called by pre-commit. (This turned out to be easier than using any existing pre-commit hooks, without making subtle changes in the formatting.) This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- .pre-commit-config.yaml | 13 ++++++ CODECONVENTIONS.md | 32 ++++++++++++++ tools/codeformat.py | 15 +++++++ tools/verifygitlog.py | 97 ++++++++++++++++++++++++++--------------- 4 files changed, 122 insertions(+), 35 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000000..12f3d79c9353 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: + - repo: local + hooks: + - id: codeformat + name: MicroPython codeformat.py for changed files + entry: tools/codeformat.py -v -f + language: python + - id: verifygitlog + name: MicroPython git commit message format checker + entry: tools/verifygitlog.py --check-file --ignore-rebase + language: python + verbose: true + stages: [commit-msg] diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md index bceab746182c..2daea8431f99 100644 --- a/CODECONVENTIONS.md +++ b/CODECONVENTIONS.md @@ -69,6 +69,38 @@ the tool the files that changed and it will only reformat those. v0.71 or v0.72 for MicroPython. Different uncrustify versions produce slightly different formatting, and the configuration file formats are often incompatible. +Automatic Pre-Commit Hooks +========================== + +To have code formatting and commit message conventions automatically checked +using [pre-commit](https://pre-commit.com/), run the following commands in your +local MicroPython directory: + +``` +$ pip install pre-commit + +$ pre-commit install + +$ pre-commit install --hook-type commit-msg +``` + +pre-commit will now automatically run during `git commit` for both code and +commit message formatting. + +The same formatting checks will be run by CI for any Pull Request submitted to +MicroPython. Pre-commit allows you to see any failure more quickly, and in many +cases will automatically correct it in your local working copy. + +Tips: + +* To skip pre-commit checks on a single commit, use `git commit -n` (for + `--no-verify`). +* To ignore the pre-commit message format check temporarily, start the commit + message subject line with "WIP" (for "Work In Progress"). + +(It is also possible to install pre-commit using Brew or other sources, see +[the docs](https://pre-commit.com/index.html#install) for details.) + Python code conventions ======================= diff --git a/tools/codeformat.py b/tools/codeformat.py index 1c865663a495..13a699065e30 100755 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -151,6 +151,11 @@ def main(): cmd_parser.add_argument("-c", action="store_true", help="Format C code only") cmd_parser.add_argument("-p", action="store_true", help="Format Python code only") cmd_parser.add_argument("-v", action="store_true", help="Enable verbose output") + cmd_parser.add_argument( + "-f", + action="store_true", + help="Filter files provided on the command line against the default list of files to check.", + ) cmd_parser.add_argument("files", nargs="*", help="Run on specific globs") args = cmd_parser.parse_args() @@ -162,6 +167,16 @@ def main(): files = [] if args.files: files = list_files(args.files) + if args.f: + # Filter against the default list of files. This is a little fiddly + # because we need to apply both the inclusion globs given in PATHS + # as well as the EXCLUSIONS, and use absolute paths + files = set(os.path.abspath(f) for f in files) + all_files = set(list_files(PATHS, EXCLUSIONS, TOP)) + if args.v: # In verbose mode, log any files we're skipping + for f in files - all_files: + print("Not checking: {}".format(f)) + files = list(files & all_files) else: files = list_files(PATHS, EXCLUSIONS, TOP) diff --git a/tools/verifygitlog.py b/tools/verifygitlog.py index ce3679125617..f9d98106d6f3 100755 --- a/tools/verifygitlog.py +++ b/tools/verifygitlog.py @@ -7,6 +7,8 @@ verbosity = 0 # Show what's going on, 0 1 or 2. suggestions = 1 # Set to 0 to not include lengthy suggestions in error messages. +ignore_prefixes = [] + def verbose(*args): if verbosity: @@ -18,6 +20,22 @@ def very_verbose(*args): print(*args) +class ErrorCollection: + # Track errors and warnings as the program runs + def __init__(self): + self.has_errors = False + self.has_warnings = False + self.prefix = "" + + def error(self, text): + print("error: {}{}".format(self.prefix, text)) + self.has_errors = True + + def warning(self, text): + print("warning: {}{}".format(self.prefix, text)) + self.has_warnings = True + + def git_log(pretty_format, *args): # Delete pretty argument from user args so it doesn't interfere with what we do. args = ["git", "log"] + [arg for arg in args if "--pretty" not in args] @@ -28,83 +46,88 @@ def git_log(pretty_format, *args): yield line.decode().rstrip("\r\n") -def verify(sha): +def verify(sha, err): verbose("verify", sha) - errors = [] - warnings = [] - - def error_text(err): - return "commit " + sha + ": " + err - - def error(err): - errors.append(error_text(err)) - - def warning(err): - warnings.append(error_text(err)) + err.prefix = "commit " + sha + ": " # Author and committer email. for line in git_log("%ae%n%ce", sha, "-n1"): very_verbose("email", line) if "noreply" in line: - error("Unwanted email address: " + line) + err.error("Unwanted email address: " + line) # Message body. raw_body = list(git_log("%B", sha, "-n1")) + verify_message_body(raw_body, err) + + +def verify_message_body(raw_body, err): if not raw_body: - error("Message is empty") - return errors, warnings + err.error("Message is empty") + return # Subject line. subject_line = raw_body[0] + for prefix in ignore_prefixes: + if subject_line.startswith(prefix): + verbose("Skipping ignored commit message") + return very_verbose("subject_line", subject_line) subject_line_format = r"^[^!]+: [A-Z]+.+ .+\.$" if not re.match(subject_line_format, subject_line): - error("Subject line should match " + repr(subject_line_format) + ": " + subject_line) + err.error("Subject line should match " + repr(subject_line_format) + ": " + subject_line) if len(subject_line) >= 73: - error("Subject line should be 72 or less characters: " + subject_line) + err.error("Subject line should be 72 or less characters: " + subject_line) # Second one divides subject and body. if len(raw_body) > 1 and raw_body[1]: - error("Second message line should be empty: " + raw_body[1]) + err.error("Second message line should be empty: " + raw_body[1]) # Message body lines. for line in raw_body[2:]: # Long lines with URLs are exempt from the line length rule. if len(line) >= 76 and "://" not in line: - error("Message lines should be 75 or less characters: " + line) + err.error("Message lines should be 75 or less characters: " + line) if not raw_body[-1].startswith("Signed-off-by: ") or "@" not in raw_body[-1]: - warning("Message should be signed-off") - - return errors, warnings + err.warning("Message should be signed-off") def run(args): verbose("run", *args) - has_errors = False - has_warnings = False - for sha in git_log("%h", *args): - errors, warnings = verify(sha) - has_errors |= any(errors) - has_warnings |= any(warnings) - for err in errors: - print("error:", err) - for err in warnings: - print("warning:", err) - if has_errors or has_warnings: + + err = ErrorCollection() + + if "--check-file" in args: + filename = args[-1] + verbose("checking commit message from", filename) + with open(args[-1]) as f: + lines = [line.rstrip("\r\n") for line in f] + verify_message_body(lines, err) + else: # Normal operation, pass arguments to git log + for sha in git_log("%h", *args): + verify(sha, err) + + if err.has_errors or err.has_warnings: if suggestions: print("See https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md") else: print("ok") - if has_errors: + if err.has_errors: sys.exit(1) def show_help(): - print("usage: verifygitlog.py [-v -n -h] ...") + print("usage: verifygitlog.py [-v -n -h --check-file] ...") print("-v : increase verbosity, can be speficied multiple times") print("-n : do not print multi-line suggestions") print("-h : print this help message and exit") + print( + "--check-file : Pass a single argument which is a file containing a candidate commit message" + ) + print( + "--ignore-rebase : Skip checking commits with git rebase autosquash prefixes or WIP as a prefix" + ) print("... : arguments passed to git log to retrieve commits to verify") print(" see https://www.git-scm.com/docs/git-log") print(" passing no arguments at all will verify all commits") @@ -117,6 +140,10 @@ def show_help(): args = sys.argv[1:] verbosity = args.count("-v") suggestions = args.count("-n") == 0 + if "--ignore-rebase" in args: + args.remove("--ignore-rebase") + ignore_prefixes = ["squash!", "fixup!", "amend!", "WIP"] + if "-h" in args: show_help() else: From 95c614e2b60b5c1c83c85aefe88a2aadbf43b9ed Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 4 Oct 2022 17:43:04 +1100 Subject: [PATCH 1795/4290] esp32/machine_hw_spi: Use auto DMA channel on S2, S3, C3 chips. Auto DMA channel is supported in IDF v4.4, and is required to be used on S3 chips, so use this simpler configuration option where possible. Fixes issue #8634. Signed-off-by: Damien George --- ports/esp32/machine_hw_spi.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 05b1c871cb3c..647874e17f64 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -267,21 +267,15 @@ STATIC void machine_hw_spi_init_internal( // Select DMA channel based on the hardware SPI host int dma_chan = 0; + #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 + dma_chan = SPI_DMA_CH_AUTO; + #else if (self->host == HSPI_HOST) { - #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 - dma_chan = 3; - #else dma_chan = 1; - #endif - #ifdef FSPI_HOST - } else if (self->host == FSPI_HOST) { - dma_chan = 1; - #endif - #ifdef VSPI_HOST - } else if (self->host == VSPI_HOST) { + } else { dma_chan = 2; - #endif } + #endif ret = spi_bus_initialize(self->host, &buscfg, dma_chan); switch (ret) { From f13134e40308c24bcb2c09084f17fc9d54efe5db Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 5 Oct 2022 22:30:29 +1100 Subject: [PATCH 1796/4290] tools/mpremote: Fix argument handling for follow and add help strings. Fixes in this commit are: - Make --follow the default for "run" (accidentally changed in 68d094358). - Add help strings for "repl": --capture --inject-file --inject-code - Update help strings for "run". - Fix encoding for --inject-code (accidentally broken in 68d094358). - Remove ability to --no-follow for "eval". It was there previously because it shared the same code path with "exec" and "run", but makes no sense for "eval", so might as well remove. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- tools/mpremote/mpremote/commands.py | 2 +- tools/mpremote/mpremote/main.py | 29 ++++++++++++++++++++++------- tools/mpremote/mpremote/repl.py | 1 + 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/tools/mpremote/mpremote/commands.py b/tools/mpremote/mpremote/commands.py index bf56df69993a..558cd82f1080 100644 --- a/tools/mpremote/mpremote/commands.py +++ b/tools/mpremote/mpremote/commands.py @@ -204,7 +204,7 @@ def do_exec(state, args): def do_eval(state, args): buf = "print(" + args.expr[0] + ")" - _do_execbuffer(state, buf, args.follow) + _do_execbuffer(state, buf, True) def do_run(state, args): diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py index 4f541685a0cf..988ffe8f60f1 100644 --- a/tools/mpremote/mpremote/main.py +++ b/tools/mpremote/mpremote/main.py @@ -119,30 +119,45 @@ def argparse_mount(): def argparse_repl(): cmd_parser = argparse.ArgumentParser(description="connect to given device") - cmd_parser.add_argument("--capture", type=str, required=False, help="TODO") - cmd_parser.add_argument("--inject-code", type=str, required=False, help="TODO") - cmd_parser.add_argument("--inject-file", type=str, required=False, help="TODO") + cmd_parser.add_argument( + "--capture", + type=str, + required=False, + help="saves a copy of the REPL session to the specified path", + ) + cmd_parser.add_argument( + "--inject-code", type=str, required=False, help="code to be run when Ctrl-J is pressed" + ) + cmd_parser.add_argument( + "--inject-file", + type=str, + required=False, + help="path to file to be run when Ctrl-K is pressed", + ) return cmd_parser def argparse_eval(): cmd_parser = argparse.ArgumentParser(description="evaluate and print the string") - _bool_flag(cmd_parser, "follow", "f", True, "TODO") cmd_parser.add_argument("expr", nargs=1, help="expression to execute") return cmd_parser def argparse_exec(): cmd_parser = argparse.ArgumentParser(description="execute the string") - _bool_flag(cmd_parser, "follow", "f", True, "TODO") + _bool_flag( + cmd_parser, "follow", "f", True, "follow output until the expression completes (default)" + ) cmd_parser.add_argument("expr", nargs=1, help="expression to execute") return cmd_parser def argparse_run(): cmd_parser = argparse.ArgumentParser(description="run the given local script") - _bool_flag(cmd_parser, "follow", "f", False, "TODO") - cmd_parser.add_argument("path", nargs=1, help="expression to execute") + _bool_flag( + cmd_parser, "follow", "f", True, "follow output until the script completes (default)" + ) + cmd_parser.add_argument("path", nargs=1, help="path to script to execute") return cmd_parser diff --git a/tools/mpremote/mpremote/repl.py b/tools/mpremote/mpremote/repl.py index 7da00c0fdef0..3d6ca1881b1e 100644 --- a/tools/mpremote/mpremote/repl.py +++ b/tools/mpremote/mpremote/repl.py @@ -61,6 +61,7 @@ def do_repl(state, args): print('Capturing session to file "%s"' % capture_file) capture_file = open(capture_file, "wb") if code_to_inject is not None: + code_to_inject = bytes(code_to_inject.replace("\\n", "\r\n"), "utf8") print("Use Ctrl-J to inject", code_to_inject) if file_to_inject is not None: print('Use Ctrl-K to inject file "%s"' % file_to_inject) From 46d02c2469ec7947fe3aae2d68e07236baf5c72e Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 Oct 2022 01:02:39 +1100 Subject: [PATCH 1797/4290] tools/mpremote: Bump version to 0.4.0. Signed-off-by: Damien George --- tools/mpremote/mpremote/__init__.py | 2 +- tools/mpremote/setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mpremote/mpremote/__init__.py b/tools/mpremote/mpremote/__init__.py index 493f7415d73d..6a9beea82f65 100644 --- a/tools/mpremote/mpremote/__init__.py +++ b/tools/mpremote/mpremote/__init__.py @@ -1 +1 @@ -__version__ = "0.3.0" +__version__ = "0.4.0" diff --git a/tools/mpremote/setup.cfg b/tools/mpremote/setup.cfg index 16880d77f895..7fae3cbcb390 100644 --- a/tools/mpremote/setup.cfg +++ b/tools/mpremote/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = mpremote -version = 0.3.0 +version = 0.4.0 author = Damien George author_email = damien@micropython.org description = Tool for interacting remotely with MicroPython From 85afed569d3d435b2611856356ff9c78d244f25c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 27 May 2022 15:43:48 +0200 Subject: [PATCH 1798/4290] samd: Remove the existing provisional support for REPL on UART. It was only partially working and will be rpelaced later by a full machine.UART class implementation. --- .../mpconfigboard.h | 16 ----- .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c | 1 + .../mpconfigboard.h | 15 ---- .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c | 1 + .../ADAFRUIT_TRINKET_M0/mpconfigboard.h | 15 ---- ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c | 1 + ports/samd/boards/MINISAM_M4/mpconfigboard.h | 15 ---- ports/samd/boards/MINISAM_M4/pins.c | 1 + .../SAMD21_XPLAINED_PRO/mpconfigboard.h | 16 ----- ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c | 1 + .../boards/SEEED_WIO_TERMINAL/mpconfigboard.h | 15 ---- ports/samd/boards/SEEED_WIO_TERMINAL/pins.c | 1 + ports/samd/boards/SEEED_XIAO/mpconfigboard.h | 15 ---- ports/samd/boards/SEEED_XIAO/pins.c | 1 + ports/samd/modmachine.c | 5 -- ports/samd/modmachine.h | 3 - ports/samd/mphalport.c | 8 --- ports/samd/samd_soc.c | 70 ------------------- 18 files changed, 7 insertions(+), 193 deletions(-) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h index 6d3b7987e39d..bdb22d2e0adf 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h @@ -9,20 +9,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; -// ASF4 MCU package specific Pin definitions -#include "samd21g18a.h" - -// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. -// On this board (see https://learn.adafruit.com/assets/40553) TX is D1 (PA10) and RX is D0 (PA11) -// USART pin assignments: Tx=PA10=SERCOM0/PAD[2], Rx=PA11==SERCOM0/PAD[3] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 0 // A=0, B=1 -#define MP_TX_PIN 10 // 'n' -#define MP_RX_PIN 11 -#define MP_PERIPHERAL_MUX 5 // 'n'th group of 2 pins -#define USARTx SERCOM0 // SERCOM0: tx/rx -#define MP_PORT_FUNC 0x22 // Sets PMUXE & PMUXO to the Alternative Function.(A-H=0-7) -#define MP_RXPO_PAD 3 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 1 // TXPO- Transmit Data Pinout -#define MP_SERCOMx SERCOM0_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM0_CORE // Generic Clock Control diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c index e0dd752ec900..fbb5032a4062 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in 'pins.h' reflects # of Pins defined here. diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h index c1c4fd8cad4c..80baf39e5d6d 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h @@ -14,19 +14,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // -// ASF4 MCU package specific Pin definitions -#include "samd51g19a.h" - -// Please consult the SAM_D51 Datasheet, I/O Multiplexing and Considerations. -// USART pin assignments: Tx=TX_D1=PA17=SERCOM3/PAD[0], Rx=RX_D0=PA16=SERCOM3/PAD[1] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 1 // A-D=0-3 -#define MP_TX_PIN 17 -#define MP_RX_PIN 16 // 'n' -#define MP_PERIPHERAL_MUX 8 // 'n'th group of 2 pins -#define USARTx SERCOM3 // -#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-N=0-13 -#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout -#define MP_SERCOMx SERCOM3_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE SERCOM3_GCLK_ID_CORE diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c index 82948ccbc4f1..0342b0d00c58 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in 'pins.h' reflects # of Pins defined here. diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h index 128689f4f74a..066c7ee1429e 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h @@ -9,19 +9,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; -// ASF4 MCU package specific Pin definitions -#include "samd21e18a.h" - -// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. -// USART pin assignments: Tx=D4=PA06=SERCOM0/PAD[2], Rx=D3=PA07=SERCOM0/PAD[3] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 1 // A=0, B=1 -#define MP_TX_PIN 6 // 'n' -#define MP_RX_PIN 7 -#define MP_PERIPHERAL_MUX 3 // 'n'th group of 2 pins -#define USARTx SERCOM0 // SERCOM0: tx/rx -#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-H=0-7 -#define MP_RXPO_PAD 3 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 2 // TXPO- Tranmit Data Pinout -#define MP_SERCOMx SERCOM0_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM0_CORE // Generic Clock Control diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c index 9fecddb6cd87..676b4794e89b 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in 'pins.h' reflects # of Pins defined here. diff --git a/ports/samd/boards/MINISAM_M4/mpconfigboard.h b/ports/samd/boards/MINISAM_M4/mpconfigboard.h index a65eb54b495f..a8f1f96242c8 100644 --- a/ports/samd/boards/MINISAM_M4/mpconfigboard.h +++ b/ports/samd/boards/MINISAM_M4/mpconfigboard.h @@ -14,19 +14,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // -// ASF4 MCU package specific Pin definitions -#include "samd51g19a.h" - -// Please consult the SAM_D51 Datasheet, I/O Multiplexing and Considerations. -// USART pin assignments: Tx=TX_D1=PA17=SERCOM3/PAD[0], Rx=RX_D0=PA16=SERCOM3/PAD[1] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 0 // A-D=0-3 -#define MP_TX_PIN 17 -#define MP_RX_PIN 16 // 'n' -#define MP_PERIPHERAL_MUX 8 // 'n'th group of 2 pins -#define USARTx SERCOM3 // -#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-N=0-13 -#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout -#define MP_SERCOMx SERCOM3_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE SERCOM3_GCLK_ID_CORE diff --git a/ports/samd/boards/MINISAM_M4/pins.c b/ports/samd/boards/MINISAM_M4/pins.c index 6cdd840b6bc7..17ed58d3c418 100644 --- a/ports/samd/boards/MINISAM_M4/pins.c +++ b/ports/samd/boards/MINISAM_M4/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in 'pins.h' reflects # of Pins defined here. diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h index a7dbf76144bc..860cb6b97778 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h @@ -9,20 +9,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; -// ASF4 MCU package specific Pin definitions -#include "samd21j18a.h" - -// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. -// USART pin assignments: (This board has 3 USARTS brought out to the pins. See https://docs.zephyrproject.org/1.14.1/boards/arm/atsamd21_xpro/doc/index.html#serial-port ) -// Tx=PA10=SERCOM0/PAD[2], Rx=PA11=SERCOM0/PAD[3] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 1 // A=0, B=1 -#define MP_TX_PIN 10 // 'n' -#define MP_RX_PIN 11 -#define MP_PERIPHERAL_MUX 5 // 'n'th group of 2 pins -#define USARTx SERCOM0 // SERCOM0: tx/rx -#define MP_PORT_FUNC 0x22 // Sets PMUXE & PMUXO to the Alternative Function.(A-H=0-7) -#define MP_RXPO_PAD 3 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 2 // TXPO- Tranmit Data Pinout -#define MP_SERCOMx SERCOM0_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM0_CORE // Generic Clock Control diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c index 2a2d50eb48fc..35718ea7f3d7 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in 'pins.h' reflects # of Pins defined here. diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h index 290bd802b8a0..bb0f1c828e78 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h @@ -14,19 +14,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; -// ASF4 MCU package specific Pin definitions -#include "samd51p19a.h" - -// Please consult the SAM_D51 Datasheet, I/O Multiplexing and Considerations. -// WIO_Terminal USART pin assignments: Tx=BCM14=PB27=SERCOM2/PAD[0], Rx=BCM15=PB26=SERCOM2/PAD[1] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 1 // A-D=0-3 -#define MP_TX_PIN 27 -#define MP_RX_PIN 26 // 'n' -#define MP_PERIPHERAL_MUX 13 // 'n'th group of 2 pins -#define USARTx SERCOM2 // -#define MP_PORT_FUNC 0x22 // Sets PMUXE & PMUXO to the Alternative Function.A-N=0-13 -#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout -#define MP_SERCOMx SERCOM2_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE SERCOM2_GCLK_ID_CORE diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c index 9862552fa3d8..d7833416d3c7 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in "pins.h" reflects # of Pins defined here. diff --git a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h index 6422d7ea0232..a2f2a9fb0b01 100644 --- a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h +++ b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h @@ -9,19 +9,4 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; -// ASF4 MCU package specific Pin definitions -#include "samd21g18a.h" - -// Please consult the SAM_D21 Datasheet, I/O Multiplexing and Considerations. -// XIAO_M0 USART pin assignments: Tx=A6=PB8=SERCOM4/PAD[0], Rx=PB9=A7=SERCOM4/PAD[1] #define CPU_FREQ (48000000) // For selecting Baud from clock. -#define MP_PIN_GRP 1 // A=0, B=1 -#define MP_TX_PIN 8 // 'n' -#define MP_RX_PIN 9 -#define MP_PERIPHERAL_MUX 4 // 'n'th group of 2 pins -#define USARTx SERCOM4 // SERCOM4:XIAO_M0 tx/rx -#define MP_PORT_FUNC 0x33 // Sets PMUXE & PMUXO to the Alternative Function.A-H=0-7 -#define MP_RXPO_PAD 1 // RXPO- Receive Data Pinout -#define MP_TXPO_PAD 0 // TXPO- Tranmit Data Pinout -#define MP_SERCOMx SERCOM4_ // APBCMASK -#define MP_SERCOM_GCLK_ID_x_CORE GCLK_CLKCTRL_ID_SERCOM4_CORE // Generic Clock Control diff --git a/ports/samd/boards/SEEED_XIAO/pins.c b/ports/samd/boards/SEEED_XIAO/pins.c index 6043913d2bad..e2f7c264b4bd 100644 --- a/ports/samd/boards/SEEED_XIAO/pins.c +++ b/ports/samd/boards/SEEED_XIAO/pins.c @@ -27,6 +27,7 @@ */ #include "modmachine.h" +#include "sam.h" #include "pins.h" // Ensure Declaration in 'pins.h' reflects # of Pins defined here. diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 74e357175942..1b78b687e180 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -45,9 +45,6 @@ #define DBL_TAP_MAGIC_LOADER 0xf01669ef #define DBL_TAP_MAGIC_RESET 0xf02669ef -MP_DEFINE_CONST_FUN_OBJ_0(machine_uart_init_obj, machine_uart_init); -MP_DEFINE_CONST_FUN_OBJ_0(machine_uart_deinit_obj, machine_uart_deinit); - STATIC mp_obj_t machine_reset(void) { *DBL_TAP_ADDR = DBL_TAP_MAGIC_RESET; NVIC_SystemReset(); @@ -119,8 +116,6 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, { 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) }, - { MP_ROM_QSTR(MP_QSTR_uart_init), MP_ROM_PTR(&machine_uart_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_uart_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, }; diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 61bd2f4d2991..f7ad2b5e5cbc 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -31,7 +31,4 @@ extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_led_type; -mp_obj_t machine_uart_init(void); -mp_obj_t machine_uart_deinit(void); - #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index c19d542a8556..beade14a6e3d 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -71,9 +71,6 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { int mp_hal_stdin_rx_chr(void) { for (;;) { - if (USARTx->USART.INTFLAG.bit.RXC) { - return USARTx->USART.DATA.bit.DATA; - } if (tud_cdc_connected() && tud_cdc_available()) { uint8_t buf[1]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); @@ -100,9 +97,4 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { i += n2; } } - while (len--) { - while (!(USARTx->USART.INTFLAG.bit.DRE)) { - } - USARTx->USART.DATA.bit.DATA = *str++; - } } diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 7f4df1bb1c75..7a96cbb4800f 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -35,75 +35,6 @@ #include "samd_soc.h" #include "tusb.h" -// "MP" macros defined in "boards/$(BOARD)/mpconfigboard.h" -mp_obj_t machine_uart_init(void) { - // Firstly, assign alternate function SERCOM PADs to GPIO pins. - PORT->Group[MP_PIN_GRP].PINCFG[MP_TX_PIN].bit.PMUXEN = 1; // Enable - PORT->Group[MP_PIN_GRP].PINCFG[MP_RX_PIN].bit.PMUXEN = 1; // Enable - PORT->Group[MP_PIN_GRP].PMUX[MP_PERIPHERAL_MUX].reg = MP_PORT_FUNC; // Sets PMUXE & PMUXO in 1 hit. - uint32_t rxpo = MP_RXPO_PAD; // 1=Pad1,3=Pad3 Rx data - uint32_t txpo = MP_TXPO_PAD; // 0=pad0,1=Pad2 Tx data - - // Initialise the clocks - #if defined(MCU_SAMD21) - PM->APBCMASK.bit.MP_SERCOMx = 1; // Enable synchronous clock - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | MP_SERCOM_GCLK_ID_x_CORE; // Select multiplexer generic clock source and enable. - // Wait while it updates synchronously. - while (GCLK->STATUS.bit.SYNCBUSY) { - } - #elif defined(MCU_SAMD51) - GCLK->PCHCTRL[MP_SERCOM_GCLK_ID_x_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; - MCLK->APBBMASK.bit.MP_SERCOMx = 1; - #endif - - // Setup the Peripheral. - // Reset (clear) the peripheral registers. - while (USARTx->USART.SYNCBUSY.bit.SWRST) { - } - USARTx->USART.CTRLA.bit.SWRST = 1; // Reset all Registers, disable peripheral - while (USARTx->USART.SYNCBUSY.bit.SWRST) { - } - - // Set the register bits as needed - // (CMODE (async),CHSIZE (8),FORM (no parity),SBMODE (1 stop) already 0). - USARTx->USART.CTRLA.reg = // USARTx = SERCOMx set in "boards/$(BOARD)/mpconfigboard.h" - SERCOM_USART_CTRLA_DORD // Data order - | SERCOM_USART_CTRLA_RXPO(rxpo) // Set Pad# - | SERCOM_USART_CTRLA_TXPO(txpo) // Set Pad# - | SERCOM_USART_CTRLA_MODE(1) // USART with internal clock - ; - USARTx->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN; // Enable Rx & Tx - while (USARTx->USART.SYNCBUSY.bit.CTRLB) { - } - - // Baud rate is clock dependant. - #if CPU_FREQ == 8000000 - uint32_t baud = 50437; // 115200 baud; 65536*(1 - 16 * 115200/8e6) - #elif CPU_FREQ == 48000000 - uint32_t baud = 63019; // 115200 baud; 65536*(1 - 16 * 115200/48e6) - #elif CPU_FREQ == 120000000 - uint32_t baud = 64529; // 115200 baud; 65536*(1 - 16 * 115200/120e6) - #endif - USARTx->USART.BAUD.bit.BAUD = baud; // Set Baud - USARTx->USART.CTRLA.bit.ENABLE = 1; // Enable the peripheral - // Wait for the Registers to update. - while (USARTx->USART.SYNCBUSY.bit.ENABLE) { - } - - return mp_const_none; -} - -// Disconnect SERCOM from GPIO pins. (Can't SWRST, as that will totally kill USART). -mp_obj_t machine_uart_deinit(void) { - // Reset - printf("Disabling the Alt-Funct, releasing the USART pins for GPIO... \n"); - PORT->Group[MP_PIN_GRP].PINCFG[MP_TX_PIN].bit.PMUXEN = 0; // Disable - PORT->Group[MP_PIN_GRP].PINCFG[MP_RX_PIN].bit.PMUXEN = 0; // Disable - - return mp_const_none; -} - - static void usb_init(void) { // Init USB clock #if defined(MCU_SAMD21) @@ -168,6 +99,5 @@ void samd_init(void) { #endif SysTick_Config(CPU_FREQ / 1000); - machine_uart_init(); usb_init(); } From 0420799a847d4bb74c9a92666e2cd35c23b1c12c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 27 May 2022 21:19:47 +0200 Subject: [PATCH 1799/4290] samd/boards: Replace pins.c and pins.h by pins.csv. The files pins.c and pins.h are generated during the build process from pins.csv, using a make-pins.py script. --- ports/samd/Makefile | 11 +- .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c | 59 -------- .../ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv | 37 +++++ .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h | 42 ------ .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c | 59 -------- .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv | 36 +++++ .../ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h | 42 ------ ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c | 44 ------ .../samd/boards/ADAFRUIT_TRINKET_M0/pins.csv | 16 +++ ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h | 42 ------ ports/samd/boards/MINISAM_M4/pins.c | 52 -------- ports/samd/boards/MINISAM_M4/pins.csv | 27 ++++ ports/samd/boards/MINISAM_M4/pins.h | 42 ------ ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c | 92 ------------- .../samd/boards/SAMD21_XPLAINED_PRO/pins.csv | 63 +++++++++ ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h | 42 ------ ports/samd/boards/SEEED_WIO_TERMINAL/pins.c | 61 --------- ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv | 30 +++++ ports/samd/boards/SEEED_WIO_TERMINAL/pins.h | 42 ------ ports/samd/boards/SEEED_XIAO/pins.c | 53 -------- ports/samd/boards/SEEED_XIAO/pins.csv | 22 +++ ports/samd/boards/SEEED_XIAO/pins.h | 42 ------ ports/samd/boards/make-pins.py | 126 ++++++++++++++++++ 23 files changed, 367 insertions(+), 715 deletions(-) delete mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv delete mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h delete mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv delete mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h delete mode 100644 ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c create mode 100644 ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv delete mode 100644 ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h delete mode 100644 ports/samd/boards/MINISAM_M4/pins.c create mode 100644 ports/samd/boards/MINISAM_M4/pins.csv delete mode 100644 ports/samd/boards/MINISAM_M4/pins.h delete mode 100644 ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c create mode 100644 ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv delete mode 100644 ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h delete mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/pins.c create mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv delete mode 100644 ports/samd/boards/SEEED_WIO_TERMINAL/pins.h delete mode 100644 ports/samd/boards/SEEED_XIAO/pins.c create mode 100644 ports/samd/boards/SEEED_XIAO/pins.csv delete mode 100644 ports/samd/boards/SEEED_XIAO/pins.h create mode 100644 ports/samd/boards/make-pins.py diff --git a/ports/samd/Makefile b/ports/samd/Makefile index aed8637abcc1..1ef35c1a025e 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -56,6 +56,11 @@ LDFLAGS += $(LDFLAGS_MOD) LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +MAKE_PINS = boards/make-pins.py +BOARD_PINS = $(BOARD_DIR)/pins.csv +GEN_PINS_SRC = $(BUILD)/pins.c +GEN_PINS_HDR = $(BUILD)/pins.h + # Tune for Debugging or Optimization CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG),1) @@ -79,7 +84,7 @@ SRC_C = \ help.c \ modutime.c \ modmachine.c \ - $(BOARD_DIR)/pins.c \ + $(BUILD)/pins.c \ machine_pin.c \ machine_led.c \ modsamd.c \ @@ -160,4 +165,8 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin $(Q)$(PYTHON) $(UF2CONV) -b $(TEXT0) -c -o $@ $< +$(GEN_PINS_SRC): $(BOARD_PINS) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --pins $(GEN_PINS_SRC) --inc $(GEN_PINS_HDR) + include $(TOP)/py/mkrules.mk diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c deleted file mode 100644 index fbb5032a4062..000000000000 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - {{&machine_pin_type}, PIN_PA11}, // D0 - {{&machine_pin_type}, PIN_PA10}, // D1 - {{&machine_pin_type}, PIN_PA14}, // D2 - {{&machine_pin_type}, PIN_PA09}, // D3/ - {{&machine_pin_type}, PIN_PA08}, // D4/ - {{&machine_pin_type}, PIN_PA15}, // D5 - {{&machine_pin_type}, PIN_PA20}, // D6 - {{&machine_pin_type}, PIN_PA21}, // D7 - {{&machine_pin_type}, PIN_PA06}, // D8/ - {{&machine_pin_type}, PIN_PA07}, // D9/ - {{&machine_pin_type}, PIN_PA18}, // D10 - {{&machine_pin_type}, PIN_PA16}, // D11 - {{&machine_pin_type}, PIN_PA19}, // D12 - {{&machine_pin_type}, PIN_PA17}, // D13/ - {{&machine_pin_type}, PIN_PA02}, // A0 - {{&machine_pin_type}, PIN_PB08}, // A1 - {{&machine_pin_type}, PIN_PB09}, // A2 - {{&machine_pin_type}, PIN_PA04}, // A3/ - {{&machine_pin_type}, PIN_PA05}, // A4/ - {{&machine_pin_type}, PIN_PB02}, // A5 -}; - -const machine_led_obj_t machine_led_obj[] = { - {{&machine_led_type}, PIN_PA17}, // D13/ user LED -}; diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv new file mode 100644 index 000000000000..84e68157acbc --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv @@ -0,0 +1,37 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +PIN_PA11,D0 +PIN_PA10,D1 +PIN_PA14,D2 +PIN_PA09,D3 +PIN_PA08,D4 +PIN_PA15,D5 +PIN_PA20,D6 +PIN_PA21,D7 +PIN_PA06,D8 +PIN_PA07,D9 +PIN_PA18,D10 +PIN_PA16,D11 +PIN_PA19,D12 +PIN_PA17,D13 +PIN_PA02,A0 +PIN_PB08,A1 +PIN_PB09,A2 +PIN_PA04,A3 +PIN_PA05,A4 +PIN_PB02,A5 +PIN_PB22,TX +PIN_PB23,RX +PIN_PA23,SCL +PIN_PA22,SDA +PIN_PA06,NEOPIXEL +PIN_PA13,FLASH_CS + +LED_PA17,LED +LED_PA27,LED_TX +LED_PB03,LED_RX diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h deleted file mode 100644 index 45bee6167837..000000000000 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[20]; -extern const machine_led_obj_t machine_led_obj[1]; diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c deleted file mode 100644 index 0342b0d00c58..000000000000 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - {{&machine_pin_type}, PIN_PA16}, // RX_D0 - {{&machine_pin_type}, PIN_PA17}, // TX_D1 - {{&machine_pin_type}, PIN_PA07}, // D2 - {{&machine_pin_type}, PIN_PB22}, // D3 - {{&machine_pin_type}, PIN_PA14}, // D4 - {{&machine_pin_type}, PIN_PA15}, // D5 - {{NULL}, -1}, // D6- not terminated on breakout. - {{&machine_pin_type}, PIN_PA18}, // D7 - {{NULL}, -1}, // D8- not terminated on breakout. - {{&machine_pin_type}, PIN_PA19}, // D9 - {{&machine_pin_type}, PIN_PA20}, // D10 - {{&machine_pin_type}, PIN_PA21}, // D11 - {{&machine_pin_type}, PIN_PA23}, // D12 - {{&machine_pin_type}, PIN_PA22}, // D13 - {{&machine_pin_type}, PIN_PA02}, // A0 - {{&machine_pin_type}, PIN_PA05}, // A1 - {{&machine_pin_type}, PIN_PB08}, // A2 - {{&machine_pin_type}, PIN_PB09}, // A3 - {{&machine_pin_type}, PIN_PA04}, // A4 - {{&machine_pin_type}, PIN_PA06}, // A5 -}; - -const machine_led_obj_t machine_led_obj[] = { - {{&machine_led_type}, PIN_PA22}, // D13 -}; diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv new file mode 100644 index 000000000000..90e38761a10c --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv @@ -0,0 +1,36 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +PIN_PA16,D0 +PIN_PA17,D1 +PIN_PA07,D2 +PIN_PB22,D3 +PIN_PA14,D4 +PIN_PA15,D5 +- +PIN_PA18,D7 +- +PIN_PA19,D9 +PIN_PA20,D10 +PIN_PA21,D11 +PIN_PA23,D12 +PIN_PA22,D13 +PIN_PA02,A0 +PIN_PA05,A1 +PIN_PB08,A2 +PIN_PB09,A3 +PIN_PA04,A4 +PIN_PA06,A5 +PIN_PA12,SDA +PIN_PA13,SCL +PIN_PA00,MO +PIN_PB23,MI +PIN_PA01,SCK +PIN_PB02,DOTSTAR_CLK +PIN_PB03,DOTSTAR_DATA + +LED_PA22,LED diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h deleted file mode 100644 index 45bee6167837..000000000000 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[20]; -extern const machine_led_obj_t machine_led_obj[1]; diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c deleted file mode 100644 index 676b4794e89b..000000000000 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - {{&machine_pin_type}, PIN_PA08}, // D0 - {{&machine_pin_type}, PIN_PA02}, // D1 - {{&machine_pin_type}, PIN_PA09}, // D2 - {{&machine_pin_type}, PIN_PA07}, // D3/ RxD - {{&machine_pin_type}, PIN_PA06}, // D4/ TxD -}; - -const machine_led_obj_t machine_led_obj[] = { - {{&machine_led_type}, PIN_PA10}, // user LED -}; diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv new file mode 100644 index 000000000000..797b3f70bb92 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv @@ -0,0 +1,16 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +PIN_PA08,D0 +PIN_PA02,D1 +PIN_PA09,D2 +PIN_PA07,D3 +PIN_PA06,D4 +PIN_PA00,DOTSTAR_DATA +PIN_PA01,DOTSTAR_CLK + +LED_PA10,LED diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h deleted file mode 100644 index 843d69addc0f..000000000000 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[5]; -extern const machine_led_obj_t machine_led_obj[1]; diff --git a/ports/samd/boards/MINISAM_M4/pins.c b/ports/samd/boards/MINISAM_M4/pins.c deleted file mode 100644 index 17ed58d3c418..000000000000 --- a/ports/samd/boards/MINISAM_M4/pins.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - {{&machine_pin_type}, PIN_PA02}, // A0,D9 - {{&machine_pin_type}, PIN_PB08}, // A1,D10 - {{&machine_pin_type}, PIN_PB09}, // A2,D11 - {{&machine_pin_type}, PIN_PA04}, // A3,D12 - {{&machine_pin_type}, PIN_PA05}, // A4,D13 - {{&machine_pin_type}, PIN_PA06}, // A5 - {{&machine_pin_type}, PIN_PA16}, // RX_D0 - {{&machine_pin_type}, PIN_PA17}, // TX_D1 - {{&machine_pin_type}, PIN_PA07}, // D2,A6 - {{&machine_pin_type}, PIN_PA19}, // D3 - {{&machine_pin_type}, PIN_PA20}, // D4 - {{&machine_pin_type}, PIN_PA21}, // D5 - {{&machine_pin_type}, PIN_PA00}, // BUTTON -}; - -const machine_led_obj_t machine_led_obj[] = { - {{&machine_led_type}, PIN_PA15}, // LED -}; diff --git a/ports/samd/boards/MINISAM_M4/pins.csv b/ports/samd/boards/MINISAM_M4/pins.csv new file mode 100644 index 000000000000..7442a028d12a --- /dev/null +++ b/ports/samd/boards/MINISAM_M4/pins.csv @@ -0,0 +1,27 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +PIN_PA02,A0_D9 +PIN_PB08,A1_D10 +PIN_PB09,A2_D11 +PIN_PA04,A3_D12 +PIN_PA05,A4_D13 +PIN_PA06,A5 +PIN_PA16,D0 +PIN_PA17,D1 +PIN_PA07,A6_D2 +PIN_PA19,D3 +PIN_PA20,D4 +PIN_PA21,D5 +PIN_PA00,BUTTON +PIN_PA03,AREF +PIN_PA12,SDA +PIN_PA13,SCL +PIN_PB03,DOTSTAR_DATA +PIN_PB02,DOTSTAR_CLK + +LED_PA15,LED diff --git a/ports/samd/boards/MINISAM_M4/pins.h b/ports/samd/boards/MINISAM_M4/pins.h deleted file mode 100644 index 892b0e7b9763..000000000000 --- a/ports/samd/boards/MINISAM_M4/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[13]; -extern const machine_led_obj_t machine_led_obj[1]; diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c deleted file mode 100644 index 35718ea7f3d7..000000000000 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - // EXT1 - {{&machine_pin_type}, PIN_PB00}, // PIN3_ADC(+) - {{&machine_pin_type}, PIN_PB01}, // PIN4_ADC(-) - {{&machine_pin_type}, PIN_PB06}, // PIN5_GPIO - {{&machine_pin_type}, PIN_PB07}, // PIN6_GPIO - {{&machine_pin_type}, PIN_PB02}, // PIN7_PWM(+) - {{&machine_pin_type}, PIN_PB03}, // PIN8_PWM(-) - {{&machine_pin_type}, PIN_PB04}, // PIN9_IRQ/GPIO - {{&machine_pin_type}, PIN_PB05}, // PIN10_SPI_SS_B/GPIO - {{&machine_pin_type}, PIN_PA08}, // PIN11_TWI_SDA - {{&machine_pin_type}, PIN_PA09}, // PIN12_TWI_SCL - {{&machine_pin_type}, PIN_PB09}, // PIN13_UART_RX - {{&machine_pin_type}, PIN_PB08}, // PIN14_UART_TX - {{&machine_pin_type}, PIN_PA05}, // PIN15_SPI_SS_A - {{&machine_pin_type}, PIN_PA06}, // PIN16_SPI_MOSI - {{&machine_pin_type}, PIN_PA04}, // PIN17_SPI_MISO - {{&machine_pin_type}, PIN_PA07}, // PIN18_SPI_SCK - - // EXT2 - {{&machine_pin_type}, PIN_PA10}, // PIN3_ADC(+) - {{&machine_pin_type}, PIN_PA11}, // PIN4_ADC(-) - {{&machine_pin_type}, PIN_PA20}, // PIN5_GPIO - {{&machine_pin_type}, PIN_PA21}, // PIN6_GPIO - {{&machine_pin_type}, PIN_PB12}, // PIN7_PWM(+) - {{&machine_pin_type}, PIN_PB13}, // PIN8_PWM(-) - {{&machine_pin_type}, PIN_PB14}, // PIN9_IRQ/GPIO - {{&machine_pin_type}, PIN_PB15}, // PIN10_SPI_SS_B/GPIO - {{NULL}, -1}, // PIN_PA08/ PIN11_TWI_SDA already defined - {{NULL}, -1}, // PIN_PA09/ PIN12_TWI_SCL already defined - {{&machine_pin_type}, PIN_PB11}, // PIN13_UART_RX - {{&machine_pin_type}, PIN_PB10}, // PIN14_UART_TX - {{&machine_pin_type}, PIN_PA17}, // PIN15_SPI_SS_A - {{&machine_pin_type}, PIN_PA18}, // PIN16_SPI_MOSI - {{&machine_pin_type}, PIN_PA16}, // PIN17_SPI_MISO - {{&machine_pin_type}, PIN_PA19}, // PIN18_SPI_SCK - - // EXT3 - {{&machine_pin_type}, PIN_PA02}, // PIN3_ADC(+) - {{&machine_pin_type}, PIN_PA03}, // PIN4_ADC(-) - {{NULL}, -1}, // PIN_PB30/ PIN5_GPIO already defined - {{&machine_pin_type}, PIN_PA15}, // PIN6_GPIO; USER_BUTTON - {{&machine_pin_type}, PIN_PA12}, // PIN7_PWM(+) - {{&machine_pin_type}, PIN_PA13}, // PIN8_PWM(-) - {{&machine_pin_type}, PIN_PA28}, // PIN9_IRQ/GPIO - {{&machine_pin_type}, PIN_PA27}, // PIN10_SPI_SS_B/GPIO - {{NULL}, -1}, // PIN_PA08/ PIN11_TWI_SDA already defined - {{NULL}, -1}, // PIN_PA09/ PIN12_TWI_SCL already defined - {{NULL}, -1}, // PIN_PB11/ PIN13_UART_RX already defined - {{NULL}, -1}, // PIN_PB10/ PIN14_UART_TX already defined - {{&machine_pin_type}, PIN_PB17}, // PIN15_SPI_SS_A - {{&machine_pin_type}, PIN_PB22}, // PIN16_SPI_MOSI - {{&machine_pin_type}, PIN_PB16}, // PIN17_SPI_MISO - {{&machine_pin_type}, PIN_PB23}, // PIN18_SPI_SCK -}; - -const machine_led_obj_t machine_led_obj[] = { - {{&machine_led_type}, PIN_PB30}, // USER_LED -}; diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv new file mode 100644 index 000000000000..438119d90c1a --- /dev/null +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv @@ -0,0 +1,63 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +# EXT1 +PIN_PB00,EXT1_PIN3 +PIN_PB01,EXT1_PIN4 +PIN_PB06,EXT1_PIN5 +PIN_PB07,EXT1_PIN6 +PIN_PB02,EXT1_PIN7 +PIN_PB03,EXT1_PIN8 +PIN_PB04,EXT1_PIN9 +PIN_PB05,EXT1_PIN10 +PIN_PA08,EXT1_PIN11 +PIN_PA09,EXT1_PIN12 +PIN_PB09,EXT1_PIN13 +PIN_PB08,EXT1_PIN14 +PIN_PA05,EXT1_PIN15 +PIN_PA06,EXT1_PIN16 +PIN_PA04,EXT1_PIN17 +PIN_PA07,EXT1_PIN18 + +# EXT2 +PIN_PA10,EXT2_PIN3 +PIN_PA11,EXT2_PIN4 +PIN_PA20,EXT2_PIN5 +PIN_PA21,EXT2_PIN6 +PIN_PB12,EXT2_PIN7 +PIN_PB13,EXT2_PIN8 +PIN_PB14,EXT2_PIN9 +PIN_PB15,EXT2_PIN10 +- +- +PIN_PB11,EXT2_PIN13 +PIN_PB10,EXT2_PIN14 +PIN_PA17,EXT2_PIN15 +PIN_PA18,EXT2_PIN16 +PIN_PA16,EXT2_PIN17 +PIN_PA19,EXT2_PIN18 + +# EXT3 +PIN_PA02,EXT3_PIN3 +PIN_PA03,EXT3_PIN4 +- +PIN_PA15,EXT3_PIN6 +PIN_PA12,EXT3_PIN7 +PIN_PA13,EXT3_PIN8 +PIN_PA28,EXT3_PIN9 +PIN_PA27,EXT3_PIN10 +- +- +- +- +PIN_PB17,EXT3_PIN15 +PIN_PB22,EXT3_PIN16 +PIN_PB16,EXT3_PIN17 +PIN_PB23,EXT3_PIN18 + +LED_PB30,LED + diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h deleted file mode 100644 index 0b0e878b43e1..000000000000 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[48]; -extern const machine_led_obj_t machine_led_obj[1]; diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c deleted file mode 100644 index d7833416d3c7..000000000000 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in "pins.h" reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - {{&machine_pin_type}, PIN_PB08}, // A0/D0 - {{&machine_pin_type}, PIN_PB09}, // A1/D1 - {{&machine_pin_type}, PIN_PA07}, // A2/D2 - {{&machine_pin_type}, PIN_PB04}, // A3/D3 - {{&machine_pin_type}, PIN_PB05}, // A4/D4 - {{&machine_pin_type}, PIN_PB06}, // A5/D5 - {{&machine_pin_type}, PIN_PA04}, // A6/D6 - {{&machine_pin_type}, PIN_PB07}, // A7/D7 - {{&machine_pin_type}, PIN_PA06}, // A8/D8 - {{&machine_pin_type}, PIN_PD08}, // SWITCH_X - {{&machine_pin_type}, PIN_PD09}, // SWITCH_Y - {{&machine_pin_type}, PIN_PD10}, // SWITCH_Z - {{&machine_pin_type}, PIN_PD12}, // SWITCH_B - {{&machine_pin_type}, PIN_PD20}, // SWITCH_U - {{&machine_pin_type}, PIN_PC26}, // BUTTON_1 - {{&machine_pin_type}, PIN_PC27}, // BUTTON_2 - {{&machine_pin_type}, PIN_PC28}, // BUTTON_3 - {{&machine_pin_type}, PIN_PD11}, // BUZZER_CTR - {{&machine_pin_type}, PIN_PC14}, // 5V_OUTPUT_CTR- enable 5V on hdr - {{&machine_pin_type}, PIN_PC15}, // 3V3_OUTPUT_CTR- enable 3V3 on hdr -}; - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_led_obj_t machine_led_obj[] = { - {{&machine_led_type}, PIN_PA15}, // USER_LED (Blue) - {{&machine_led_type}, PIN_PC05}, // LCD_BACKLIGHT_CTR -}; diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv new file mode 100644 index 000000000000..72da71224a4d --- /dev/null +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv @@ -0,0 +1,30 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +PIN_PB08,A0_D0 +PIN_PB09,A1_D1 +PIN_PA07,A2_D2 +PIN_PB04,A3_D3 +PIN_PB05,A4_D4 +PIN_PB06,A5_D5 +PIN_PA04,A6_D6 +PIN_PB07,A7_D7 +PIN_PA06,A8_D8 +PIN_PD08,SWITCH_X +PIN_PD09,SWITCH_Y +PIN_PD10,SWITCH_Z +PIN_PD12,SWITCH_B +PIN_PD20,SWITCH_U +PIN_PC26,BUTTON_1 +PIN_PC27,BUTTON_2 +PIN_PC28,BUTTON_3 +PIN_PD11,BUZZER_CTR +PIN_PC14,5V_ENABLE +PIN_PC15,3V3_ENABLE + +LED_PA15,LED_BLUE +LED_PC05,LED_LCD diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.h b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.h deleted file mode 100644 index 45ecc254f11e..000000000000 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[20]; -extern const machine_led_obj_t machine_led_obj[2]; diff --git a/ports/samd/boards/SEEED_XIAO/pins.c b/ports/samd/boards/SEEED_XIAO/pins.c deleted file mode 100644 index e2f7c264b4bd..000000000000 --- a/ports/samd/boards/SEEED_XIAO/pins.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c. Holds Board/MCU specific Pin allocations. - */ - -#include "modmachine.h" -#include "sam.h" -#include "pins.h" - -// Ensure Declaration in 'pins.h' reflects # of Pins defined here. -const machine_pin_obj_t machine_pin_obj[] = { - {{&machine_pin_type}, PIN_PA02}, // A0/D0 - {{&machine_pin_type}, PIN_PA04}, // A1/D1 - {{&machine_pin_type}, PIN_PA10}, // A2/D2 - {{&machine_pin_type}, PIN_PA11}, // A3/D3 - {{&machine_pin_type}, PIN_PA08}, // A4/D4 - {{&machine_pin_type}, PIN_PA09}, // A5/D5 - {{&machine_pin_type}, PIN_PB08}, // A6/D6 - {{&machine_pin_type}, PIN_PB09}, // A7/D7 - {{&machine_pin_type}, PIN_PA07}, // A8/D8 - {{&machine_pin_type}, PIN_PA05}, // A9/D9 - {{&machine_pin_type}, PIN_PA06}, // A10/D10 -}; - -const machine_led_obj_t machine_led_obj[] = { -// XIAO: Just the available LED Pins: User LED (PA17), Rx & Tx. - {{&machine_led_type}, PIN_PA17}, // W13 - {{&machine_led_type}, PIN_PA18}, // RX_LED - {{&machine_led_type}, PIN_PA19}, // TX_LED -}; diff --git a/ports/samd/boards/SEEED_XIAO/pins.csv b/ports/samd/boards/SEEED_XIAO/pins.csv new file mode 100644 index 000000000000..8a70a7714563 --- /dev/null +++ b/ports/samd/boards/SEEED_XIAO/pins.csv @@ -0,0 +1,22 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with # are ignored + +PIN_PA02,A0_D0 +PIN_PA04,A1_D1 +PIN_PA10,A2_D2 +PIN_PA11,A3_D3 +PIN_PA08,A4_D4 +PIN_PA09,A5_D5 +PIN_PB08,A6_D6 +PIN_PB09,A7_D7 +PIN_PA07,A8_D8 +PIN_PA05,A9_D9 +PIN_PA06,A10_D10 + +LED_PA17,USER_LED +LED_PA18,RX_LED +LED_PA19,TX_LED diff --git a/ports/samd/boards/SEEED_XIAO/pins.h b/ports/samd/boards/SEEED_XIAO/pins.h deleted file mode 100644 index 226b3f1d7b07..000000000000 --- a/ports/samd/boards/SEEED_XIAO/pins.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2021 Peter van der Burg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Used by machine_pin.c & board specific pins.c. Holds Board/MCU specific Pin - * allocations. - */ - -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_pin_obj_t; - -typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; -} machine_led_obj_t; - -// MUST explicitly hold array # of rows, else machine_pin.c wont compile. -extern const machine_pin_obj_t machine_pin_obj[11]; -extern const machine_led_obj_t machine_led_obj[3]; diff --git a/ports/samd/boards/make-pins.py b/ports/samd/boards/make-pins.py new file mode 100644 index 000000000000..400a9c9b8870 --- /dev/null +++ b/ports/samd/boards/make-pins.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +"""Generates the pins file for the SAMD port.""" + +from __future__ import print_function + +import argparse +import sys +import csv + +pins_header_prefix = """// This file was automatically generated by make-pins.py +// +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; + uint32_t id; + char *name; +} machine_pin_obj_t; + +""" + +led_header_prefix = """typedef struct _machine_led_obj_t { + mp_obj_base_t base; + uint32_t id; + char *name; +} machine_led_obj_t; + +""" + + +class Pins: + def __init__(self): + self.board_pins = [] # list of pin objects + self.board_leds = [] # list of led objects + + def parse_csv_file(self, filename): + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile) + for row in rows: + # Pin numbers must start with "PIN_" + # LED numbers must start with "LED_" + if len(row) > 0: + if row[0].strip().startswith("PIN_"): + if len(row) == 1: + self.board_pins.append([row[0], row[0][4:]]) + else: + self.board_pins.append([row[0], row[1]]) + elif row[0].strip().startswith("LED_"): + self.board_leds.append(["PIN_" + row[0][4:], row[1]]) + elif row[0].strip().startswith("-"): + self.board_pins.append(["-1", ""]) + + def print_pins(self, pins_filename): + with open(pins_filename, "wt") as pins_file: + pins_file.write("// This file was automatically generated by make-pins.py\n") + pins_file.write("//\n") + pins_file.write('#include "modmachine.h"\n') + pins_file.write('#include "sam.h"\n') + pins_file.write('#include "pins.h"\n\n') + + pins_file.write("const machine_pin_obj_t machine_pin_obj[] = {\n") + for pin in self.board_pins: + pins_file.write(" {{&machine_pin_type}, ") + pins_file.write(pin[0] + ', "' + pin[1]) + pins_file.write('"},\n') + pins_file.write("};\n") + + if self.board_leds: + pins_file.write("\nconst machine_led_obj_t machine_led_obj[] = {\n") + for pin in self.board_leds: + pins_file.write(" {{&machine_pin_type}, ") + pins_file.write(pin[0] + ', "' + pin[1]) + pins_file.write('"},\n') + pins_file.write("};\n") + + def print_header(self, hdr_filename): + with open(hdr_filename, "wt") as hdr_file: + hdr_file.write(pins_header_prefix) + if self.board_leds: + hdr_file.write(led_header_prefix) + hdr_file.write( + "extern const machine_pin_obj_t machine_pin_obj[%d];\n" % len(self.board_pins) + ) + if self.board_leds: + hdr_file.write( + "extern const machine_led_obj_t machine_led_obj[%d];\n" % len(self.board_leds) + ) + + +def main(): + parser = argparse.ArgumentParser( + prog="make-pins.py", + usage="%(prog)s [options] [command]", + description="Generate board specific pin file", + ) + parser.add_argument( + "-b", + "--board", + dest="csv_filename", + help="Specifies the pins.csv filename", + ) + parser.add_argument( + "-p", + "--pins", + dest="pins_filename", + help="Specifies the name of the generated pins.c file", + ) + parser.add_argument( + "-i", + "--inc", + dest="hdr_filename", + help="Specifies name of generated pin header file", + ) + args = parser.parse_args(sys.argv[1:]) + + pins = Pins() + + if args.csv_filename: + pins.parse_csv_file(args.csv_filename) + + if args.pins_filename: + pins.print_pins(args.pins_filename) + + pins.print_header(args.hdr_filename) + + +if __name__ == "__main__": + main() From a5d5ecbf8434e480b42a8a477ef9ba7979bba927 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 13:27:12 +0200 Subject: [PATCH 1800/4290] samd/boards: Move mcu-specific settings into a mpconfig_samdXX.h file. Located at the boards directory. That way, the mpconfigboard.h files are almost empty, just setting the board name and the MCU name. --- ports/samd/Makefile | 3 +++ .../mpconfigboard.h | 10 --------- .../mpconfigboard.h | 15 ------------- .../ADAFRUIT_TRINKET_M0/mpconfigboard.h | 10 --------- ports/samd/boards/MINISAM_M4/mpconfigboard.h | 15 ------------- .../SAMD21_XPLAINED_PRO/mpconfigboard.h | 10 --------- .../boards/SEEED_WIO_TERMINAL/mpconfigboard.h | 15 ------------- ports/samd/boards/SEEED_XIAO/mpconfigboard.h | 10 --------- ports/samd/boards/mpconfig_samd21.h | 9 ++++++++ ports/samd/boards/mpconfig_samd51.h | 21 +++++++++++++++++++ ports/samd/mpconfigport.h | 2 ++ 11 files changed, 35 insertions(+), 85 deletions(-) create mode 100644 ports/samd/boards/mpconfig_samd21.h create mode 100644 ports/samd/boards/mpconfig_samd51.h diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 1ef35c1a025e..4dd6356c1e0d 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -50,6 +50,9 @@ CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-a CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += -DMPCONFIG_MCU_H='' + +QSTR_GLOBAL_DEPENDENCIES += boards/mpconfig_$(MCU_SERIES_LOWER).h LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref LDFLAGS += $(LDFLAGS_MOD) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h index bdb22d2e0adf..cec9e9ccdda4 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h @@ -1,12 +1,2 @@ #define MICROPY_HW_BOARD_NAME "Feather M0 Express" #define MICROPY_HW_MCU_NAME "SAMD21G18A" - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 64k Flash storage at top. 256k-64k=196k -// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h index 80baf39e5d6d..2fffc9c7de28 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h @@ -1,17 +1,2 @@ #define MICROPY_HW_BOARD_NAME "ItsyBitsy M4 Express" #define MICROPY_HW_MCU_NAME "SAMD51G19A" - -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) -#define MICROPY_PY_BUILTINS_COMPLEX (0) -#define MICROPY_PY_MATH (0) -#define MICROPY_PY_CMATH (0) - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 -// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h index 066c7ee1429e..d3a6ba2d8687 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/mpconfigboard.h @@ -1,12 +1,2 @@ #define MICROPY_HW_BOARD_NAME "Trinket M0" #define MICROPY_HW_MCU_NAME "SAMD21E18A" - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 64k Flash storage at top. 256k-64k=196k -// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/MINISAM_M4/mpconfigboard.h b/ports/samd/boards/MINISAM_M4/mpconfigboard.h index a8f1f96242c8..6715a16f0145 100644 --- a/ports/samd/boards/MINISAM_M4/mpconfigboard.h +++ b/ports/samd/boards/MINISAM_M4/mpconfigboard.h @@ -1,17 +1,2 @@ #define MICROPY_HW_BOARD_NAME "Mini SAM M4" #define MICROPY_HW_MCU_NAME "SAMD51G19A" - -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) -#define MICROPY_PY_BUILTINS_COMPLEX (0) -#define MICROPY_PY_MATH (0) -#define MICROPY_PY_CMATH (0) - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 -// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h index 860cb6b97778..c69b5b4c149d 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h @@ -1,12 +1,2 @@ #define MICROPY_HW_BOARD_NAME "SAMD21-XPLAINED-PRO" #define MICROPY_HW_MCU_NAME "SAMD21J18A" - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 64k Flash storage at top. 256k-64k=196k -// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h index bb0f1c828e78..cfda18d11c96 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.h @@ -1,17 +1,2 @@ #define MICROPY_HW_BOARD_NAME "Wio Terminal D51R" #define MICROPY_HW_MCU_NAME "SAMD51P19A" - -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) -#define MICROPY_PY_BUILTINS_COMPLEX (0) -#define MICROPY_PY_MATH (0) -#define MICROPY_PY_CMATH (0) - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 -// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h index a2f2a9fb0b01..2026efc6b153 100644 --- a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h +++ b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h @@ -1,12 +1,2 @@ #define MICROPY_HW_BOARD_NAME "Seeed Xiao" #define MICROPY_HW_MCU_NAME "SAMD21G18A" - -// MicroPython configs -// samd_flash.c flash parameters -// Build a 64k Flash storage at top. 256k-64k=196k -// 256*1024=262144 minus 64*1024=65536 = 196608 = 0x30000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; - -#define CPU_FREQ (48000000) // For selecting Baud from clock. diff --git a/ports/samd/boards/mpconfig_samd21.h b/ports/samd/boards/mpconfig_samd21.h new file mode 100644 index 000000000000..1924f66f0604 --- /dev/null +++ b/ports/samd/boards/mpconfig_samd21.h @@ -0,0 +1,9 @@ +// Deinitions common to all SAMD21 boards +#include "samd21.h" + +#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +#define CPU_FREQ (48000000) +#define APB_FREQ (48000000) diff --git a/ports/samd/boards/mpconfig_samd51.h b/ports/samd/boards/mpconfig_samd51.h new file mode 100644 index 000000000000..1b67b1d02d5c --- /dev/null +++ b/ports/samd/boards/mpconfig_samd51.h @@ -0,0 +1,21 @@ +// Deinitions common to all SAMD51 boards +#include "samd51.h" + +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_PY_BUILTINS_COMPLEX (0) +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_CMATH (0) + +// Due to a limitation in the TC counter for us, the ticks period is 2**29 +#define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) +// MicroPython configs +// samd_flash.c flash parameters +// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 +// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 +#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // + +#define CPU_FREQ (120000000) +#define APB_FREQ (48000000) +#define DPLLx_REF_FREQ (32768) diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 2c6052149ba3..c29043c5d0a2 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -28,6 +28,8 @@ // Board specific definitions #include "mpconfigboard.h" +// MCU-Specific definitions +#include MPCONFIG_MCU_H // Memory allocation policies #define MICROPY_GC_STACK_ENTRY_TYPE uint16_t From c4f7c0b8a2504e8a13644ea692c4a66d6f124871 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 16:16:22 +0200 Subject: [PATCH 1801/4290] samd/Makefile: Alphabetically sort the source code files in Makefile. --- ports/samd/Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 4dd6356c1e0d..66e23bae69d0 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -83,16 +83,16 @@ LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif SRC_C = \ - main.c \ help.c \ + machine_led.c \ + machine_pin.c \ + main.c \ modutime.c \ modmachine.c \ - $(BUILD)/pins.c \ - machine_pin.c \ - machine_led.c \ modsamd.c \ - samd_flash.c \ mphalport.c \ + $(BUILD)/pins.c \ + samd_flash.c \ samd_isr.c \ samd_soc.c \ tusb_port.c \ @@ -130,10 +130,10 @@ endif # List of sources for qstr extraction SRC_QSTR += \ + machine_led.c \ + machine_pin.c \ modutime.c \ modmachine.c \ - machine_pin.c \ - machine_led.c \ modsamd.c \ samd_flash.c \ shared/readline/readline.c \ From 949a808076f10f9f7e25fd9ebe4a03b8cc397e1f Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 15:42:56 +0200 Subject: [PATCH 1802/4290] samd/boards: Add ADAFRUIT_FEATHER_M4_EXPRESS and _ITSYBITSY_M0_EXPRESS. These two boards are used for testing, so it is favorable to have them added early. The full test set is: - ADAFRUIT_FEATHER_M4_EXPRESS: SAMD51 with 32kHz crystal. - ADAFRUIT_ITSYBITSY_M0_EXPRESS: SAMD21 without crystal. - ADAFRUIT_ITSYBITSY_M4_EXPRESS: SAMD51 without crystal. - SEEED_XIAO: SAM21 with 32kHz crystal. --- .../ADAFRUIT_FEATHER_M4_EXPRESS/board.json | 22 ++++++++++ .../mpconfigboard.h | 2 + .../mpconfigboard.mk | 8 ++++ .../ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv | 34 ++++++++++++++++ .../ADAFRUIT_ITSYBITSY_M0_EXPRESS/board.json | 20 ++++++++++ .../mpconfigboard.h | 2 + .../mpconfigboard.mk | 8 ++++ .../ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv | 40 +++++++++++++++++++ ports/samd/boards/samd51j19a.ld | 17 ++++++++ 9 files changed, 153 insertions(+) create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/board.json create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk create mode 100644 ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/board.json create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.mk create mode 100644 ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv create mode 100644 ports/samd/boards/samd51j19a.ld diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/board.json new file mode 100644 index 000000000000..c8042aa25473 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/board.json @@ -0,0 +1,22 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Feather", + "Micro USB", + "RGB LED", + "SPI Flash" + ], + "images": [ + "feather_m4_express.jpg" + ], + "mcu": "samd51", + "product": "Feather M4 Express", + "thumbnail": "", + "url": "https://www.adafruit.com/product/3857", + "vendor": "Adafruit" +} diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h new file mode 100644 index 000000000000..48599eec4729 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h @@ -0,0 +1,2 @@ +#define MICROPY_HW_BOARD_NAME "Feather M4 Express" +#define MICROPY_HW_MCU_NAME "SAMD51J19A" diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk new file mode 100644 index 000000000000..d29e2b1097b1 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk @@ -0,0 +1,8 @@ +MCU_SERIES = SAMD51 +CMSIS_MCU = SAMD51J19A +LD_FILES = boards/samd51j19a.ld sections.ld +TEXT0 = 0x4000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv new file mode 100644 index 000000000000..5b999c39e022 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv @@ -0,0 +1,34 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines starting with PIN_ or LED_ are ignored + +PIN_PB17,D0 +PIN_PB16,D1 +PIN_PA14,D4 +PIN_PA16,D5 +PIN_PA18,D6 +- +PIN_PB03,D8 +PIN_PA19,D9 +PIN_PA20,D10 +PIN_PA21,D11 +PIN_PA22,D12 +PIN_PA23,D13 +PIN_PA02,A0 +PIN_PA05,A1 +PIN_PB08,A2 +PIN_PB09,A3 +PIN_PA04,A4 +PIN_PB06,A5 +PIN_PA13,SCL +PIN_PA12,SDA +PIN_PB23,MOSI +PIN_PB22,MISO +PIN_PA17,SCK +PIN_PB01,VDIV +PIN_PA03,AREF + +LED_PA17,LED diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/board.json new file mode 100644 index 000000000000..f99d19ca87f8 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/board.json @@ -0,0 +1,20 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Breadboard Friendly", + "Micro USB", + "RGB LED", + "SPI Flash" + ], + "images": [ + "itsybitsy_m0_express.jpg" + ], + "mcu": "samd21", + "product": "ItsyBitsy M0 Express", + "thumbnail": "", + "url": "https://www.adafruit.com/product/3727", + "vendor": "Adafruit" +} diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h new file mode 100644 index 000000000000..d647af9312ed --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h @@ -0,0 +1,2 @@ +#define MICROPY_HW_BOARD_NAME "ItsyBitsy M0 Express" +#define MICROPY_HW_MCU_NAME "SAMD21G18A" diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.mk new file mode 100644 index 000000000000..a760cf047e62 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.mk @@ -0,0 +1,8 @@ +MCU_SERIES = SAMD21 +CMSIS_MCU = SAMD21G18A +LD_FILES = boards/samd21x18a.ld sections.ld +TEXT0 = 0x2000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv new file mode 100644 index 000000000000..50c3c1cf68f5 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv @@ -0,0 +1,40 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines not starting with PIN_ or LED_ are ignored + +PIN_PA11,D0 +PIN_PA10,D1 +PIN_PA14,D2 +PIN_PB09,D3 +PIN_PA08,D4 +PIN_PA15,D5 +- +PIN_PA21,D7 +- +PIN_PA07,D9 +PIN_PA18,D10 +PIN_PA16,D11 +PIN_PA19,D12 +PIN_PA17,D13 +PIN_PA02,A0 +PIN_PB08,A1 +PIN_PB09,A2 +PIN_PA04,A3 +PIN_PA05,A4 +PIN_PB02,A5 +PIN_PA22,SDA +PIN_PA23,SCL +PIN_PB10,MO +PIN_PA12,MI +PIN_PB11,SCK +PIN_PA00,DOTSTAR_CLK +PIN_PA01,DOTSTAR_DATA +PIN_PB22,FLASH_MOSI +PIN_PB03,FLASH_MISO +PIN_PB23,FLASH_SCK +PIN_PA27,FLASH_CS + +LED_PA17,LED diff --git a/ports/samd/boards/samd51j19a.ld b/ports/samd/boards/samd51j19a.ld new file mode 100644 index 000000000000..e0baa9bba028 --- /dev/null +++ b/ports/samd/boards/samd51j19a.ld @@ -0,0 +1,17 @@ +/* + GNU linker script for SAMD51 +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 512K - 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K +} + +/* Top end of the stack, with room for double-tap variable */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_sstack = _estack - 16K; + +_sheap = _ebss; +_eheap = _sstack; From b4d29fd47a52526bc9626e5dc28794fa1d95dcf2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 16:31:46 +0200 Subject: [PATCH 1803/4290] samd/clock_config: Set up the clock configuration. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clock settings: - GCLK0: 48 MHz (SAMD21) or 120 MHz(SAMD51). - GCLK1: 32768 Hz for driving the PLL. - GCLK2: 48 MHz for tzhe peripheral clock. - GCLK3: 1 MHz (SAMD21) or 8 MHz (SAMD51) for the µs ticks timer. - GCLK8: 1 kHz for WDT (SAMD21 only). If a 32 kHz crystal is present, it will be used as clock source. Otherwise the DFLL48M in open-loop mode is used. GCLK0 for SAM51 can be changed between 48 MHz and 200 MHz. The specified range is 96 MHz - 120 MHz. --- ports/samd/Makefile | 1 + ports/samd/clock_config.c | 348 ++++++++++++++++++++++++++++++++++++++ ports/samd/clock_config.h | 33 ++++ ports/samd/samd_soc.c | 64 ++++--- ports/samd/samd_soc.h | 11 ++ 5 files changed, 430 insertions(+), 27 deletions(-) create mode 100644 ports/samd/clock_config.c create mode 100644 ports/samd/clock_config.h diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 66e23bae69d0..e3316a9d6c11 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -83,6 +83,7 @@ LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif SRC_C = \ + clock_config.c \ help.c \ machine_led.c \ machine_pin.c \ diff --git a/ports/samd/clock_config.c b/ports/samd/clock_config.c new file mode 100644 index 000000000000..0f5634fdb737 --- /dev/null +++ b/ports/samd/clock_config.c @@ -0,0 +1,348 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * This file provides functions for configuring the clocks. + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "samd_soc.h" + +static uint32_t cpu_freq = CPU_FREQ; +static uint32_t apb_freq = APB_FREQ; + +#if defined(MCU_SAMD21) +int sercom_gclk_id[] = { + GCLK_CLKCTRL_ID_SERCOM0_CORE, GCLK_CLKCTRL_ID_SERCOM1_CORE, + GCLK_CLKCTRL_ID_SERCOM2_CORE, GCLK_CLKCTRL_ID_SERCOM3_CORE, + GCLK_CLKCTRL_ID_SERCOM4_CORE, GCLK_CLKCTRL_ID_SERCOM5_CORE +}; +#elif defined(MCU_SAMD51) +int sercom_gclk_id[] = { + SERCOM0_GCLK_ID_CORE, SERCOM1_GCLK_ID_CORE, + SERCOM2_GCLK_ID_CORE, SERCOM3_GCLK_ID_CORE, + SERCOM4_GCLK_ID_CORE, SERCOM5_GCLK_ID_CORE, + #if defined(SERCOM7_GCLK_ID_CORE) + SERCOM6_GCLK_ID_CORE, SERCOM7_GCLK_ID_CORE, + #endif +}; +#endif + +uint32_t get_cpu_freq(void) { + return cpu_freq; +} + +uint32_t get_apb_freq(void) { + return apb_freq; +} + +#if defined(MCU_SAMD21) +void set_cpu_freq(uint32_t cpu_freq_arg) { + cpu_freq = cpu_freq_arg; +} + +#elif defined(MCU_SAMD51) +void set_cpu_freq(uint32_t cpu_freq_arg) { + cpu_freq = cpu_freq_arg; + + // Setup GCLK0 for 48MHz as default state to keep the MCU running during config change. + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL0) { + } + + // Setup DPLL0 for 120 MHz + // first: disable DPLL0 in case it is running + OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = 0; + while (OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.ENABLE == 1) { + } + // Now configure the registers + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(1) | OSCCTRL_DPLLCTRLB_LBYPASS | + OSCCTRL_DPLLCTRLB_REFCLK(0) | OSCCTRL_DPLLCTRLB_WUF | OSCCTRL_DPLLCTRLB_FILTER(0x01); + + uint32_t div = cpu_freq / DPLLx_REF_FREQ; + uint32_t frac = (cpu_freq - div * DPLLx_REF_FREQ) / (DPLLx_REF_FREQ / 32); + OSCCTRL->Dpll[0].DPLLRATIO.reg = (frac << 16) + div - 1; + // enable it again + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | OSCCTRL_DPLLCTRLA_RUNSTDBY; + + // Per errata 2.13.1 + while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 1)) { + } + + // Setup GCLK0 for DPLL0 output (48 or 48-200MHz) + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DPLL0; + while (GCLK->SYNCBUSY.bit.GENCTRL0) { + } +} +#endif + +void init_clocks(uint32_t cpu_freq) { + #if defined(MCU_SAMD21) + + // SAMD21 Clock settings + // GCLK0: 48MHz from DFLL open loop mode or closed loop mode from 32k Crystal + // GCLK1: 32768 Hz from 32K ULP or 32k Crystal + // GCLK2: 48MHz from DFLL for Peripherals + // GCLK3: 1Mhz for the us-counter (TC3/TC4) + // GCLK8: 1kHz clock for WDT + + NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" + NVMCTRL->CTRLB.bit.RWS = 1; // 1 read wait state for 48MHz + + #if MICROPY_HW_XOSC32K + // Set up OSC32K according datasheet 17.6.3 + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP(0x3) | SYSCTRL_XOSC32K_EN32K | + SYSCTRL_XOSC32K_XTALEN; + SYSCTRL->XOSC32K.bit.ENABLE = 1; + while (SYSCTRL->PCLKSR.bit.XOSC32KRDY == 0) { + } + // Set up the DFLL48 according to the data sheet 17.6.7.1.2 + // Step 1: Set up the reference clock + // Connect the OSC32K via GCLK1 to the DFLL input and for further use. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(1); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_DFLL48 | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_CLKEN; + // Enable access to the DFLLCTRL reg acc. to Errata 1.2.1 + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; + while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { + } + // Step 2: Set the coarse and fine values. + // The coarse setting will be taken from the calibration data. So the value used here + // does not matter. Get the coarse value from the calib data. In case it is not set, + // set a midrange value. + uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) + >> FUSES_DFLL48M_COARSE_CAL_Pos; + if (coarse == 0x3f) { + coarse = 0x1f; + } + SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); + while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { + } + // Step 3: Set the multiplication values. The offset of 16384 to the freq is for rounding. + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_MUL((CPU_FREQ + 16384) / 32768) | + SYSCTRL_DFLLMUL_FSTEP(1) | SYSCTRL_DFLLMUL_CSTEP(1); + while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { + } + // Step 4: Start the DFLL and wait for the PLL lock. We just wait for the fine lock, since + // coarse adjusting is bypassed. + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK | + SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_ENABLE; + while (SYSCTRL->PCLKSR.bit.DFLLLCKF == 0) { + } + + #else // MICROPY_HW_XOSC32K + + // Enable DFLL48M + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { + } + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | SYSCTRL_DFLLMUL_FSTEP(1) + | SYSCTRL_DFLLMUL_MUL(48000); + uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) + >> FUSES_DFLL48M_COARSE_CAL_Pos; + if (coarse == 0x3f) { + coarse = 0x1f; + } + SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_USBCRM + | SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_ENABLE; + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { + } + // Enable 32768 Hz on GCLK1 for consistency + GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(48016384 / 32768); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(1); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + #endif // MICROPY_HW_XOSC32K + + // Enable GCLK output: 48M on both CCLK0 and GCLK2 + GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(2); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + // Enable GCLK output: 1MHz on GCLK3 for TC3 + GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(48); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(3); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + // Set GCLK8 to 1 kHz. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + #elif defined(MCU_SAMD51) + + // SAMD51 clock settings + // GCLK0: 48MHz from DFLL48M or 48 - 200 MHz from DPLL0 (SAMD51) + // GCLK1: DPLLx_REF_FREQ 32768 Hz from 32KULP or 32k Crystal + // GCLK2: 48MHz from DFLL48M for Peripheral devices + // GCLK3: 16Mhz for the us-counter (TC0/TC1) + // DPLL0: 48 - 200 MHz + + // Steps to set up clocks: + // Reset Clocks + // Switch GCLK0 to DFLL 48MHz + // Setup 32768 Hz source and DFLL48M in closed loop mode, if a crystal is present. + // Setup GCLK1 to the DPLL0 Reference freq. of 32768 Hz + // Setup GCLK1 to drive peripheral channel 1 + // Setup DPLL0 to 120MHz + // Setup GCLK0 to 120MHz + // Setup GCLK2 to 48MHz for Peripherals + // Setup GCLK3 to 8MHz for TC0/TC1 + + // Setup GCLK0 for 48MHz as default state to keep the MCU running during config change. + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL0) { + } + + #if MICROPY_HW_XOSC32K + // OSCILLATOR CONTROL + // Setup XOSC32K + OSC32KCTRL->INTFLAG.reg = OSC32KCTRL_INTFLAG_XOSC32KRDY | OSC32KCTRL_INTFLAG_XOSC32KFAIL; + OSC32KCTRL->XOSC32K.bit.CGM = OSC32KCTRL_XOSC32K_CGM_HS_Val; + OSC32KCTRL->XOSC32K.bit.XTALEN = 1; // 0: Generator 1: Crystal + OSC32KCTRL->XOSC32K.bit.EN32K = 1; + OSC32KCTRL->XOSC32K.bit.ONDEMAND = 0; + OSC32KCTRL->XOSC32K.bit.RUNSTDBY = 1; + OSC32KCTRL->XOSC32K.bit.STARTUP = 4; + OSC32KCTRL->CFDCTRL.bit.CFDEN = 1; // Fall back to internal Osc on crystal fail + OSC32KCTRL->XOSC32K.bit.ENABLE = 1; + // make sure osc32kcrtl is ready + while (OSC32KCTRL->STATUS.bit.XOSC32KRDY == 0) { + } + + // Setup GCLK1 for 32kHz crystal + GCLK->GENCTRL[1].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K; + while (GCLK->SYNCBUSY.bit.GENCTRL1) { + } + + // Set-up the DFLL48M in closed loop mode with input from the 32kHz crystal + + // Step 1: Peripheral channel 0 is driven by GCLK1 and it feeds DFLL48M + GCLK->PCHCTRL[0].reg = GCLK_PCHCTRL_GEN_GCLK1 | GCLK_PCHCTRL_CHEN; + while (GCLK->PCHCTRL[0].bit.CHEN == 0) { + } + // Step 2: Set the multiplication values. The offset of 16384 to the freq is for rounding. + OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_MUL((APB_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) | + OSCCTRL_DFLLMUL_FSTEP(1) | OSCCTRL_DFLLMUL_CSTEP(1); + while (OSCCTRL->DFLLSYNC.bit.DFLLMUL == 1) { + } + // Step 3: Set the mode to closed loop + OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_BPLCKC | OSCCTRL_DFLLCTRLB_MODE; + while (OSCCTRL->DFLLSYNC.bit.DFLLCTRLB == 1) { + } + // Wait for lock fine + while (OSCCTRL->STATUS.bit.DFLLLCKF == 0) { + } + // Step 4: Start the DFLL. + OSCCTRL->DFLLCTRLA.reg = OSCCTRL_DFLLCTRLA_RUNSTDBY | OSCCTRL_DFLLCTRLA_ENABLE; + while (OSCCTRL->DFLLSYNC.bit.ENABLE == 1) { + } + + #else // MICROPY_HW_XOSC32K + + // Set GCLK1 to DPLL0_REF_FREQ as defined in mpconfigboard.h (e.g. 32768 Hz) + GCLK->GENCTRL[1].reg = ((APB_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) << GCLK_GENCTRL_DIV_Pos + | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL1) { + } + + #endif // MICROPY_HW_XOSC32K + + // Peripheral channel 1 is driven by GCLK1 and it feeds DPLL0 + GCLK->PCHCTRL[1].reg = GCLK_PCHCTRL_GEN_GCLK1 | GCLK_PCHCTRL_CHEN; + while (GCLK->PCHCTRL[1].bit.CHEN == 0) { + } + + set_cpu_freq(cpu_freq); + + apb_freq = APB_FREQ; // To be changed if CPU_FREQ < 48M + + // Setup GCLK2 for DPLL1 output (48 MHz) + GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL2) { + } + + // Setup GCLK3 for 8MHz, Used for TC0/1 counter + GCLK->GENCTRL[3].reg = GCLK_GENCTRL_DIV(6) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL3) { + } + + #endif // defined(MCU_SAMD51) +} + +void enable_sercom_clock(int id) { + // Next: Set up the clocks + #if defined(MCU_SAMD21) + // Enable synchronous clock. The bits are nicely arranged + PM->APBCMASK.reg |= 0x04 << id; + // Select multiplexer generic clock source and enable. + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | sercom_gclk_id[id]; + // Wait while it updates synchronously. + while (GCLK->STATUS.bit.SYNCBUSY) { + } + #elif defined(MCU_SAMD51) + GCLK->PCHCTRL[sercom_gclk_id[id]].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; + // no easy way to set the clocks, except enabling all of them + switch (id) { + case 0: + MCLK->APBAMASK.bit.SERCOM0_ = 1; + break; + case 1: + MCLK->APBAMASK.bit.SERCOM1_ = 1; + break; + case 2: + MCLK->APBBMASK.bit.SERCOM2_ = 1; + break; + case 3: + MCLK->APBBMASK.bit.SERCOM3_ = 1; + break; + case 4: + MCLK->APBDMASK.bit.SERCOM4_ = 1; + break; + case 5: + MCLK->APBDMASK.bit.SERCOM5_ = 1; + break; + #ifdef SERCOM7_GCLK_ID_CORE + case 6: + MCLK->APBDMASK.bit.SERCOM6_ = 1; + break; + case 7: + MCLK->APBDMASK.bit.SERCOM7_ = 1; + break; + #endif + } + #endif +} diff --git a/ports/samd/clock_config.h b/ports/samd/clock_config.h new file mode 100644 index 000000000000..0e7a9e3280ec --- /dev/null +++ b/ports/samd/clock_config.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * This file provides functions for configuring the clocks. + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +void init_clocks(uint32_t cpu_freq); +void set_cpu_freq(uint32_t cpu_freq); +uint32_t get_cpu_freq(void); +uint32_t get_apb_freq(void); +void enable_sercom_clock(int id); diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 7a96cbb4800f..8d6e808f6390 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -10,6 +10,7 @@ * The MIT License (MIT) * * Copyright (c) 2019 Damien P. George + * Copyright (c) 2022 Robert Hammelrath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,6 +34,7 @@ #include "py/runtime.h" #include "modmachine.h" #include "samd_soc.h" +#include "sam.h" #include "tusb.h" static void usb_init(void) { @@ -43,7 +45,7 @@ static void usb_init(void) { PM->APBBMASK.bit.USB_ = 1; uint8_t alt = 6; // alt G, USB #elif defined(MCU_SAMD51) - GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK1; + GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; while (GCLK->PCHCTRL[USB_GCLK_ID].bit.CHEN == 0) { } MCLK->AHBMASK.bit.USB_ = 1; @@ -61,43 +63,51 @@ static void usb_init(void) { tusb_init(); } -void samd_init(void) { +// Initialize the microsecond counter on TC 0/1 +void init_us_counter(void) { #if defined(MCU_SAMD21) - NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" - NVMCTRL->CTRLB.bit.RWS = 1; // 1 read wait state for 48MHz - - // Enable DFLL48M - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; - while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { - } - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | SYSCTRL_DFLLMUL_FSTEP(1) - | SYSCTRL_DFLLMUL_MUL(48000); - uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) - >> FUSES_DFLL48M_COARSE_CAL_Pos; - if (coarse == 0x3f) { - coarse = 0x1f; - } - uint32_t fine = 512; - SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(fine); - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_USBCRM - | SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_ENABLE; - while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { + PM->APBCMASK.bit.TC3_ = 1; // Enable TC3 clock + PM->APBCMASK.bit.TC4_ = 1; // Enable TC4 clock + // Select multiplexer generic clock source and enable. + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID_TC4_TC5; + // Wait while it updates synchronously. + while (GCLK->STATUS.bit.SYNCBUSY) { } - GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(1); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0); - while (GCLK->STATUS.bit.SYNCBUSY) { + // configure the timer + TC4->COUNT32.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT32_Val; + TC4->COUNT32.CTRLA.bit.RUNSTDBY = 1; + TC4->COUNT32.CTRLA.bit.ENABLE = 1; + while (TC4->COUNT32.STATUS.bit.SYNCBUSY) { + } + TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ | TC_READREQ_RCONT | 0x10; + while (TC4->COUNT32.STATUS.bit.SYNCBUSY) { } #elif defined(MCU_SAMD51) - GCLK->GENCTRL[1].reg = 1 << GCLK_GENCTRL_DIV_Pos | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; - while (GCLK->SYNCBUSY.bit.GENCTRL1) { + MCLK->APBAMASK.bit.TC0_ = 1; // Enable TC0 clock + MCLK->APBAMASK.bit.TC1_ = 1; // Enable TC1 clock + // Peripheral channel 9 is driven by GCLK3, 8 MHz. + GCLK->PCHCTRL[TC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK3 | GCLK_PCHCTRL_CHEN; + while (GCLK->PCHCTRL[TC0_GCLK_ID].bit.CHEN == 0) { + } + + // configure the timer + TC0->COUNT32.CTRLA.bit.PRESCALER = 0; + TC0->COUNT32.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT32_Val; + TC0->COUNT32.CTRLA.bit.RUNSTDBY = 1; + TC0->COUNT32.CTRLA.bit.ENABLE = 1; + while (TC0->COUNT32.SYNCBUSY.bit.ENABLE) { } #endif +} - SysTick_Config(CPU_FREQ / 1000); +void samd_init(void) { + init_clocks(get_cpu_freq()); + SysTick_Config(get_cpu_freq() / 1000); + init_us_counter(); usb_init(); } diff --git a/ports/samd/samd_soc.h b/ports/samd/samd_soc.h index a07e68dbed64..b97159dc7fc5 100644 --- a/ports/samd/samd_soc.h +++ b/ports/samd/samd_soc.h @@ -28,6 +28,7 @@ #include #include "sam.h" +#include "clock_config.h" void samd_init(void); void samd_main(void); @@ -38,4 +39,14 @@ void USB_1_Handler_wrapper(void); void USB_2_Handler_wrapper(void); void USB_3_Handler_wrapper(void); +void common_uart_irq_handler(int uart_nr); +void common_spi_irq_handler(int spi_nr); +void common_i2c_irq_handler(int i2c_nr); +void sercom_enable(Sercom *spi, int state); +void sercom_register_irq(int sercom_id, int mode); + +#define SERCOM_IRQ_TYPE_UART (0) +#define SERCOM_IRQ_TYPE_SPI (1) +#define SERCOM_IRQ_TYPE_I2C (2) + #endif // MICROPY_INCLUDED_SAMD_SAMD_SOC_H From 5af54ad61feb52f4c1367d6f9a8a60d972f02419 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 17:00:32 +0200 Subject: [PATCH 1804/4290] samd/modmachine: Allow changing the CPU freq with machine.freq(f). SAMD51 only. Accepted values are 48_000_000 to 200_000_000. The range specified by Atmel is 96_000_000 to 120_000_000. --- ports/samd/modmachine.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 1b78b687e180..99fccf5bf008 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -59,10 +59,21 @@ STATIC mp_obj_t machine_bootloader(void) { } MP_DEFINE_CONST_FUN_OBJ_0(machine_bootloader_obj, machine_bootloader); -STATIC mp_obj_t machine_freq(void) { - return MP_OBJ_NEW_SMALL_INT(CPU_FREQ); +STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return MP_OBJ_NEW_SMALL_INT(get_cpu_freq()); + } else { + #if defined(MCU_SAMD51) + uint32_t freq = mp_obj_get_int(args[0]); + if (freq >= 48000000 && freq <= 200000000) { + set_cpu_freq(freq); + SysTick_Config(freq / 1000); + } + #endif + return mp_const_none; + } } -MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq); STATIC mp_obj_t machine_unique_id(void) { // Each device has a unique 128-bit serial number which is a concatenation of four 32-bit From 3d9940bc28e66464e22386916cb71100d6b24f1d Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 18:09:11 +0200 Subject: [PATCH 1805/4290] samd/mphalport: Add pin open-drain funcs, and improve delay and ticks. The changes in this commit are: - Add an interface for pin open-drain mode. - Improve ticks_us() by using the us-counter. - Improve ticks_cpu() by using the CPU's SysTick. --- ports/samd/mphalport.c | 47 ++++++++++++++++++++++++++++-------- ports/samd/mphalport.h | 54 +++++++++++++++++++++++++++++++++++------- 2 files changed, 82 insertions(+), 19 deletions(-) diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index beade14a6e3d..e51f13ab7e9f 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2019 Damien P. George + * Copyright (c) 2022 Robert Hammelrath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,10 +28,13 @@ #include "py/runtime.h" #include "py/mphal.h" #include "py/stream.h" +#include "shared/runtime/interrupt_char.h" +#include "extmod/misc.h" #include "samd_soc.h" #include "tusb.h" #if MICROPY_KBD_EXCEPTION +int mp_interrupt_char = -1; void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; @@ -40,24 +44,47 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { } void mp_hal_set_interrupt_char(int c) { + mp_interrupt_char = c; tud_cdc_set_wanted_char(c); } #endif +void mp_hal_set_pin_mux(mp_hal_pin_obj_t pin, uint8_t mux) { + int pin_grp = pin / 32; + int port_grp = (pin % 32) / 2; + PORT->Group[pin_grp].PINCFG[pin % 32].bit.PMUXEN = 1; // Enable Mux + if (pin & 1) { + PORT->Group[pin_grp].PMUX[port_grp].bit.PMUXO = mux; + } else { + PORT->Group[pin_grp].PMUX[port_grp].bit.PMUXE = mux; + } +} + + void mp_hal_delay_ms(mp_uint_t ms) { - ms += 1; - uint32_t t0 = systick_ms; - while (systick_ms - t0 < ms) { - MICROPY_EVENT_POLL_HOOK + if (ms > 10) { + uint32_t t0 = systick_ms; + while (systick_ms - t0 < ms) { + MICROPY_EVENT_POLL_HOOK + } + } else { + mp_hal_delay_us(ms * 1000); } } void mp_hal_delay_us(mp_uint_t us) { - uint32_t ms = us / 1000 + 1; - uint32_t t0 = systick_ms; - while (systick_ms - t0 < ms) { - __WFI(); + if (us > 0) { + uint32_t start = mp_hal_ticks_us(); + #if defined(MCU_SAMD21) + // SAMD21 counter has effective 32 bit width + while ((mp_hal_ticks_us() - start) < us) { + } + #elif defined(MCU_SAMD51) + // SAMD51 counter has effective 29 bit width + while (((mp_hal_ticks_us() - start) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)) < us) { + } + #endif } } @@ -78,7 +105,7 @@ int mp_hal_stdin_rx_chr(void) { return buf[0]; } } - __WFI(); + MICROPY_EVENT_POLL_HOOK } } @@ -90,7 +117,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { n = CFG_TUD_CDC_EP_BUFSIZE; } while (n > tud_cdc_write_available()) { - __WFI(); + MICROPY_EVENT_POLL_HOOK } uint32_t n2 = tud_cdc_write(str + i, n); tud_cdc_write_flush(); diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index 2bbde4390e33..b18aa2f9b435 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2019-2021 Damien P. George + * Copyright (c) 2022 Robert Hammelrath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,25 +28,49 @@ #define MICROPY_INCLUDED_SAMD_MPHALPORT_H #include "py/mpconfig.h" -#include "py/ringbuf.h" // ASF4 #include "hal_gpio.h" +#include "hpl_time_measure.h" +#include "sam.h" extern int mp_interrupt_char; -extern ringbuf_t stdin_ringbuf; extern volatile uint32_t systick_ms; +extern volatile uint32_t systick_ms_upper; void mp_hal_set_interrupt_char(int c); +#define mp_hal_delay_us_fast mp_hal_delay_us + static inline mp_uint_t mp_hal_ticks_ms(void) { return systick_ms; } + static inline mp_uint_t mp_hal_ticks_us(void) { + #if defined(MCU_SAMD21) + + return REG_TC4_COUNT32_COUNT; + + #elif defined(MCU_SAMD51) + + TC0->COUNT32.CTRLBSET.reg = TC_CTRLBSET_CMD_READSYNC; + while (TC0->COUNT32.CTRLBSET.reg != 0) { + } + return REG_TC0_COUNT32_COUNT >> 3; + + #else return systick_ms * 1000; + #endif } + +// ticks_cpu is limited to a 1 ms period, since the CPU SysTick counter +// is used for the 1 ms SysTick_Handler interrupt. static inline mp_uint_t mp_hal_ticks_cpu(void) { - return 0; + return (system_time_t)SysTick->VAL; +} + +static inline uint64_t mp_hal_time_ns(void) { + return ((uint64_t)systick_ms + (uint64_t)systick_ms_upper * 0x100000000) * 1000000; } // C-level pin HAL @@ -55,9 +80,10 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { #define MP_HAL_PIN_FMT "%u" #define mp_hal_pin_obj_t uint -extern uint32_t machine_pin_open_drain_mask; +extern uint32_t machine_pin_open_drain_mask[]; mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in); +void mp_hal_set_pin_mux(mp_hal_pin_obj_t pin, uint8_t mux); static inline unsigned int mp_hal_pin_name(mp_hal_pin_obj_t pin) { return pin; @@ -65,18 +91,22 @@ static inline unsigned int mp_hal_pin_name(mp_hal_pin_obj_t pin) { static inline void mp_hal_pin_input(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); - machine_pin_open_drain_mask &= ~(1 << pin); + machine_pin_open_drain_mask[pin / 32] &= ~(1 << (pin % 32)); } static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT); - machine_pin_open_drain_mask &= ~(1 << pin); + machine_pin_open_drain_mask[pin / 32] &= ~(1 << (pin % 32)); } static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); gpio_set_pin_level(pin, 0); - machine_pin_open_drain_mask |= 1 << pin; + machine_pin_open_drain_mask[pin / 32] |= 1 << (pin % 32); +} + +static inline unsigned int mp_hal_get_pin_direction(mp_hal_pin_obj_t pin) { + return (PORT->Group[pin / 32].DIR.reg & (1 << (pin % 32))) >> (pin % 32); } static inline int mp_hal_pin_read(mp_hal_pin_obj_t pin) { @@ -87,7 +117,14 @@ static inline void mp_hal_pin_write(mp_hal_pin_obj_t pin, int v) { gpio_set_pin_level(pin, v); } -/* +static inline void mp_hal_pin_low(mp_hal_pin_obj_t pin) { + gpio_set_pin_level(pin, 0); +} + +static inline void mp_hal_pin_high(mp_hal_pin_obj_t pin) { + gpio_set_pin_level(pin, 1); +} + static inline void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT); } @@ -95,6 +132,5 @@ static inline void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) { static inline void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); } -*/ #endif // MICROPY_INCLUDED_SAMD_MPHALPORT_H From 98ae3126402260eab306e846d01d12af317d96a2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 20:23:56 +0200 Subject: [PATCH 1806/4290] samd/samd_isr: Extend systick_ms to 64 bit. By adding a 32 bit overflow counter. This allows it to be used for the time functions. --- ports/samd/samd_isr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index dcf80d28cab0..a7956c49305f 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -32,6 +32,7 @@ extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss; const ISR isr_vector[]; uint32_t systick_ms; +volatile uint32_t systick_ms_upper; void Reset_Handler(void) __attribute__((naked)); void Reset_Handler(void) { @@ -81,7 +82,11 @@ void Default_Handler(void) { } void SysTick_Handler(void) { - systick_ms += 1; + uint32_t next_tick = systick_ms + 1; + systick_ms = next_tick; + if (systick_ms == 0) { + systick_ms_upper += 1; + } } const ISR isr_vector[] __attribute__((section(".isr_vector"))) = { From 33eaf739d2e0502ec77bdd212dfb6a3106db30b8 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 20:33:48 +0200 Subject: [PATCH 1807/4290] samd/machine_pin: Add OPEN_DRAIN mode for pins. Changes in this commit are: - Use mphal_xx functions whenever possible. - Remove obsolete includes. - Clean up traces of a non-functional pin.irq() from earlier builds. Pin.irq() will be added in further commits in a working manner. --- ports/samd/machine_pin.c | 124 +++++++++++++++------------------------ ports/samd/mphalport.h | 4 +- 2 files changed, 50 insertions(+), 78 deletions(-) diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 5f9cbfb99b85..49aecba011e9 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -31,35 +31,25 @@ #include "extmod/virtpin.h" #include "modmachine.h" #include "samd_soc.h" -#include "pins.h" // boards// +#include "pins.h" -// ASF4 (MCU package specific pin defs in 'boards') #include "hal_gpio.h" -#include "hpl_gpio.h" -#include "hal_atomic.h" #define GPIO_MODE_IN (0) #define GPIO_MODE_OUT (1) -// #define GPIO_MODE_ALT (3) +#define GPIO_MODE_OPEN_DRAIN (2) #define GPIO_STRENGTH_2MA (0) #define GPIO_STRENGTH_8MA (1) -// asf4 hpl_gpio.h gpio_pull_mode +uint32_t machine_pin_open_drain_mask[4]; -/* -typedef struct _machine_pin_irq_obj_t { - mp_irq_obj_t base; - uint32_t flags; - uint32_t trigger; -} machine_pin_irq_obj_t; - -STATIC const mp_irq_methods_t machine_pin_irq_methods; -*/ +// Open drain behaviour is simulated. +#define GPIO_IS_OPEN_DRAIN(id) (machine_pin_open_drain_mask[id / 32] & (1 << (id % 32))) STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pin_obj_t *self = self_in; - mp_printf(print, "Pin(%u)", self->id); + mp_printf(print, "GPIO P%c%02u", "ABCD"[self->id / 32], self->id % 32); } STATIC void pin_validate_drive(bool strength) { @@ -84,24 +74,26 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ // set initial value (do this before configuring mode/pull) if (args[ARG_value].u_obj != mp_const_none) { - gpio_set_pin_level(self->id, mp_obj_is_true(args[ARG_value].u_obj)); + mp_hal_pin_write(self->id, mp_obj_is_true(args[ARG_value].u_obj)); } // configure mode if (args[ARG_mode].u_obj != mp_const_none) { mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj); if (mode == GPIO_MODE_IN) { - gpio_set_pin_direction(self->id, GPIO_DIRECTION_IN); + mp_hal_pin_input(self->id); } else if (mode == GPIO_MODE_OUT) { - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); + mp_hal_pin_output(self->id); + } else if (mode == GPIO_MODE_OPEN_DRAIN) { + mp_hal_pin_open_drain(self->id); } else { - gpio_set_pin_direction(self->id, GPIO_DIRECTION_IN); // If no args are given, the Pin is 'input'. + mp_hal_pin_input(self->id); // If no args are given, the Pin is 'input'. } } // configure pull. Only to be used with IN mode. The function sets the pin to INPUT. uint32_t pull = 0; - mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj); - if (mode == GPIO_MODE_OUT && args[ARG_pull].u_obj != mp_const_none) { + mp_int_t dir = mp_hal_get_pin_direction(self->id); + if (dir == GPIO_DIRECTION_OUT && args[ARG_pull].u_obj != mp_const_none) { mp_raise_ValueError(MP_ERROR_TEXT("OUT incompatible with pull")); } else if (args[ARG_pull].u_obj != mp_const_none) { pull = mp_obj_get_int(args[ARG_pull].u_obj); @@ -143,17 +135,24 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, } // fast method for getting/setting pin value -STATIC mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); machine_pin_obj_t *self = self_in; if (n_args == 0) { // get pin - return MP_OBJ_NEW_SMALL_INT(gpio_get_pin_level(self->id)); + return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self->id)); } else { // set pin bool value = mp_obj_is_true(args[0]); - gpio_set_pin_level(self->id, value); - + if (GPIO_IS_OPEN_DRAIN(self->id)) { + if (value == 0) { + mp_hal_pin_od_low(self->id); + } else { + mp_hal_pin_od_high(self->id); + } + } else { + mp_hal_pin_write(self->id, value); + } return mp_const_none; } } @@ -165,7 +164,7 @@ STATIC mp_obj_t machine_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_obj_init); // Pin.value([value]) -STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { +mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { return machine_pin_call(args[0], n_args - 1, 0, args + 1); } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value); @@ -181,9 +180,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable); // Pin.low() Totem-pole (push-pull) STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - gpio_set_pin_level(self->id, false); - + if (GPIO_IS_OPEN_DRAIN(self->id)) { + mp_hal_pin_od_low(self->id); + } else { + mp_hal_pin_low(self->id); + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low); @@ -191,9 +192,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low); // Pin.high() Totem-pole (push-pull) STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - gpio_set_pin_level(self->id, true); - + if (GPIO_IS_OPEN_DRAIN(self->id)) { + mp_hal_pin_od_high(self->id); + } else { + mp_hal_pin_high(self->id); + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high); @@ -205,18 +208,18 @@ STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { // Determine DIRECTION of PIN. bool pin_dir; - pin_dir = (PORT->Group[(enum gpio_port)GPIO_PORT(self->id)].DIR.reg // Get PORT# - & (1 << GPIO_PIN(self->id))) // Isolate the Pin in question - >> GPIO_PIN(self->id); // Shift to LSB for binary result. - - if (pin_dir) { - // Pin is OUTPUT - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - gpio_toggle_pin_level(self->id); + if (GPIO_IS_OPEN_DRAIN(self->id)) { + pin_dir = mp_hal_get_pin_direction(self->id); + if (pin_dir) { + // Pin is output, thus low, switch to high + mp_hal_pin_od_high(self->id); + } else { + mp_hal_pin_od_low(self->id); + } } else { - mp_raise_ValueError(MP_ERROR_TEXT("Cannot TOGGLE INPUT pin!\n")); + gpio_toggle_pin_level(self->id); } - return mp_const_true; + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle); @@ -250,20 +253,15 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_disable), MP_ROM_PTR(&machine_pin_disable_obj) }, { MP_ROM_QSTR(MP_QSTR_drive), MP_ROM_PTR(&machine_pin_drive_obj) }, - - // { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) }, - // class constants { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_IN) }, { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUT) }, - // { MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(GPIO_MODE_ALT) }, + { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_OPEN_DRAIN) }, { MP_ROM_QSTR(MP_QSTR_PULL_OFF), MP_ROM_INT(GPIO_PULL_OFF) }, { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULL_UP) }, { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) }, { MP_ROM_QSTR(MP_QSTR_LOW_POWER), MP_ROM_INT(GPIO_STRENGTH_2MA) }, { MP_ROM_QSTR(MP_QSTR_HIGH_POWER), MP_ROM_INT(GPIO_STRENGTH_8MA) }, - // { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_IRQ_EDGE_RISE) }, - // { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_IRQ_EDGE_FALL) }, }; STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); @@ -298,34 +296,6 @@ MP_DEFINE_CONST_OBJ_TYPE( locals_dict, &machine_pin_locals_dict ); -/* -STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { - machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_obj[self->id]); - gpio_set_irq_enabled(self->id, GPIO_IRQ_ALL, false); - irq->flags = 0; - irq->trigger = new_trigger; - gpio_set_irq_enabled(self->id, new_trigger, true); - return 0; -} - -STATIC mp_uint_t machine_pin_irq_info(mp_obj_t self_in, mp_uint_t info_type) { - machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_obj[self->id]); - if (info_type == MP_IRQ_INFO_FLAGS) { - return irq->flags; - } else if (info_type == MP_IRQ_INFO_TRIGGERS) { - return irq->trigger; - } - return 0; -} - -STATIC const mp_irq_methods_t machine_pin_irq_methods = { - .trigger = machine_pin_irq_trigger, - .info = machine_pin_irq_info, -}; -*/ - mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) { if (!mp_obj_is_type(obj, &machine_pin_type)) { mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin")); diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index b18aa2f9b435..0a1db7df0c5b 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -101,7 +101,7 @@ static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) { static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); - gpio_set_pin_level(pin, 0); + gpio_set_pin_pull_mode(pin, GPIO_PULL_UP); machine_pin_open_drain_mask[pin / 32] |= 1 << (pin % 32); } @@ -127,10 +127,12 @@ static inline void mp_hal_pin_high(mp_hal_pin_obj_t pin) { static inline void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT); + gpio_set_pin_level(pin, 0); } static inline void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) { gpio_set_pin_direction(pin, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(pin, GPIO_PULL_UP); } #endif // MICROPY_INCLUDED_SAMD_MPHALPORT_H From e8615f5813855a3f839714fb62c7d8a5e0082072 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 20:56:18 +0200 Subject: [PATCH 1808/4290] samd/machine_pin: Allow specifying a pin or LED by its name as a string. The names are defined in pins.csv. --- ports/samd/boards/make-pins.py | 10 ++++++---- ports/samd/machine_led.c | 6 ++---- ports/samd/machine_pin.c | 23 ++++++++++++++++++++++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/ports/samd/boards/make-pins.py b/ports/samd/boards/make-pins.py index 400a9c9b8870..2b62ba7c5959 100644 --- a/ports/samd/boards/make-pins.py +++ b/ports/samd/boards/make-pins.py @@ -15,6 +15,8 @@ char *name; } machine_pin_obj_t; +int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size); + """ led_header_prefix = """typedef struct _machine_led_obj_t { @@ -33,19 +35,19 @@ def __init__(self): def parse_csv_file(self, filename): with open(filename, "r") as csvfile: - rows = csv.reader(csvfile) + rows = csv.reader(csvfile, skipinitialspace=True) for row in rows: # Pin numbers must start with "PIN_" # LED numbers must start with "LED_" if len(row) > 0: - if row[0].strip().startswith("PIN_"): + if row[0].startswith("PIN_"): if len(row) == 1: self.board_pins.append([row[0], row[0][4:]]) else: self.board_pins.append([row[0], row[1]]) - elif row[0].strip().startswith("LED_"): + elif row[0].startswith("LED_"): self.board_leds.append(["PIN_" + row[0][4:], row[1]]) - elif row[0].strip().startswith("-"): + elif row[0].startswith("-"): self.board_pins.append(["-1", ""]) def print_pins(self, pins_filename): diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index 03b47e7cf2aa..9c157695818a 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -30,12 +30,10 @@ #include "py/mphal.h" #include "extmod/virtpin.h" #include "modmachine.h" -#include "pins.h" // boards// +#include "pins.h" // ASF4 (MCU package specific pin defs in 'boards') #include "hal_gpio.h" -#include "hpl_gpio.h" -#include "hal_atomic.h" STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_led_obj_t *self = self_in; @@ -70,7 +68,7 @@ mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); // get the wanted LED object - int wanted_led = mp_obj_get_int(args[0]); + int wanted_led = pin_find(args[0], (const machine_pin_obj_t *)machine_led_obj, MP_ARRAY_SIZE(machine_led_obj)); const machine_led_obj_t *self = NULL; if (0 <= wanted_led && wanted_led < MP_ARRAY_SIZE(machine_led_obj)) { self = (machine_led_obj_t *)&machine_led_obj[wanted_led]; diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 49aecba011e9..98317abbf26a 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -26,6 +26,7 @@ * Uses pins.h & pins.c to create board (MCU package) specific 'machine_pin_obj' array. */ +#include "string.h" #include "py/runtime.h" #include "py/mphal.h" #include "extmod/virtpin.h" @@ -58,6 +59,26 @@ STATIC void pin_validate_drive(bool strength) { } } +int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size) { + int wanted_pin = -1; + if (mp_obj_is_small_int(pin)) { + // Pin defined by the index of pin table + wanted_pin = mp_obj_get_int(pin); + } else if (mp_obj_is_str(pin)) { + // Search by name + size_t slen; + const char *s = mp_obj_str_get_data(pin, &slen); + for (wanted_pin = 0; wanted_pin < table_size; wanted_pin++) { + if (slen == strlen(machine_pin_obj[wanted_pin].name) && + strncmp(s, machine_pin_obj[wanted_pin].name, slen) == 0) { + break; + } + } + } + return wanted_pin; +} + + // Pin.init(mode, pull=None, *, value=None, drive=0). No 'alt' yet. STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt }; @@ -112,7 +133,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); // get the wanted pin object - int wanted_pin = mp_obj_get_int(args[0]); + int wanted_pin = pin_find(args[0], machine_pin_obj, MP_ARRAY_SIZE(machine_pin_obj)); const machine_pin_obj_t *self = NULL; if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_obj)) { From 4013577af2f530599db80a6696c23be2ed335bee Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 4 Jun 2022 21:26:45 +0200 Subject: [PATCH 1809/4290] samd/modmachine: Enable SoftSPI and SoftI2C. --- ports/samd/Makefile | 1 + ports/samd/modmachine.c | 4 ++++ ports/samd/mpconfigport.h | 2 ++ 3 files changed, 7 insertions(+) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index e3316a9d6c11..ea71973bd763 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -110,6 +110,7 @@ SRC_C = \ lib/tinyusb/src/device/usbd_control.c \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ lib/tinyusb/src/tusb.c \ + drivers/bus/softspi.c \ shared/libc/printf.c \ shared/libc/string0.c \ shared/readline/readline.c \ diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 99fccf5bf008..b095a6b39dc9 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -28,6 +28,8 @@ #include "extmod/machine_mem.h" #include "samd_soc.h" #include "modmachine.h" +#include "extmod/machine_i2c.h" +#include "extmod/machine_spi.h" // ASF 4 #include "hal_flash.h" @@ -129,6 +131,8 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, + { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index c29043c5d0a2..6441818ba2c5 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -97,6 +97,8 @@ #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_UASYNCIO (1) +#define MICROPY_PY_MACHINE_SOFTI2C (1) +#define MICROPY_PY_MACHINE_SOFTSPI (1) #define MP_STATE_PORT MP_STATE_VM From 6c037af086acd90755f93cd323a5114984885449 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 08:55:27 +0200 Subject: [PATCH 1810/4290] samd/boards: Create pin_af_table.c from pin_af_table_SAMDxx.csv files. This step just creates the table. The firmware cannot be built at this commit. The next commit will complete the pin-af mechanism. --- ports/samd/Makefile | 23 ++++- ports/samd/boards/make-pin-af.py | 104 ++++++++++++++++++++ ports/samd/boards/pin-af-table-SAMD21.csv | 65 +++++++++++++ ports/samd/boards/pin-af-table-SAMD51.csv | 113 ++++++++++++++++++++++ 4 files changed, 300 insertions(+), 5 deletions(-) create mode 100644 ports/samd/boards/make-pin-af.py create mode 100644 ports/samd/boards/pin-af-table-SAMD21.csv create mode 100644 ports/samd/boards/pin-af-table-SAMD51.csv diff --git a/ports/samd/Makefile b/ports/samd/Makefile index ea71973bd763..1556d8161720 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -45,12 +45,22 @@ INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include/pio INC += -I$(TOP)/lib/tinyusb/src +MAKE_PIN_AF = boards/make-pin-af.py +PIN_AF_TABLE_CSV = boards/pin-af-table-$(MCU_SERIES).csv +GEN_PIN_AF = pin_af_table.c + +MAKE_PINS = boards/make-pins.py +BOARD_PINS = $(BOARD_DIR)/pins.csv +GEN_PINS_SRC = $(BUILD)/pins.c +GEN_PINS_HDR = $(BUILD)/pins.h + CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += -DMPCONFIG_MCU_H='' +CFLAGS += -DPIN_AF_TABLE_C='<$(BUILD)/$(GEN_PIN_AF)>' QSTR_GLOBAL_DEPENDENCIES += boards/mpconfig_$(MCU_SERIES_LOWER).h @@ -59,11 +69,6 @@ LDFLAGS += $(LDFLAGS_MOD) LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) -MAKE_PINS = boards/make-pins.py -BOARD_PINS = $(BOARD_DIR)/pins.csv -GEN_PINS_SRC = $(BUILD)/pins.c -GEN_PINS_HDR = $(BUILD)/pins.h - # Tune for Debugging or Optimization CFLAGS += -g # always include debug info in the ELF ifeq ($(DEBUG),1) @@ -92,6 +97,7 @@ SRC_C = \ modmachine.c \ modsamd.c \ mphalport.c \ + pin_af.c \ $(BUILD)/pins.c \ samd_flash.c \ samd_isr.c \ @@ -170,6 +176,13 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin $(Q)$(PYTHON) $(UF2CONV) -b $(TEXT0) -c -o $@ $< +pin_af.c: $(BUILD)/$(GEN_PIN_AF) + +$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES) + + $(GEN_PINS_SRC): $(BOARD_PINS) $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --pins $(GEN_PINS_SRC) --inc $(GEN_PINS_HDR) diff --git a/ports/samd/boards/make-pin-af.py b/ports/samd/boards/make-pin-af.py new file mode 100644 index 000000000000..d895ef9dd99a --- /dev/null +++ b/ports/samd/boards/make-pin-af.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +"""Generates the pin_cap table file for the SAMD port.""" + +from __future__ import print_function + +import argparse +import sys +import csv + +table_header = """// This file was automatically generated by make-pin-cap.py +// + +""" + + +class Pins: + def __init__(self): + self.board_pins = [] # list of pin objects + + def parse_csv_file(self, filename): + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile) + for row in rows: + # Pin numbers must start with "PA", "PB", "PC" or "PD" + if len(row) > 0 and row[0].strip().upper()[:2] in ("PA", "PB", "PC", "PD"): + self.board_pins.append(row) + + def print_table(self, table_filename, mcu_name): + with open(table_filename, "wt") as table_file: + table_file.write(table_header) + table_file.write("const pin_af_t pin_af_table[] = {\n") + if mcu_name == "SAMD21": + for row in self.board_pins: + pin = "PIN_" + row[0].upper() + table_file.write(" #ifdef " + pin + "\n") + eic = row[1] if row[1] else "0xff" + adc = row[2] if row[2] else "0xff" + table_file.write(" {%s, %s, %s" % (pin, eic, adc)) + for cell in row[3:]: + if cell: + table_file.write( + ", 0x%s" % cell if len(cell) == 2 else ", 0x0%s" % cell + ) + else: + table_file.write(", 0xff") + table_file.write("},\n") + table_file.write(" #endif\n") + else: + for row in self.board_pins: + pin = "PIN_" + row[0].upper() + table_file.write(" #ifdef " + pin + "\n") + eic = row[1] if row[1] else "0xff" + adc0 = row[2] if row[2] else "0xff" + adc1 = row[3] if row[3] else "0xff" + table_file.write(" {%s, %s, %s, %s" % (pin, eic, adc0, adc1)) + for cell in row[4:]: + if cell: + table_file.write( + ", 0x%s" % cell if len(cell) == 2 else ", 0x0%s" % cell + ) + else: + table_file.write(", 0xff") + table_file.write("},\n") + table_file.write(" #endif\n") + table_file.write("};\n") + + +def main(): + parser = argparse.ArgumentParser( + prog="make-pin-cap.py", + usage="%(prog)s [options] [command]", + description="Generate MCU-specific pin cap table file", + ) + parser.add_argument( + "-c", + "--csv", + dest="csv_filename", + help="Specifies the pin-mux-xxxx.csv filename", + ) + parser.add_argument( + "-t", + "--table", + dest="table_filename", + help="Specifies the name of the generated pin cap table file", + ) + parser.add_argument( + "-m", + "--mcu", + dest="mcu_name", + help="Specifies type of the MCU (SAMD21 or SAMD51)", + ) + args = parser.parse_args(sys.argv[1:]) + + pins = Pins() + + if args.csv_filename: + pins.parse_csv_file(args.csv_filename) + + if args.table_filename: + pins.print_table(args.table_filename, args.mcu_name) + + +if __name__ == "__main__": + main() diff --git a/ports/samd/boards/pin-af-table-SAMD21.csv b/ports/samd/boards/pin-af-table-SAMD21.csv new file mode 100644 index 000000000000..d8ab903c9e7c --- /dev/null +++ b/ports/samd/boards/pin-af-table-SAMD21.csv @@ -0,0 +1,65 @@ +# The pin_cap_tables contain the information anbout pin mux set and pad +# for some of the peripheral devices with many possible assignments. +# The pin_cap_table is a subset from table 7-1 of the data sheet. +# It contain the information about pin mux set and pad +# The eic and adc columns contain the decimal numer for the respecitive +# quantity, the columns for sercom, tc and tcc have in each cell +# the device number in the upper nibble, and the pad number in the lower +# nibble. If a signal is not available, the cell in the csv table is left empty. +# The first column is the pin id, not the number of the board pin. +# Rows not starting with pa, pb, pc or pd are ignored. +# When editing the table with a spread sheet, take care to import the data as text. +# +# Pin,EIC,ADC,SERCOM1,SERCOM2,TC,TCC +pa00,0,,,10,20, +pa01,1,,,11,21, +pa02,2,0,,,, +pa03,3,1,,,, +pb04,4,12,,,, +pb05,5,13,,,, +pb06,6,14,,,, +pb07,7,15,,,, +pb08,8,2,,40,40, +pb09,9,3,,41,41, +pa04,4,4,,00,00, +pa05,5,5,,01,01, +pa06,6,6,,02,10, +pa07,7,7,,03,11, +pa08,,16,00,20,00,12 +pa09,9,17,01,21,01,13 +pa10,10,18,02,22,10,02 +pa11,11,19,03,23,11,03 +pb10,10,,,42,50,04 +pb11,11,,,43,51,05 +pb12,12,,40,,40,06 +pb13,13,,41,,41,07 +pb14,14,,42,,50, +pb15,15,,43,,51, +pa12,12,,20,40,20,06 +pa13,13,,21,41,20,07 +pa14,14,,22,42,30,04 +pa15,15,,23,43,31,05 +pa16,0,,10,30,20,06 +pa17,1,,11,31,21,07 +pa18,2,,12,32,30,02 +pa19,3,,13,33,31,03 +pb16,9,,50,,60,04 +pb17,1,,51,,61,05 +pa20,4,,52,32,70,04 +pa21,5,,53,33,71,07 +pa22,6,,30,50,40,04 +pa23,7,,31,51,41,05 +pa24,12,,32,52,50,12 +pa25,13,,33,53,51,13 +pb22,6,,,52,70, +pb23,7,,,53,71, +pa27,15,,,,, +pa28,8,,,,, +pa30,10,,,12,10, +pa31,11,,,13,11, +pb30,14,,,50,00,12 +pb31,15,,,51,01,13 +pb00,0,,,52,70, +pb01,1,,,53,71, +pb02,2,,,50,60, +pb03,3,,,51,61, diff --git a/ports/samd/boards/pin-af-table-SAMD51.csv b/ports/samd/boards/pin-af-table-SAMD51.csv new file mode 100644 index 000000000000..70a009ba5223 --- /dev/null +++ b/ports/samd/boards/pin-af-table-SAMD51.csv @@ -0,0 +1,113 @@ +# The pin_cap_table is a subset from table 6-1 of the data sheet. +# It contain the information about pin mux set and pad +# for some of the peripheral devices with many possible assignments. +# The colums represent the peripheral class, as defined in pin_cap_t. The +# column number is equivalent to the mux class. +# The eic and adc columns contain the decimal numer for the respecitive +# quantity, the columns for sercom, tc and tcc have in each cell +# the device number in the first, and the pad number in the second +# digit. If a signal is not available, the cell in the csv table is left empty. +# The first column is the pin id, not the number of the board pin. +# Rows not starting with pa, pb, pc or pd are ignored. +# When editing the table with a spread sheet, take care to import the data as text. +# +# Pin,EIC,ADC0,ADC1,SERCOM1,SERCOM2,TC,TCC1,TCC2 +pb03,9,15,,,51,61,, +pa00,0,,,,10,20,, +pa01,1,,,,11,21,, +pc00,0,,10,,,,, +pc01,1,,11,,,,, +pc02,2,,4,,,,, +pc03,3,,5,,,,, +pa02,2,0,,,,,, +pa03,3,10,,,,,, +pb04,4,,6,,,,, +pb05,5,,7,,,,, +pd00,0,,14,,,,, +pd01,1,,15,,,,, +pb06,6,,8,,,,, +pb07,7,,9,,,,, +pb08,8,2,0,,40,40,, +pb09,9,3,1,,41,41,, +pa04,4,4,,,00,00,, +pa05,5,5,,,01,01,, +pa06,6,6,,,02,10,, +pa07,7,7,,,03,11,, +pc04,4,,,60,,,00, +pc05,5,,,61,,,, +pc06,6,,,62,,,, +pc07,9,,,63,,,, +pa08,,8,2,00,21,00,00,14 +pa09,9,9,3,01,20,01,01,15 +pa10,10,10,,02,22,10,02,16 +pa11,11,11,,03,23,11,03,17 +pb10,10,,,,42,50,04,10 +pb11,12,,,,43,51,05,11 +pb12,12,,,40,,40,30,00 +pb13,13,,,41,,41,31,01 +pb14,14,,,42,,50,40,02 +pb15,15,,,43,,51,41,03 +pd08,3,,,70,61,,01, +pd09,4,,,71,60,,02, +pd10,5,,,72,62,,03, +pd11,6,,,73,63,,04, +pd12,7,,,,,,05, +pc10,10,,,62,72,,00,14 +pc11,11,,,63,73,,01,15 +pc12,12,,,70,61,,02,16 +pc13,13,,,71,60,,03,17 +pc14,14,,,72,62,,04,10 +pc15,15,,,73,63,,05,11 +pa12,12,,,20,41,20,06,12 +pa13,13,,,21,40,21,07,13 +pa14,14,,,22,42,30,20,12 +pa15,15,,,23,43,31,21,13 +pa16,0,,,10,31,20,10,04 +pa17,1,,,11,30,21,11,05 +pa18,2,,,12,32,30,12,06 +pa19,3,,,13,33,31,13,07 +pc16,0,,,60,01,,00, +pc17,1,,,61,00,,01, +pc18,2,,,62,02,,02, +pc19,3,,,63,03,,03, +pc20,4,,,,,,04, +pc21,5,,,,,,05, +pc22,6,,,10,31,,05, +pc23,7,,,11,30,,07, +pd20,10,,,12,32,,10, +pd21,11,,,13,33,,11, +pb16,0,,,50,,60,30,04 +pb17,1,,,51,,61,31,05 +pb18,2,,,52,72,,10, +pb19,3,,,53,73,,11, +pb20,4,,,30,71,,12, +pb21,5,,,31,70,,13, +pa20,4,,,52,32,70,14,00 +pa21,5,,,53,33,71,15,01 +pa22,6,,,30,51,40,16,02 +pa23,7,,,31,50,41,17,03 +pa24,8,,,32,52,50,22, +pa25,9,,,33,53,51,, +pb22,22,,,12,52,70,, +pb23,7,,,13,53,71,, +pb24,8,,,00,21,,, +pb25,9,,,01,20,,, +pb26,12,,,20,41,,12, +pb27,13,,,21,40,,13, +pb28,14,,,22,42,,14, +pb29,15,,,23,43,,15, +pc24,8,,,02,22,,, +pc25,9,,,03,23,,, +pc26,10,,,,,,, +pc27,11,,,10,,,, +pc28,12,,,11,,,, +pa27,11,,,,,,, +pa30,14,,,72,12,60,20, +pa31,15,,,73,13,61,21, +pb30,14,,,70,51,00,40,06 +pb31,15,,,71,50,01,41,07 +pc30,14,,12,,,,, +pc31,15,,13,,,,, +pb00,9,12,,,52,70,, +pb01,1,13,,,53,71,, +pb02,2,14,,,50,60,22, From 6765d4bbd66c19898158504ed8102ebd8de4c645 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 09:26:49 +0200 Subject: [PATCH 1811/4290] samd/pin_af: Add the pin af table and its helper functions. The pin af table is a representation of the MUX table from the data sheet. It provides information for each pin about the supported device functions. That information is needed by pin.irq, machine.ADC, machine.PWM, machine.UART, machine.SPI and machine.I2C. For each of these, the table tells for each pin, which device number, af number and pad number is assigned. Using the table gives a straight, uniform access to the information, where the benefit outweights the size of the table, which is not that large. The tables are MCU-specific. It is not required to tell for each board, which and where each of the above devices is available. That makes addding boards easy. Note: The information for DAC and I2S was not included, since it affects only a few pins. --- ports/samd/pin_af.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ ports/samd/pin_af.h | 90 +++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 ports/samd/pin_af.c create mode 100644 ports/samd/pin_af.h diff --git a/ports/samd/pin_af.c b/ports/samd/pin_af.c new file mode 100644 index 000000000000..8c152e0d8be0 --- /dev/null +++ b/ports/samd/pin_af.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file provides and checks pin capabilities as required + * for USART, I2C, SPI, PWM, ADC + * + */ + +#include + +#include "py/runtime.h" +#include "py/misc.h" +#include "pin_af.h" +#include "sam.h" + + +extern const uint8_t tcc_channel_count[]; + +#include PIN_AF_TABLE_C + +// Just look for an table entry for a given pin and raise an error +// in case of no match (which should not happen). + +const pin_af_t *get_pin_af_info(int pin_id) { + for (int i = 0; i < MP_ARRAY_SIZE(pin_af_table); i++) { + if (pin_af_table[i].pin_id == pin_id) { // Pin match + return &pin_af_table[i]; + } + } + mp_raise_ValueError(MP_ERROR_TEXT("wrong pin")); +} + +// Test, wether 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. + +sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) { + const pin_af_t *pct_ptr = get_pin_af_info(pin_id); + if ((pct_ptr->sercom1 >> 4) == sercom_nr) { + return (sercom_pad_config_t) {ALT_FCT_SERCOM1, pct_ptr->sercom1 & 0x0f}; + } else if ((pct_ptr->sercom2 >> 4) == sercom_nr) { + return (sercom_pad_config_t) {ALT_FCT_SERCOM2, pct_ptr->sercom2 & 0x0f}; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("wrong serial device")); + } +} + +// Test, wether the given pin is defined as ADC. +// If that applies return the adc instance and channel. +// If not, an error will be raised. + +adc_config_t get_adc_config(int pin_id, int32_t flag) { + const pin_af_t *pct_ptr = get_pin_af_info(pin_id); + if (pct_ptr->adc0 != 0xff && (flag & (1 << pct_ptr->adc0)) == 0) { + return (adc_config_t) {0, pct_ptr->adc0}; + #if defined(MUC_SAMD51) + } else if (pct_ptr->adc1 != 0xff && (flag & (1 << (pct_ptr->adc1 + 16))) == 0) { + return (adc_config_t) {1, pct_ptr->adc1}; + #endif + } else { + mp_raise_ValueError(MP_ERROR_TEXT("ADC pin used")); + } +} + +// Test, wether the given pin is defined and has signals for pwm. +// If that applies return the alt_fct, tcc number and channel number. +// If not, an error will be raised. +// The function either supplies a channel from a wanted device, or +// tries to provide an unused device, if available. + +pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t device_status[]) { + const pin_af_t *pct_ptr = get_pin_af_info(pin_id); + uint8_t tcc1 = pct_ptr->tcc1; + uint8_t tcc2 = pct_ptr->tcc2; + + if (wanted_dev != -1) { + if ((tcc1 >> 4) == wanted_dev) { + return (pwm_config_t) {ALT_FCT_TCC1, tcc1}; + } else if ((tcc2 >> 4) == wanted_dev) { + return (pwm_config_t) {ALT_FCT_TCC2, tcc2}; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("wrong device or channel")); + } + } else { + pwm_config_t ret = {}; + if ((tcc1 >> 4) < TCC_INST_NUM) { + ret = (pwm_config_t) {ALT_FCT_TCC1, tcc1}; + if (tcc2 == 0xff) { + return ret; + } + } + if ((tcc2 >> 4) < TCC_INST_NUM) { + // if a device in slot 1 is not available or already in use, use the one in slot 2 + if (tcc1 == 0xff || device_status[(ret.device_channel >> 4)] != 0) { + return (pwm_config_t) {ALT_FCT_TCC2, tcc2}; + } else { + return ret; + } + } else { + mp_raise_ValueError(MP_ERROR_TEXT("not a PWM pin")); + } + } +} diff --git a/ports/samd/pin_af.h b/ports/samd/pin_af.h new file mode 100644 index 000000000000..f9dec6b7da05 --- /dev/null +++ b/ports/samd/pin_af.h @@ -0,0 +1,90 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file initialises provides and checks pin capabilities as required + * for USART, I2C, SPI, PWM, ADC + * + */ + +#if defined(MCU_SAMD21) + +typedef struct { + uint8_t pin_id; + uint8_t eic; + uint8_t adc0; + uint8_t sercom1; + uint8_t sercom2; + uint8_t tcc1; + uint8_t tcc2; +} pin_af_t; + +#define ALT_FCT_TC 4 +#define ALT_FCT_TCC1 4 +#define ALT_FCT_TCC2 5 + +#elif defined(MCU_SAMD51) + +typedef struct { + uint8_t pin_id; + uint8_t eic; + uint8_t adc0; + uint8_t adc1; + uint8_t sercom1; + uint8_t sercom2; + uint8_t tc; + uint8_t tcc1; + uint8_t tcc2; +} pin_af_t; + +#define ALT_FCT_TC 4 +#define ALT_FCT_TCC1 5 +#define ALT_FCT_TCC2 6 + +#endif + +typedef struct _sercom_pad_config_t { + uint8_t alt_fct; + uint8_t pad_nr; +} sercom_pad_config_t; + +typedef struct _adc_config_t { + uint8_t device; + uint8_t channel; +} adc_config_t; + +typedef struct _pwm_config_t { + uint8_t alt_fct; + uint8_t device_channel; +} pwm_config_t; + +#define ALT_FCT_EIC 0 +#define ALT_FCT_ADC 1 +#define ALT_FCT_SERCOM1 2 +#define ALT_FCT_SERCOM2 3 + +sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom); +adc_config_t get_adc_config(int pin_id, int32_t flag); +pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t used_dev[]); +const pin_af_t *get_pin_af_info(int pin_id); From 5c7e93ec48b04a6a049cc7f2ec90230cd64ecba2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 10:34:23 +0200 Subject: [PATCH 1812/4290] samd/machine_adc: Add the machine.ADC class. With the method read_u16(). Keyword arguments of the constructor are: - bits=n The resolution; default is 12. - average=n The average of samples, which are taken and cumulated. The default value is 16. Averaging by hw is faster than averaging in code. The ADC runs at a clock freq 1.5 MHz. A single 12 bit conversion takes 8 microseconds. --- ports/samd/Makefile | 2 + ports/samd/machine_adc.c | 238 +++++++++++++++++++++++++++++++++++++++ ports/samd/main.c | 2 + ports/samd/modmachine.c | 4 +- ports/samd/modmachine.h | 3 +- 5 files changed, 247 insertions(+), 2 deletions(-) create mode 100644 ports/samd/machine_adc.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 1556d8161720..910ecdac3103 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -90,6 +90,7 @@ endif SRC_C = \ clock_config.c \ help.c \ + machine_adc.c \ machine_led.c \ machine_pin.c \ main.c \ @@ -138,6 +139,7 @@ endif # List of sources for qstr extraction SRC_QSTR += \ + machine_adc.c \ machine_led.c \ machine_pin.c \ modutime.c \ diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c new file mode 100644 index 000000000000..97b6a14f17a4 --- /dev/null +++ b/ports/samd/machine_adc.c @@ -0,0 +1,238 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Philipp Ebensberger + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "sam.h" +#include "pin_af.h" +#include "modmachine.h" + +typedef struct _machine_adc_obj_t { + mp_obj_base_t base; + adc_config_t adc_config; + uint8_t id; + uint8_t avg; + uint8_t bits; +} machine_adc_obj_t; + +#define DEFAULT_ADC_BITS 12 +#define DEFAULT_ADC_AVG 16 + +Adc *const adc_bases[] = ADC_INSTS; +uint32_t busy_flags = 0; +bool init_flags[2] = {false, false}; +static void adc_init(machine_adc_obj_t *self); +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; +} + +STATIC void adc_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { + (void)kind; + machine_adc_obj_t *self = MP_OBJ_TO_PTR(o); + + mp_printf(print, "ADC(P%c%02u, ADC%u, channel=%u, bits=%u, average=%u)", + "ABCD"[self->id / 32], self->id % 32, self->adc_config.device, + self->adc_config.channel, self->bits, 1 << self->avg); +} + +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) { + enum { ARG_id, ARG_bits, ARG_average }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { 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} }, + }; + + // Parse the arguments. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Unpack and check, whther the pin has ADC capability + int id = mp_hal_get_pin_obj(args[ARG_id].u_obj); + adc_config_t adc_config = get_adc_config(id, busy_flags); + + // Now that we have a valid device and channel, create and populate the ADC instance + machine_adc_obj_t *self = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); + self->id = id; + self->adc_config = adc_config; + self->bits = DEFAULT_ADC_BITS; + uint16_t bits = args[ARG_bits].u_int; + if (bits >= 8 && bits <= 12) { + self->bits = bits; + } + uint32_t avg = log2i(args[ARG_average].u_int); + self->avg = (avg <= 10 ? avg : 10); + + // flag the device/channel as being in use. + busy_flags |= (1 << (self->adc_config.device * 16 + self->adc_config.channel)); + + adc_init(self); + + return MP_OBJ_FROM_PTR(self); +} + +// read_u16() +STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) { + machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + Adc *adc = adc_bases[self->adc_config.device]; + // Set Input channel and resolution + // Select the pin as positive input and gnd as negative input reference, non-diff mode by default + adc->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | self->adc_config.channel; + // set resolution. Scale 8-16 to 0 - 4 for table access. + adc->CTRLB.bit.RESSEL = resolution[(self->bits - 8) / 2]; + // Measure input voltage + adc->SWTRIG.bit.START = 1; + while (adc->INTFLAG.bit.RESRDY == 0) { + } + // Get and return the result + return MP_OBJ_NEW_SMALL_INT(adc->RESULT.reg * (65536 / (1 << self->bits))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_u16_obj, machine_adc_read_u16); + +// deinit() : release the ADC channel +STATIC mp_obj_t machine_adc_deinit(mp_obj_t self_in) { + machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + + busy_flags &= ~((1 << (self->adc_config.device * 16 + self->adc_config.channel))); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_deinit_obj, machine_adc_deinit); + +void adc_deinit_all(void) { + busy_flags = 0; + init_flags[0] = 0; + init_flags[1] = 0; +} + +STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read_u16), MP_ROM_PTR(&machine_adc_read_u16_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_adc_deinit_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_adc_type, + MP_QSTR_ADC, + MP_TYPE_FLAG_NONE, + make_new, adc_obj_make_new, + print, adc_obj_print, + locals_dict, &adc_locals_dict + ); + +static void adc_init(machine_adc_obj_t *self) { + // ADC & clock init is done only once per ADC + if (init_flags[self->adc_config.device] == false) { + Adc *adc = adc_bases[self->adc_config.device]; + + init_flags[self->adc_config.device] = true; + + #if defined(MCU_SAMD21) + // Configuration SAMD21 + // Enable APBD clocks and PCHCTRL clocks; GCLK2 at 48 MHz + PM->APBCMASK.reg |= PM_APBCMASK_ADC; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_ADC; + while (GCLK->STATUS.bit.SYNCBUSY) { + } + // Reset ADC registers + adc->CTRLA.bit.SWRST = 1; + while (adc->CTRLA.bit.SWRST) { + } + // Get the calibration data + uint32_t bias = (*((uint32_t *)ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; + uint32_t linearity = (*((uint32_t *)ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; + linearity |= ((*((uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; + /* Write the calibration data. */ + ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity); + // Divide 48MHz clock by 32 to obtain 1.5 MHz clock to adc + adc->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV32; + // Select external AREFA as reference voltage. + adc->REFCTRL.reg = ADC_REFCTRL_REFSEL_AREFA; + // Average: Accumulate samples and scale them down accordingly + adc->AVGCTRL.reg = self->avg | ADC_AVGCTRL_ADJRES(self->avg); + // Enable ADC and wait to be ready + adc->CTRLA.bit.ENABLE = 1; + while (adc->STATUS.bit.SYNCBUSY) { + } + + #elif defined(MCU_SAMD51) + // Configuration SAMD51 + // Enable APBD clocks and PCHCTRL clocks; GCLK2 at 48 MHz + if (self->adc_config.device == 0) { + GCLK->PCHCTRL[ADC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; + MCLK->APBDMASK.bit.ADC0_ = 1; + } else { + GCLK->PCHCTRL[ADC1_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; + MCLK->APBDMASK.bit.ADC1_ = 1; + } + // Reset ADC registers + adc->CTRLA.bit.SWRST = 1; + while (adc->CTRLA.bit.SWRST) { + } + // Get the calibration data + uint32_t biascomp; + uint32_t biasr2r; + uint32_t biasrefbuf; + if (self->adc_config.device == 0) { + biascomp = (*((uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos; + biasr2r = (*((uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos; + biasrefbuf = (*((uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos; + } else { + biascomp = (*((uint32_t *)ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos; + biasr2r = (*((uint32_t *)ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos; + biasrefbuf = (*((uint32_t *)ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos; + } + /* Write the calibration data. */ + adc->CALIB.reg = ADC_CALIB_BIASCOMP(biascomp) | ADC_CALIB_BIASR2R(biasr2r) | ADC_CALIB_BIASREFBUF(biasrefbuf); + // Divide 48MHz clock by 32 to obtain 1.5 MHz clock to adc + adc->CTRLA.reg = ADC_CTRLA_PRESCALER_DIV32; + // Select external AREFA as reference voltage. + adc->REFCTRL.reg = ADC_REFCTRL_REFSEL_AREFA; + // Average: Accumulate samples and scale them down accordingly + adc->AVGCTRL.reg = self->avg | ADC_AVGCTRL_ADJRES(self->avg); + // Enable ADC and wait to be ready + adc->CTRLA.bit.ENABLE = 1; + while (adc->SYNCBUSY.bit.ENABLE) { + } + + #endif + } + // Set the port as given in self->id as ADC + mp_hal_set_pin_mux(self->id, ALT_FCT_ADC); +} diff --git a/ports/samd/main.c b/ports/samd/main.c index d8c1c596c5b0..ece86f5889b6 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -33,6 +33,7 @@ #include "shared/runtime/pyexec.h" extern uint8_t _sstack, _estack, _sheap, _eheap; +extern void adc_deinit_all(void); void samd_main(void) { mp_stack_set_top(&_estack); @@ -62,6 +63,7 @@ void samd_main(void) { } mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); + adc_deinit_all(); gc_sweep_all(); mp_deinit(); } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index b095a6b39dc9..287641cc33aa 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -129,8 +129,10 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, { 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) }, - { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, + + { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, + { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, }; diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index f7ad2b5e5cbc..53914a10c7fc 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -28,7 +28,8 @@ #include "py/obj.h" -extern const mp_obj_type_t machine_pin_type; +extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_led_type; +extern const mp_obj_type_t machine_pin_type; #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H From d693758ab28a6b25601f019db78c7f9bc213be38 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 11:03:59 +0200 Subject: [PATCH 1813/4290] samd/machine_pwm: Add the machine.PWM class. Features are: - 3 to 5 different frequency groups. - Freq range of 1Hz - 24 MHz. - Duty rate stays stable on freq change. Keyword options to the PWM constructor: - device=n Select a specific PWM device. If no device is specified, a free device is chosen, if available at that pin. - freq=nnnn - duty_u16=nnnn - duty_ns=nnnn - invert=True/False Allowing two outputs on the same device/channel to have complementary signals. If both freq and duty are provided, PWM output will start immediately. Pins at the same device have the same frequency. If the PWM output number exceeds the number of channels at the PWM device, the effctive channel_no is output_no % channel_count. So with a channel count of 4, output 7 is assigned to channel 3. Pins at a certain channel have the same frequency and duty rate, but may be seperately inverted. --- ports/samd/Makefile | 1 + ports/samd/machine_pwm.c | 362 ++++++++++++++++++++++++++++++++++++++ ports/samd/main.c | 2 + ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + ports/samd/mpconfigport.h | 4 + ports/samd/mphalport.c | 4 + ports/samd/mphalport.h | 1 + 8 files changed, 376 insertions(+) create mode 100644 ports/samd/machine_pwm.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 910ecdac3103..514c92ba1bd6 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -142,6 +142,7 @@ SRC_QSTR += \ machine_adc.c \ machine_led.c \ machine_pin.c \ + machine_pwm.c \ modutime.c \ modmachine.c \ modsamd.c \ diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c new file mode 100644 index 000000000000..6f9ca42b1b2a --- /dev/null +++ b/ports/samd/machine_pwm.c @@ -0,0 +1,362 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "modmachine.h" + +#include "sam.h" +#include "pin_af.h" + +/******************************************************************************/ +// MicroPython bindings for machine.PWM + +typedef struct _machine_pwm_obj_t { + mp_obj_base_t base; + Tcc *instance; + uint8_t pin_id; + uint8_t alt_fct; + uint8_t device; + uint8_t channel; + uint8_t output; + uint16_t prescaler; + uint32_t period; // full period count ticks +} machine_pwm_obj_t; + +#define PWM_NOT_INIT (0) +#define PWM_CLK_READY (1) +#define PWM_TCC_ENABLED (2) +#define PWM_MASTER_CLK (48000000) +#define PWM_FULL_SCALE (65536) + +static Tcc *tcc_instance[] = TCC_INSTS; + +#if defined(MCU_SAMD21) + +static const int tcc_gclk_id[] = { + GCLK_CLKCTRL_ID_TCC0_TCC1, GCLK_CLKCTRL_ID_TCC0_TCC1, GCLK_CLKCTRL_ID_TCC2_TC3 +}; +const uint8_t tcc_channel_count[] = {4, 2, 2}; +const static uint8_t tcc_channel_offset[] = {0, 4, 6}; +static uint32_t pwm_duty_values[8]; + +#define PERBUF PERB +#define CCBUF CCB + +#elif defined(MCU_SAMD51) + +static const int tcc_gclk_id[] = { + TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, + #if TCC_INST_NUM > 3 + TCC3_GCLK_ID, TCC4_GCLK_ID + #endif +}; + +#if TCC_INST_NUM > 3 +const uint8_t tcc_channel_count[] = {6, 4, 3, 2, 2}; +const static uint8_t tcc_channel_offset[] = {0, 6, 10, 13, 15}; +static uint32_t pwm_duty_values[17]; +#else +const uint8_t tcc_channel_count[] = {6, 4, 3}; +const static uint8_t tcc_channel_offset[] = {0, 6, 10}; +static uint32_t pwm_duty_values[13]; +#endif // TCC_INST_NUM > 3 + +#endif // defined(MCU_SAMD51) + +#define put_duty_value(device, channel, duty) \ + pwm_duty_values[tcc_channel_offset[device] + channel] = duty; + +#define get_duty_value(device, channel) \ + pwm_duty_values[tcc_channel_offset[device] + channel] + +static uint8_t duty_type_flags[TCC_INST_NUM]; +static uint8_t device_status[TCC_INST_NUM]; +static uint8_t output_active[TCC_INST_NUM]; +const uint16_t prescaler_table[] = {1, 2, 4, 8, 16, 64, 256, 1024}; + +STATIC void pwm_stop_device(int device); +STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq); +STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16); +STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns); + +STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "PWM P%c%02u device=%u channel=%u output=%u", + "ABCD"[self->pin_id / 32], self->pin_id % 32, self->device, self->channel, self->output); +} + +// PWM(pin) +STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_pin, ARG_freq, ARG_duty_u16, ARG_duty_ns, ARG_invert, ARG_device }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_freq, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_duty_u16, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_duty_ns, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_invert, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_device, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + }; + + // Parse the arguments. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Get GPIO and optional device to connect to PWM. + uint32_t pin_id = mp_hal_get_pin_obj(args[ARG_pin].u_obj); + int32_t wanted_dev = args[ARG_device].u_int; // -1 = any + + // Get the peripheral object and populate it + + pwm_config_t config = get_pwm_config(pin_id, wanted_dev, device_status); + uint8_t device = config.device_channel >> 4; + if (device >= TCC_INST_NUM) { + mp_raise_ValueError(MP_ERROR_TEXT("wrong device")); + } + + machine_pwm_obj_t *self = mp_obj_malloc(machine_pwm_obj_t, &machine_pwm_type); + self->instance = tcc_instance[device]; + self->device = device; + self->pin_id = pin_id; + self->alt_fct = config.alt_fct; + self->channel = (config.device_channel & 0x0f) % tcc_channel_count[device]; + self->output = config.device_channel & 0x0f; + self->prescaler = 1; + self->period = 1; // Use an invalid but safe value + put_duty_value(self->device, self->channel, 0); + + Tcc *tcc = self->instance; + + if (device_status[device] == PWM_NOT_INIT) { + // Enable the device clock at first use. + #if defined(MCU_SAMD21) + // Enable synchronous clock. The bits are nicely arranged + PM->APBCMASK.reg |= PM_APBCMASK_TCC0 << device; + // Select multiplexer generic clock source and enable. + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | tcc_gclk_id[device]; + // Wait while it updates synchronously. + while (GCLK->STATUS.bit.SYNCBUSY) { + } + #elif defined(MCU_SAMD51) + // GenClk2 to the tcc + GCLK->PCHCTRL[tcc_gclk_id[device]].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(2); + while (GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK2) { + } + // Enable MCLK + switch (device) { + case 0: + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC0; + break; + case 1: + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC1; + break; + case 2: + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC2; + break; + #if TCC_INST_NUM > 3 + case 3: + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC3; + break; + case 4: + MCLK->APBDMASK.reg |= MCLK_APBDMASK_TCC4; + break; + #endif + } + #endif + // Reset the device + tcc->CTRLA.reg = TCC_CTRLA_SWRST; + while (tcc->SYNCBUSY.reg & TCC_SYNCBUSY_SWRST) { + } + tcc->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV1; + tcc->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM; + // Flag the clock as initialized, but not the device as enabled. + device_status[device] = PWM_CLK_READY; + } + + if (args[ARG_invert].u_int != -1) { + bool invert = !!args[ARG_invert].u_int; + if (device_status[device] != PWM_CLK_READY) { + pwm_stop_device(device); + } + uint32_t mask = 1 << (self->output + TCC_DRVCTRL_INVEN0_Pos); + if (invert) { + tcc->DRVCTRL.reg |= mask; + } else { + tcc->DRVCTRL.reg &= ~(mask); + } + } + if (args[ARG_duty_u16].u_int != -1) { + mp_machine_pwm_duty_set_u16(self, args[ARG_duty_u16].u_int); + } + if (args[ARG_duty_ns].u_int != -1) { + mp_machine_pwm_duty_set_ns(self, args[ARG_duty_ns].u_int); + } + if (args[ARG_freq].u_int != -1) { + mp_machine_pwm_freq_set(self, args[ARG_freq].u_int); + } + return MP_OBJ_FROM_PTR(self); +} + +STATIC void pwm_stop_device(int device) { + Tcc *tcc = tcc_instance[device]; + tcc->CTRLA.bit.ENABLE = 0; + while (tcc->SYNCBUSY.reg & TCC_SYNCBUSY_ENABLE) { + } + device_status[device] = PWM_CLK_READY; +} + +// Stop all TTC devices +void pwm_deinit_all(void) { + for (int i = 0; i < TCC_INST_NUM; i++) { + Tcc *tcc = tcc_instance[i]; + tcc->CTRLA.reg = TCC_CTRLA_SWRST; + while (tcc->SYNCBUSY.reg & TCC_SYNCBUSY_SWRST) { + } + device_status[i] = PWM_NOT_INIT; + duty_type_flags[i] = 0; + output_active[i] = 0; + } +} + +// Switch off an output. If all outputs of a device are off, +// switch off that device. +// This stops all channels, but keeps the configuration +// Calling pwm.freq(n) will start an instance again. +STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { + mp_hal_clr_pin_mux(self->pin_id); // Switch the output off + output_active[self->device] &= ~(1 << self->output); // clear output flasg + // Stop the device, if no output is active. + if (output_active[self->device] == 0) { + pwm_stop_device(self->device); + } +} + +STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(PWM_MASTER_CLK / self->prescaler / self->period); +} + +STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + // Set the frequency. The period counter is 24 bit or 16 bit with a pre-scaling + // of up to 1024, allowing a range from 24 MHz down to 1 Hz. + static const uint32_t max_period[5] = {1 << 24, 1 << 24, 1 << 16, 1 << 16, 1 << 16}; + + Tcc *tcc = self->instance; + if (freq < 1) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid freq")); + } + + // Get the actual settings of prescaler & period from the unit + // To be able for cope for changes. + uint32_t prev_period = tcc->PER.reg + 1; + + // Check for the right prescaler + uint8_t index; + for (index = 0; index < 8; index++) { + uint32_t temp = PWM_MASTER_CLK / prescaler_table[index] / freq; + if (temp < max_period[self->device]) { + break; + } + } + self->prescaler = prescaler_table[index]; + + uint32_t period = PWM_MASTER_CLK / self->prescaler / freq; + if (period < 2) { + mp_raise_ValueError(MP_ERROR_TEXT("freq too large")); + } + // Check, if the prescaler has to be changed and stop the device if so. + if (index != tcc->CTRLA.bit.PRESCALER) { + // stop the device + pwm_stop_device(self->device); + // update the prescaler + tcc->CTRLA.bit.PRESCALER = index; + } + // Lock the update to get a glitch-free change of period and duty cycle + tcc->CTRLBSET.reg = TCC_CTRLBSET_LUPD; + tcc->PERBUF.reg = period - 1; + self->period = period; + + // Check if the Duty rate has to be aligned again when freq or prescaler were changed. + // This condition is as well true on first call after instantiation. So (re-)configure + // all channels with a duty_u16 setting. + if (period != prev_period) { + for (uint16_t ch = 0; ch < tcc_channel_count[self->device]; ch++) { + if ((duty_type_flags[self->device] & (1 << ch)) != 0) { // duty_u16 type? + tcc->CCBUF[ch].reg = (uint64_t)get_duty_value(self->device, ch) * period / + PWM_FULL_SCALE; + } + } + } + // If the prescaler was changed, the device is disabled. So this condition is true + // after the instantiation and after a prescaler change. + // (re-)configure all channels with a duty_ns setting. + if (!(tcc->CTRLA.reg & TCC_CTRLA_ENABLE)) { + for (uint16_t ch = 0; ch < tcc_channel_count[self->device]; ch++) { + if ((duty_type_flags[self->device] & (1 << ch)) == 0) { // duty_ns type? + tcc->CCBUF[ch].reg = (uint64_t)get_duty_value(self->device, ch) * PWM_MASTER_CLK / + self->prescaler / 1000000000ULL; + } + } + } + // Remember the output as active. + output_active[self->device] |= 1 << self->output; // set output flag + // (Re-)Select PWM function for given GPIO. + mp_hal_set_pin_mux(self->pin_id, self->alt_fct); + // Enable the device, if required. + if ((device_status[self->device] & PWM_TCC_ENABLED) == 0) { + tcc->CTRLBSET.reg = TCC_CTRLBSET_CMD_UPDATE; + tcc->CTRLA.reg |= TCC_CTRLA_ENABLE; + while (tcc->SYNCBUSY.reg & TCC_SYNCBUSY_ENABLE) { + } + device_status[self->device] |= PWM_TCC_ENABLED; + } + // Unlock the register update, now that the settings are complete + tcc->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD; +} + +STATIC mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(self->instance->CC[self->channel].reg * PWM_FULL_SCALE / (self->instance->PER.reg + 1)); +} + +STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16) { + put_duty_value(self->device, self->channel, duty_u16); + // If the device is enabled, than the period is set and we get a reasonable value for + // the duty cycle, set to the CCBUF register. Otherwise, PWM does not start. + if (self->instance->CTRLA.reg & TCC_CTRLA_ENABLE) { + self->instance->CCBUF[self->channel].reg = (uint64_t)duty_u16 * (self->instance->PER.reg + 1) / PWM_FULL_SCALE; + } + duty_type_flags[self->device] |= 1 << self->channel; +} + +STATIC mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(1000000000ULL * self->instance->CC[self->channel].reg * self->prescaler / PWM_MASTER_CLK); +} + +STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) { + put_duty_value(self->device, self->channel, duty_ns); + self->instance->CCBUF[self->channel].reg = (uint64_t)duty_ns * PWM_MASTER_CLK / self->prescaler / 1000000000ULL; + duty_type_flags[self->device] &= ~(1 << self->channel); +} diff --git a/ports/samd/main.c b/ports/samd/main.c index ece86f5889b6..4af4b2b4f8e5 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -34,6 +34,7 @@ extern uint8_t _sstack, _estack, _sheap, _eheap; extern void adc_deinit_all(void); +extern void pwm_deinit_all(void); void samd_main(void) { mp_stack_set_top(&_estack); @@ -64,6 +65,7 @@ void samd_main(void) { mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); adc_deinit_all(); + pwm_deinit_all(); gc_sweep_all(); mp_deinit(); } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 287641cc33aa..e0a037846156 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -133,6 +133,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, }; diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 53914a10c7fc..00e72ede1a7f 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -31,5 +31,6 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; +extern const mp_obj_type_t machine_pwm_type; #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 6441818ba2c5..70bd202a313b 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -99,6 +99,10 @@ #define MICROPY_PY_UASYNCIO (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) +#define MICROPY_PY_MACHINE_PWM (1) +#define MICROPY_PY_MACHINE_PWM_INIT (0) +#define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) +#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/samd/machine_pwm.c" #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index e51f13ab7e9f..7a3786be8c31 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -61,6 +61,10 @@ void mp_hal_set_pin_mux(mp_hal_pin_obj_t pin, uint8_t mux) { } } +void mp_hal_clr_pin_mux(mp_hal_pin_obj_t pin) { + int pin_grp = pin / 32; + PORT->Group[pin_grp].PINCFG[pin % 32].bit.PMUXEN = 0; // Disable Mux +} void mp_hal_delay_ms(mp_uint_t ms) { if (ms > 10) { diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index 0a1db7df0c5b..6161d9821ff9 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -84,6 +84,7 @@ extern uint32_t machine_pin_open_drain_mask[]; mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in); void mp_hal_set_pin_mux(mp_hal_pin_obj_t pin, uint8_t mux); +void mp_hal_clr_pin_mux(mp_hal_pin_obj_t pin); static inline unsigned int mp_hal_pin_name(mp_hal_pin_obj_t pin) { return pin; From a9eef1b27653b1604d945f95c7ca6d1ce875b9de Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 11:52:33 +0200 Subject: [PATCH 1814/4290] samd/samd_isr: Rework the interrupt tables. Changes are: - Have two separate tables for SAM21 and SAMD51. - Use a short table for SAMD21. - Add a comment to each line telling what it's for, making further use easier. - Add preliminary handlers/entries for PendSV, EIC and Sercom. These will be replaced later when the respecitve modules are added. --- ports/samd/samd_isr.c | 406 ++++++++++++++++++++++++++---------------- 1 file changed, 256 insertions(+), 150 deletions(-) diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index a7956c49305f..e16018c5348c 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -24,14 +24,23 @@ * THE SOFTWARE. */ +#include "py/runtime.h" +#include "py/mphal.h" #include "samd_soc.h" +// includes for Softtimer +// #include "pendsv.h" +// #include "softtimer.h" typedef void (*ISR)(void); extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss; +extern void Default_Handler(void); +extern void SysTick_Handler(void); +extern void PendSV_Handler(void); +extern void EIC_Handler(void); const ISR isr_vector[]; -uint32_t systick_ms; +volatile uint32_t systick_ms; volatile uint32_t systick_ms_upper; void Reset_Handler(void) __attribute__((naked)); @@ -87,8 +96,115 @@ void SysTick_Handler(void) { if (systick_ms == 0) { systick_ms_upper += 1; } + + // if (soft_timer_next == next_tick) { + // pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler); + // } +} + +// Temporary Handlers to allow builds. +// Will be removed when the respecitve module is added. +void EIC_Handler(void) { +} + +void PendSV_Handler(void) { +} + + +static uint8_t sercom_irq_type[SERCOM_INST_NUM] = {}; +void (*sercom_irq_handler_table[])(int num) = { + // Temporarily commented until the module is added + NULL, // common_uart_irq_handler, + NULL, // common_spi_irq_handler, + NULL // common_i2c_irq_handler +}; + +void sercom_register_irq(int sercom_id, int mode) { + sercom_irq_type[sercom_id] = mode; +} + +static inline void common_sercom_irq_handler(int sercom_id) { + if (sercom_irq_handler_table[sercom_irq_type[sercom_id]]) { + sercom_irq_handler_table[sercom_irq_type[sercom_id]](sercom_id); + } +} + +void Sercom0_Handler(void) { + common_sercom_irq_handler(0); +} +void Sercom1_Handler(void) { + common_sercom_irq_handler(1); +} +void Sercom2_Handler(void) { + common_sercom_irq_handler(2); +} +void Sercom3_Handler(void) { + common_sercom_irq_handler(3); +} +void Sercom4_Handler(void) { + common_sercom_irq_handler(4); +} +void Sercom5_Handler(void) { + common_sercom_irq_handler(5); +} +#if defined(MCU_SAMD51) +void Sercom6_Handler(void) { + common_sercom_irq_handler(6); } +void Sercom7_Handler(void) { + common_sercom_irq_handler(7); +} +#endif + +#if defined(MCU_SAMD21) +const ISR isr_vector[] __attribute__((section(".isr_vector"))) = { + (ISR)&_estack, + &Reset_Handler, + &Default_Handler, // NMI_Handler + &Default_Handler, // HardFault_Handler + &Default_Handler, // MemManage_Handler + &Default_Handler, // BusFault_Handler + &Default_Handler, // UsageFault_Handler + 0, + 0, + 0, + 0, + &Default_Handler, // SVC_Handler + &Default_Handler, // DebugMon_Handler + 0, + &PendSV_Handler, // PendSV_Handler + &SysTick_Handler, // SysTick_Handler + 0, // 0 Power Manager (PM) + 0, // 1 System Control (SYSCTRL) + 0, // 2 Watchdog Timer (WDT) + 0, // 3 Real-Time Counter (RTC) + &EIC_Handler, // 4 External Interrupt Controller (EIC) + 0, // 5 Non-Volatile Memory Controller (NVMCTRL) + 0, // 6 Direct Memory Access Controller (DMAC) + USB_Handler_wrapper,// 7 Universal Serial Bus (USB) + 0, // 8 Event System Interface (EVSYS) + &Sercom0_Handler, // 9 Serial Communication Interface 0 (SERCOM0) + &Sercom1_Handler, // 10 SAMD21G18A Serial Communication Interface 1 (SERCOM1) + &Sercom2_Handler, // 11 SAMD21G18A Serial Communication Interface 2 (SERCOM2) + &Sercom3_Handler, // 12 SAMD21G18A Serial Communication Interface 3 (SERCOM3) + &Sercom4_Handler, // 13 SAMD21G18A Serial Communication Interface 4 (SERCOM4) + &Sercom5_Handler, // 14 SAMD21G18A Serial Communication Interface 5 (SERCOM5) + 0, // 15 Timer Counter Control 0 (TCC0) + 0, // 16 Timer Counter Control 1 (TCC1) + 0, // 17 Timer Counter Control 2 (TCC2) + 0, // 18 Basic Timer Counter 3 (TC3) + 0, // 19 Basic Timer Counter 4 (TC4) + 0, // 20 Basic Timer Counter 5 (TC5) + 0, // 21 Basic Timer Counter 6 (TC6) + 0, // 22 Basic Timer Counter 7 (TC7) + 0, // 23 Analog Digital Converter (ADC) + 0, // 24 Analog Comparators (AC) + 0, // 25 Digital Analog Converter (DAC) + 0, // 26 Peripheral Touch Controller (PTC) + 0, // 27 Inter-IC Sound Interface (I2S) +}; +#else const ISR isr_vector[] __attribute__((section(".isr_vector"))) = { (ISR)&_estack, &Reset_Handler, @@ -104,154 +220,144 @@ const ISR isr_vector[] __attribute__((section(".isr_vector"))) = { &Default_Handler, // SVC_Handler &Default_Handler, // DebugMon_Handler 0, - &Default_Handler, // PendSV_Handler + &PendSV_Handler, // PendSV_Handler &SysTick_Handler, // SysTick_Handler - 0, // line 0 - 0, - 0, - 0, - 0, - 0, - 0, - #if defined(MCU_SAMD21) - USB_Handler_wrapper, // line 7 - #else - 0, - #endif - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - #if defined(MCU_SAMD51) - &USB_0_Handler_wrapper, // line 80 - &USB_1_Handler_wrapper, - &USB_2_Handler_wrapper, - &USB_3_Handler_wrapper, - #else - 0, - 0, - 0, - 0, - #endif - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 0, // 0 Power Manager (PM) + 0, // 1 Main Clock (MCLK) + 0, // 2 Oscillators Control (OSCCTRL): OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 + 0, // 3 Oscillators Control (OSCCTRL): OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 + 0, // 4 Oscillators Control (OSCCTRL): OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY + 0, // 5 Oscillators Control (OSCCTRL): OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 + 0, // 6 Oscillators Control (OSCCTRL): OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 + 0, // 7 32kHz Oscillators Control (OSC32KCTRL) + 0, // 8 Supply Controller (SUPC): SUPC_B12SRDY, SUPC_B33SRDY, SUP + 0, // 9 Supply Controller (SUPC): SUPC_BOD12DET, SUPC_BOD33DET + 0, // 10 Watchdog Timer (WDT) + 0, // 11 Real-Time Counter (RTC) + &EIC_Handler, // 12 External Interrupt Controller (EIC): EIC_EXTINT_0 + &EIC_Handler, // 13 External Interrupt Controller (EIC): EIC_EXTINT_1 + &EIC_Handler, // 14 External Interrupt Controller (EIC): EIC_EXTINT_2 + &EIC_Handler, // 15 External Interrupt Controller (EIC): EIC_EXTINT_3 + &EIC_Handler, // 16 External Interrupt Controller (EIC): EIC_EXTINT_4 + &EIC_Handler, // 17 External Interrupt Controller (EIC): EIC_EXTINT_5 + &EIC_Handler, // 18 External Interrupt Controller (EIC): EIC_EXTINT_6 + &EIC_Handler, // 19 External Interrupt Controller (EIC): EIC_EXTINT_7 + &EIC_Handler, // 20 External Interrupt Controller (EIC): EIC_EXTINT_8 + &EIC_Handler, // 21 External Interrupt Controller (EIC): EIC_EXTINT_9 + &EIC_Handler, // 22 External Interrupt Controller (EIC): EIC_EXTINT_10 + &EIC_Handler, // 23 External Interrupt Controller (EIC): EIC_EXTINT_11 + &EIC_Handler, // 24 External Interrupt Controller (EIC): EIC_EXTINT_12 + &EIC_Handler, // 25 External Interrupt Controller (EIC): EIC_EXTINT_13 + &EIC_Handler, // 26 External Interrupt Controller (EIC): EIC_EXTINT_14 + &EIC_Handler, // 27 External Interrupt Controller (EIC): EIC_EXTINT_15 + 0, // 28 Frequency Meter (FREQM) + 0, // 29 Non-Volatile Memory Controller (NVMCTRL): NVMCTRL_0 - _7 + 0, // 30 Non-Volatile Memory Controller (NVMCTRL): NVMCTRL_8 - _10 + 0, // 31 Direct Memory Access Controller (DMAC): DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 + 0, // 32 Direct Memory Access Controller (DMAC): DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 + 0, // 33 Direct Memory Access Controller (DMAC): DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 + 0, // 34 Direct Memory Access Controller (DMAC): DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 + 0, // 35 Direct Memory Access Controller (DMAC): DMAC_SUSP_4 - _31, DMAC_TCMPL_4 _31, DMAC_TERR_4- _31 + 0, // 36 Event System Interface (EVSYS): EVSYS_EVD_0, EVSYS_OVR_0 + 0, // 37 Event System Interface (EVSYS): EVSYS_EVD_1, EVSYS_OVR_1 + 0, // 38 Event System Interface (EVSYS): EVSYS_EVD_2, EVSYS_OVR_2 + 0, // 39 Event System Interface (EVSYS): EVSYS_EVD_3, EVSYS_OVR_3 + 0, // 40 Event System Interface (EVSYS): EVSYS_EVD_10, EVSYS_EVD_11 + 0, // 41 Peripheral Access Controller (PAC) + 0, // 42 Trigger Allocator (TAL): TAL_BRK + 0, // 43 Trigger Allocator (TAL): TAL_IPS_x + 0, + 0, // 45 RAM ECC (RAMECC) + &Sercom0_Handler, // 46 Serial Communication Interface 0 (SERCOM0): SERCOM0_0 + &Sercom0_Handler, // 47 Serial Communication Interface 0 (SERCOM0): SERCOM0_1 + &Sercom0_Handler, // 48 Serial Communication Interface 0 (SERCOM0): SERCOM0_2 + &Sercom0_Handler, // 49 Serial Communication Interface 0 (SERCOM0): SERCOM0_3 - 6 + &Sercom1_Handler, // 50 Serial Communication Interface 1 (SERCOM1): SERCOM1_0 + &Sercom1_Handler, // 51 Serial Communication Interface 1 (SERCOM1): SERCOM1_1 + &Sercom1_Handler, // 52 Serial Communication Interface 1 (SERCOM1): SERCOM1_2 + &Sercom1_Handler, // 53 Serial Communication Interface 1 (SERCOM1): SERCOM1_3 - 6 + &Sercom2_Handler, // 54 Serial Communication Interface 2 (SERCOM2): SERCOM2_0 + &Sercom2_Handler, // 55 Serial Communication Interface 2 (SERCOM2): SERCOM2_1 + &Sercom2_Handler, // 56 Serial Communication Interface 2 (SERCOM2): SERCOM2_2 + &Sercom2_Handler, // 57 Serial Communication Interface 2 (SERCOM2): SERCOM2_3 - 6 + &Sercom3_Handler, // 58 Serial Communication Interface 3 (SERCOM3): SERCOM3_0 + &Sercom3_Handler, // 59 Serial Communication Interface 3 (SERCOM3): SERCOM3_1 + &Sercom3_Handler, // 60 Serial Communication Interface 3 (SERCOM3): SERCOM3_2 + &Sercom3_Handler, // 61 Serial Communication Interface 3 (SERCOM3): SERCOM3_3 - 6 + &Sercom4_Handler, // 62 Serial Communication Interface 4 (SERCOM4): SERCOM4_0 + &Sercom4_Handler, // 63 Serial Communication Interface 4 (SERCOM4): SERCOM4_1 + &Sercom4_Handler, // 64 Serial Communication Interface 4 (SERCOM4): SERCOM4_2 + &Sercom4_Handler, // 65 Serial Communication Interface 4 (SERCOM4): SERCOM4_3 - 6 + &Sercom5_Handler, // 66 Serial Communication Interface 5 (SERCOM5): SERCOM5_0 + &Sercom5_Handler, // 67 Serial Communication Interface 5 (SERCOM5): SERCOM5_1 + &Sercom5_Handler, // 68 Serial Communication Interface 5 (SERCOM5): SERCOM5_2 + &Sercom5_Handler, // 69 Serial Communication Interface 5 (SERCOM5): SERCOM5_3 - 6 + &Sercom6_Handler, // 70 Serial Communication Interface 6 (SERCOM6): SERCOM6_0 + &Sercom6_Handler, // 71 Serial Communication Interface 6 (SERCOM6): SERCOM6_1 + &Sercom6_Handler, // 72 Serial Communication Interface 6 (SERCOM6): SERCOM6_2 + &Sercom6_Handler, // 73 Serial Communication Interface 6 (SERCOM6): SERCOM6_3 - 6 + &Sercom7_Handler, // 74 Serial Communication Interface 7 (SERCOM7): SERCOM7_0 + &Sercom7_Handler, // 75 Serial Communication Interface 7 (SERCOM7): SERCOM7_1 + &Sercom7_Handler, // 76 Serial Communication Interface 7 (SERCOM7): SERCOM7_2 + &Sercom7_Handler, // 77 Serial Communication Interface 7 (SERCOM7): SERCOM7_3 - 6 + 0, // 78 Control Area Network 0 (CAN0) + 0, // 79 Control Area Network 1 (CAN1) + &USB_0_Handler_wrapper, // 80 Universal Serial Bus (USB): USB_EORSM_DNRS, ... + &USB_1_Handler_wrapper, // 81 Universal Serial Bus (USB): USB_SOF_HSOF + &USB_2_Handler_wrapper, // 82 Universal Serial Bus (USB): USB_TRCPT0_0 - _7 + &USB_3_Handler_wrapper, // 83 Universal Serial Bus (USB): USB_TRCPT1_0 - _7 + 0, // 84 Ethernet MAC (GMAC) + 0, // 85 Timer Counter Control 0 (TCC0): TCC0_CNT_A ... + 0, // 86 Timer Counter Control 0 (TCC0): TCC0_MC_0 + 0, // 87 Timer Counter Control 0 (TCC0): TCC0_MC_1 + 0, // 88 Timer Counter Control 0 (TCC0): TCC0_MC_2 + 0, // 89 Timer Counter Control 0 (TCC0): TCC0_MC_3 + 0, // 90 Timer Counter Control 0 (TCC0): TCC0_MC_4 + 0, // 91 Timer Counter Control 0 (TCC0): TCC0_MC_5 + 0, // 92 Timer Counter Control 1 (TCC1): TCC1_CNT_A ... + 0, // 93 Timer Counter Control 1 (TCC1): TCC1_MC_0 + 0, // 94 Timer Counter Control 1 (TCC1): TCC1_MC_1 + 0, // 95 Timer Counter Control 1 (TCC1): TCC1_MC_2 + 0, // 96 Timer Counter Control 1 (TCC1): TCC1_MC_3 + 0, // 97 Timer Counter Control 2 (TCC2): TCC2_CNT_A ... + 0, // 98 Timer Counter Control 2 (TCC2): TCC2_MC_0 + 0, // 99 Timer Counter Control 2 (TCC2): TCC2_MC_1 + 0, // 100 Timer Counter Control 2 (TCC2): TCC2_MC_2 + 0, // 101 Timer Counter Control 3 (TCC3): TCC3_CNT_A ... + 0, // 102 Timer Counter Control 3 (TCC3): TCC3_MC_0 + 0, // 103 Timer Counter Control 3 (TCC3): TCC3_MC_1 + 0, // 104 Timer Counter Control 4 (TCC4): TCC4_CNT_A ... + 0, // 105 Timer Counter Control 4 (TCC4): TCC4_MC_0 + 0, // 106 Timer Counter Control 4 (TCC4): TCC4_MC_1 + 0, // 107 Basic Timer Counter 0 (TC0) + 0, // 108 Basic Timer Counter 1 (TC1) + 0, // 109 Basic Timer Counter 2 (TC2) + 0, // 110 Basic Timer Counter 3 (TC3) + 0, // 111 Basic Timer Counter 4 (TC4) + 0, // 112 Basic Timer Counter 5 (TC5) + 0, // 113 Basic Timer Counter 6 (TC6) + 0, // 114 Basic Timer Counter 7 (TC7) + 0, // 115 Quadrature Decoder (PDEC): PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A + 0, // 116 Quadrature Decoder (PDEC): PDEC_MC_0 + 0, // 117 Quadrature Decoder (PDEC): PDEC_MC_1 + 0, // 118 Analog Digital Converter 0 (ADC0): ADC0_OVERRUN, ADC0_WINMON + 0, // 119 Analog Digital Converter 0 (ADC0): ADC0_RESRDY + 0, // 120 Analog Digital Converter 1 (ADC1): ADC1_OVERRUN, ADC1_WINMON + 0, // 121 Analog Digital Converter 1 (ADC1): ADC1_RESRDY + 0, // 122 Analog Comparators (AC) + 0, // 123 Digital-to-Analog Converter (DAC): DAC_OVERRUN_A_x, DAC_UNDERRUN_A_x + 0, // 124 Digital-to-Analog Converter (DAC): DAC_EMPTY_0 + 0, // 125 Digital-to-Analog Converter (DAC): DAC_EMPTY_1 + 0, // 126 Digital-to-Analog Converter (DAC): DAC_RESRDY_0 + 0, // 127 Digital-to-Analog Converter (DAC): DAC_RESRDY_1 + 0, // 128 Inter-IC Sound Interface (I2S) + 0, // 129 Parallel Capture Controller (PCC) + 0, // 130 Advanced Encryption Standard (AES) + 0, // 131 True Random Generator (TRNG) + 0, // 132 Integrity Check Monitor (ICM) + 0, // 133 PUblic-Key Cryptography Controller (PUKCC) + 0, // 134 Quad SPI interface (QSPI) + 0, // 135 SD/MMC Host Controller 0 (SDHC0) + 0, // 136 SD/MMC Host Controller 1 (SDHC1) }; +#endif From 4b6f6ccf88c652401e39e621b515d06140d35225 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 14:08:44 +0200 Subject: [PATCH 1815/4290] samd/machine_pin: Add pin.irq() to the machine.Pin class. Its API conforms to the docs. There are 16 IRQ channels available, which will be used as assignable to the GPIO numbers. In most cases, the irq channel is GPIO_no % 16. --- ports/samd/Makefile | 2 + ports/samd/machine_pin.c | 200 +++++++++++++++++++++++++++++++++++++- ports/samd/main.c | 2 + ports/samd/mpconfigport.h | 6 +- ports/samd/samd_isr.c | 3 - 5 files changed, 207 insertions(+), 6 deletions(-) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 514c92ba1bd6..163971cde734 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -118,6 +118,7 @@ SRC_C = \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ lib/tinyusb/src/tusb.c \ drivers/bus/softspi.c \ + shared/runtime/mpirq.c \ shared/libc/printf.c \ shared/libc/string0.c \ shared/readline/readline.c \ @@ -148,6 +149,7 @@ SRC_QSTR += \ modsamd.c \ samd_flash.c \ shared/readline/readline.c \ + shared/runtime/mpirq.c \ SRC_QSTR += $(SRC_MOD) $(SRC_CXX) diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 98317abbf26a..a70e9ad0115d 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2016-2021 Damien P. George + * Copyright (c) 2022 Robert Hammelrath (pin.irq) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,10 +30,12 @@ #include "string.h" #include "py/runtime.h" #include "py/mphal.h" +#include "shared/runtime/mpirq.h" #include "extmod/virtpin.h" #include "modmachine.h" #include "samd_soc.h" #include "pins.h" +#include "pin_af.h" #include "hal_gpio.h" @@ -42,6 +45,17 @@ #define GPIO_STRENGTH_2MA (0) #define GPIO_STRENGTH_8MA (1) +#define GPIO_IRQ_EDGE_RISE (1) +#define GPIO_IRQ_EDGE_FALL (2) + +typedef struct _machine_pin_irq_obj_t { + mp_irq_obj_t base; + uint32_t flags; + uint32_t trigger; + uint8_t pin_id; +} machine_pin_irq_obj_t; + +STATIC const mp_irq_methods_t machine_pin_irq_methods; uint32_t machine_pin_open_drain_mask[4]; @@ -262,6 +276,141 @@ STATIC mp_obj_t machine_pin_drive(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_drive_obj, 1, 2, machine_pin_drive); +// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING, hard=False) +STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_handler, ARG_trigger, ARG_hard }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_handler, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_trigger, MP_ARG_INT, {.u_int = 3} }, + { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} }, + }; + machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Get the IRQ object. + uint8_t eic_id = get_pin_af_info(self->id)->eic; + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); + if (irq != NULL && irq->pin_id != self->id) { + mp_raise_ValueError(MP_ERROR_TEXT("IRQ already used")); + } + + // Allocate the IRQ object if it doesn't already exist. + if (irq == NULL) { + irq = m_new_obj(machine_pin_irq_obj_t); + irq->base.base.type = &mp_irq_type; + irq->base.methods = (mp_irq_methods_t *)&machine_pin_irq_methods; + irq->base.parent = MP_OBJ_FROM_PTR(self); + irq->base.handler = mp_const_none; + irq->base.ishard = false; + irq->pin_id = 0xff; + MP_STATE_PORT(machine_pin_irq_objects[eic_id]) = irq; + } + // (Re-)configure the irq. + if (n_args > 1 || kw_args->used != 0) { + + // set the mux config of the pin. + mp_hal_set_pin_mux(self->id, ALT_FCT_EIC); + + // Configure IRQ. + #if defined(MCU_SAMD21) + + uint32_t irq_num = 4; + // Disable all IRQs from the affected source while data is updated. + NVIC_DisableIRQ(irq_num); + // Disable EIC + EIC->CTRL.bit.ENABLE = 0; + while (EIC->STATUS.bit.SYNCBUSY != 0) { + } + EIC->INTENCLR.reg = (1 << eic_id); + // Enable the clocks + PM->APBAMASK.bit.EIC_ |= 1; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | EIC_GCLK_ID; + + #elif defined(MCU_SAMD51) + + uint32_t irq_num = eic_id + 12; + // Disable all IRQs from the affected source while data is updated. + NVIC_DisableIRQ(irq_num); + // Disable EIC + EIC->CTRLA.bit.ENABLE = 0; + while (EIC->SYNCBUSY.bit.ENABLE != 0) { + } + EIC->INTENCLR.reg = (1 << eic_id); + // Enable the clocks + MCLK->APBAMASK.bit.EIC_ |= 1; + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; + + #endif + // Clear the pending interrupts flag + EIC->INTENCLR.reg = (1 << eic_id); + + // Update IRQ data. + irq->base.handler = args[ARG_handler].u_obj; + irq->base.ishard = args[ARG_hard].u_bool; + irq->flags = 0; + irq->trigger = args[ARG_trigger].u_int; + irq->pin_id = self->id; + + // Enable IRQ if a handler is given. + if (args[ARG_handler].u_obj != mp_const_none) { + // Set EIC channel mode + EIC->CONFIG[eic_id / 8].reg |= irq->trigger << ((eic_id % 8) * 4); + EIC->INTENSET.reg = (1 << eic_id); + EIC->INTFLAG.reg |= (1 << eic_id); + } + + // Enable EIC (again) + #if defined(MCU_SAMD21) + EIC->CTRL.bit.ENABLE = 1; + while (EIC->STATUS.bit.SYNCBUSY != 0) { + } + #elif defined(MCU_SAMD51) + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE != 0) { + } + #endif + // Enable interrupt again + NVIC_EnableIRQ(irq_num); + } + return MP_OBJ_FROM_PTR(irq); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_irq_obj, 1, machine_pin_irq); + +void pin_irq_deinit_all(void) { + + EIC->INTENCLR.reg = 0xffff; // Disable all interrupts from the EIC. + for (int i = 0; i < 16; i++) { // Clear all irq object pointers + MP_STATE_PORT(machine_pin_irq_objects[i]) = NULL; + } + // Disable all irq's at the NVIC controller + #if defined(MCU_SAMD21) + NVIC_DisableIRQ(4); + #elif defined(MCU_SAMD51) + for (int i = 12; i < 20; i++) { + NVIC_DisableIRQ(i); + } + #endif +} + +// Common EIC handler for all events. +void EIC_Handler() { + uint32_t mask = 1; + uint32_t isr = EIC->INTFLAG.reg; + for (int eic_id = 0; eic_id < 16; eic_id++, mask <<= 1) { + // Did the ISR fire? + if (isr & mask) { + EIC->INTFLAG.reg |= mask; // clear the ISR flag + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); + if (irq != NULL) { + irq->flags = irq->trigger; + mp_irq_handler(&irq->base); + break; + } + } + } +} + STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { // instance methods { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) }, @@ -273,6 +422,7 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) }, { MP_ROM_QSTR(MP_QSTR_disable), MP_ROM_PTR(&machine_pin_disable_obj) }, { MP_ROM_QSTR(MP_QSTR_drive), MP_ROM_PTR(&machine_pin_drive_obj) }, + { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) }, // class constants { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_IN) }, @@ -283,6 +433,8 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) }, { MP_ROM_QSTR(MP_QSTR_LOW_POWER), MP_ROM_INT(GPIO_STRENGTH_2MA) }, { MP_ROM_QSTR(MP_QSTR_HIGH_POWER), MP_ROM_INT(GPIO_STRENGTH_8MA) }, + { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_IRQ_EDGE_RISE) }, + { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_IRQ_EDGE_FALL) }, }; STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); @@ -292,10 +444,10 @@ STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, i switch (request) { case MP_PIN_READ: { - return gpio_get_pin_level(self->id); + return mp_hal_pin_read(self->id); } case MP_PIN_WRITE: { - gpio_set_pin_level(self->id, arg); + mp_hal_pin_write(self->id, arg); return 0; } } @@ -317,6 +469,48 @@ MP_DEFINE_CONST_OBJ_TYPE( locals_dict, &machine_pin_locals_dict ); +static uint8_t find_eic_id(int pin) { + for (int eic_id = 0; eic_id < 16; eic_id++) { + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); + if (irq != NULL && irq->pin_id == pin) { + return eic_id; + } + } + return 0xff; +} + +STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint8_t eic_id = find_eic_id(self->id); + if (eic_id != 0xff) { + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); + EIC->INTENCLR.reg |= (1 << eic_id); + irq->flags = 0; + irq->trigger = new_trigger; + EIC->INTENSET.reg |= (1 << eic_id); + } + return 0; +} + +STATIC mp_uint_t machine_pin_irq_info(mp_obj_t self_in, mp_uint_t info_type) { + machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint8_t eic_id = find_eic_id(self->id); + if (eic_id != 0xff) { + machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); + if (info_type == MP_IRQ_INFO_FLAGS) { + return irq->flags; + } else if (info_type == MP_IRQ_INFO_TRIGGERS) { + return irq->trigger; + } + } + return 0; +} + +STATIC const mp_irq_methods_t machine_pin_irq_methods = { + .trigger = machine_pin_irq_trigger, + .info = machine_pin_irq_info, +}; + mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) { if (!mp_obj_is_type(obj, &machine_pin_type)) { mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin")); @@ -324,3 +518,5 @@ mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) { machine_pin_obj_t *pin = MP_OBJ_TO_PTR(obj); return pin->id; } + +MP_REGISTER_ROOT_POINTER(void *machine_pin_irq_objects[16]); diff --git a/ports/samd/main.c b/ports/samd/main.c index 4af4b2b4f8e5..520763b5aa4a 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -34,6 +34,7 @@ extern uint8_t _sstack, _estack, _sheap, _eheap; extern void adc_deinit_all(void); +extern void pin_irq_deinit_all(void); extern void pwm_deinit_all(void); void samd_main(void) { @@ -65,6 +66,7 @@ void samd_main(void) { mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); adc_deinit_all(); + pin_irq_deinit_all(); pwm_deinit_all(); gc_sweep_all(); mp_deinit(); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 70bd202a313b..574d47b035de 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -54,7 +54,7 @@ #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_TEXT samd_help_text #define MICROPY_PY_BUILTINS_HELP_MODULES (1) - +#define MICROPY_ENABLE_SCHEDULER (1) // fixes sys/usys import issue #define MICROPY_MODULE_WEAK_LINKS (1) // Control over Python builtins @@ -104,6 +104,10 @@ #define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/samd/machine_pwm.c" +// Use VfsLfs's types for fileio/textio +#define mp_type_fileio mp_type_vfs_lfs1_fileio +#define mp_type_textio mp_type_vfs_lfs1_textio + #define MP_STATE_PORT MP_STATE_VM // Miscellaneous settings diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index e16018c5348c..a4e1dd708c41 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -104,9 +104,6 @@ void SysTick_Handler(void) { // Temporary Handlers to allow builds. // Will be removed when the respecitve module is added. -void EIC_Handler(void) { -} - void PendSV_Handler(void) { } From 7d281f6165d50a75ba21eda4d8d253a8982f3543 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 14:28:08 +0200 Subject: [PATCH 1816/4290] samd/modmachine: Add disable_irq(), enable_irq() and idle() to machine. No specific features. --- ports/samd/modmachine.c | 23 +++++++++++++++++++++++ ports/samd/mpconfigport.h | 12 ++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index e0a037846156..eafe9972d065 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -120,6 +120,25 @@ STATIC mp_obj_t machine_unique_id(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id); +STATIC mp_obj_t machine_idle(void) { + MICROPY_EVENT_POLL_HOOK; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle); + +STATIC mp_obj_t machine_disable_irq(void) { + uint32_t state = MICROPY_BEGIN_ATOMIC_SECTION(); + return mp_obj_new_int(state); +} +MP_DEFINE_CONST_FUN_OBJ_0(machine_disable_irq_obj, machine_disable_irq); + +STATIC mp_obj_t machine_enable_irq(mp_obj_t state_in) { + uint32_t state = mp_obj_get_int(state_in); + MICROPY_END_ATOMIC_SECTION(state); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq); + STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, @@ -136,6 +155,10 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, + + { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, + { 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) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 574d47b035de..fba4ee13d286 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -111,6 +111,18 @@ #define MP_STATE_PORT MP_STATE_VM // Miscellaneous settings +__attribute__((always_inline)) static inline void enable_irq(uint32_t state) { + __set_PRIMASK(state); +} + +__attribute__((always_inline)) static inline uint32_t disable_irq(void) { + uint32_t state = __get_PRIMASK(); + __disable_irq(); + return state; +} + +#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq() +#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state) #define MICROPY_EVENT_POLL_HOOK \ do { \ From b33f2045290a379d2cefc1798780aa46f56e29a1 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 15:03:52 +0200 Subject: [PATCH 1817/4290] samd/machine_uart: Add the machine.UART class. All board pins that have UART's assigned can be used. Baud rate range is 75 Baud to ~2 MBaud. No flow control yet, and only RX is buffered. TX buffer and flow control may be added later for SAMD51 with its larger RAM and Flash. --- ports/samd/Makefile | 2 + ports/samd/machine_uart.c | 475 ++++++++++++++++++++++++++++++++++++++ ports/samd/main.c | 2 + ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + ports/samd/mpconfigport.h | 1 + ports/samd/samd_isr.c | 4 +- 7 files changed, 484 insertions(+), 2 deletions(-) create mode 100644 ports/samd/machine_uart.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 163971cde734..196b7acf11bf 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -93,6 +93,7 @@ SRC_C = \ machine_adc.c \ machine_led.c \ machine_pin.c \ + machine_uart.c \ main.c \ modutime.c \ modmachine.c \ @@ -144,6 +145,7 @@ SRC_QSTR += \ machine_led.c \ machine_pin.c \ machine_pwm.c \ + machine_uart.c \ modutime.c \ modmachine.c \ modsamd.c \ diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c new file mode 100644 index 000000000000..9c5cfce83994 --- /dev/null +++ b/ports/samd/machine_uart.c @@ -0,0 +1,475 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/stream.h" +#include "py/ringbuf.h" +#include "modmachine.h" +#include "samd_soc.h" +#include "pin_af.h" +#include "clock_config.h" + +#define DEFAULT_UART_BAUDRATE (115200) +#define DEFAULT_BUFFER_SIZE (256) +#define MIN_BUFFER_SIZE (32) +#define MAX_BUFFER_SIZE (32766) +#define USART_BUFFER_TX (0) + +typedef struct _machine_uart_obj_t { + mp_obj_base_t base; + uint8_t id; + uint32_t baudrate; + uint8_t bits; + uint8_t parity; + uint8_t stop; + uint8_t tx; + sercom_pad_config_t tx_pad_config; + uint8_t rx; + sercom_pad_config_t rx_pad_config; + uint16_t timeout; // timeout waiting for first char (in ms) + uint16_t timeout_char; // timeout waiting between chars (in ms) + bool new; + ringbuf_t read_buffer; + #if USART_BUFFER_TX + ringbuf_t write_buffer; + #endif +} machine_uart_obj_t; + +Sercom *sercom_instance[] = SERCOM_INSTS; +machine_uart_obj_t *uart_table[SERCOM_INST_NUM] = {}; + +STATIC const char *_parity_name[] = {"None", "", "0", "1"}; // Is defined as 0, 2, 3 + +// Irq handler + +// take all bytes from the fifo and store them in the buffer +STATIC void uart_drain_rx_fifo(machine_uart_obj_t *self, Sercom *uart) { + while (uart->USART.INTFLAG.bit.RXC != 0) { + if (ringbuf_free(&self->read_buffer) > 0) { + // get a byte from uart and put into the buffer + ringbuf_put(&(self->read_buffer), uart->USART.DATA.bit.DATA); + } else { + // if the buffer is full, discard the data for now + // t.b.d.: flow control + uint32_t temp; + (void)temp; + temp = uart->USART.DATA.bit.DATA; + } + } +} + +void common_uart_irq_handler(int uart_id) { + machine_uart_obj_t *self = uart_table[uart_id]; + // Handle IRQ + if (self != NULL) { + Sercom *uart = sercom_instance[self->id]; + if (uart->USART.INTFLAG.bit.RXC != 0) { + // Now handler the incoming data + uart_drain_rx_fifo(self, uart); + } else if (uart->USART.INTFLAG.bit.DRE != 0) { + // handle the outgoing data + } else { + // Disable the other interrupts, if set by error + uart->USART.INTENCLR.reg = (uint8_t) ~(SERCOM_USART_INTENCLR_DRE | SERCOM_USART_INTENCLR_RXC); + } + } +} + +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, " + "timeout=%u, timeout_char=%u, rxbuf=%d)", + self->id, self->baudrate, self->bits, _parity_name[self->parity], + self->stop + 1, self->timeout, self->timeout_char, self->read_buffer.size - 1); +} + +STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_tx, ARG_rx, + ARG_timeout, ARG_timeout_char, ARG_rxbuf, ARG_txbuf}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_bits, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_parity, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_INT(-1)} }, + { MP_QSTR_stop, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + #if USART_BUFFER_TX + { MP_QSTR_txbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + #endif + }; + + // Parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Set baudrate if configured. + if (args[ARG_baudrate].u_int > 0) { + self->baudrate = args[ARG_baudrate].u_int; + } + + // Set bits if configured. + if (args[ARG_bits].u_int > 0) { + self->bits = args[ARG_bits].u_int; + } + + // Set parity if configured. + if (args[ARG_parity].u_obj != MP_OBJ_NEW_SMALL_INT(-1)) { + if (args[ARG_parity].u_obj == mp_const_none) { + self->parity = 0; + } else if (mp_obj_get_int(args[ARG_parity].u_obj) & 1) { + self->parity = 1; // odd + } else { + self->parity = 2; // even + } + } + + // Set stop bits if configured. + if (args[ARG_stop].u_int > 0) { + self->stop = (args[ARG_stop].u_int - 1) & 1; + } + + // Set TX/RX pins if configured. + if (args[ARG_tx].u_obj != mp_const_none) { + self->tx = mp_hal_get_pin_obj(args[ARG_tx].u_obj); + } + if (args[ARG_rx].u_obj != mp_const_none) { + self->rx = mp_hal_get_pin_obj(args[ARG_rx].u_obj); + } + + // Set timeout if configured. + if (args[ARG_timeout].u_int >= 0) { + self->timeout = args[ARG_timeout].u_int; + } + + // Set timeout_char if configured. + if (args[ARG_timeout_char].u_int >= 0) { + self->timeout_char = args[ARG_timeout_char].u_int; + } + + // Set the RX buffer size if configured. + size_t rxbuf_len = DEFAULT_BUFFER_SIZE; + if (args[ARG_rxbuf].u_int > 0) { + rxbuf_len = args[ARG_rxbuf].u_int; + if (rxbuf_len < MIN_BUFFER_SIZE) { + rxbuf_len = MIN_BUFFER_SIZE; + } else if (rxbuf_len > MAX_BUFFER_SIZE) { + mp_raise_ValueError(MP_ERROR_TEXT("rxbuf too large")); + } + } + + #if USART_BUFFER_TX + // Set the TX buffer size if configured. + size_t txbuf_len = DEFAULT_BUFFER_SIZE; + if (args[ARG_txbuf].u_int > 0) { + txbuf_len = args[ARG_txbuf].u_int; + if (txbuf_len < MIN_BUFFER_SIZE) { + txbuf_len = MIN_BUFFER_SIZE; + } else if (txbuf_len > MAX_BUFFER_SIZE) { + mp_raise_ValueError(MP_ERROR_TEXT("txbuf too large")); + } + } + #endif + // Initialise the UART peripheral if any arguments given, or it was not initialised previously. + if (n_args > 0 || kw_args->used > 0 || self->new) { + self->new = false; + + // Check the rx/tx pin assignments + if (self->tx == 0xff || self->rx == 0xff || (self->tx / 4) != (self->rx / 4)) { + mp_raise_ValueError(MP_ERROR_TEXT("Non-matching or missing rx/tx")); + } + self->rx_pad_config = get_sercom_config(self->rx, self->id); + self->tx_pad_config = get_sercom_config(self->tx, self->id); + + // Make sure timeout_char is at least as long as a whole character (13 bits to be safe). + uint32_t min_timeout_char = 13000 / self->baudrate + 1; + if (self->timeout_char < min_timeout_char) { + self->timeout_char = min_timeout_char; + } + + // Allocate the RX/TX buffers. + ringbuf_alloc(&(self->read_buffer), rxbuf_len + 1); + MP_STATE_PORT(samd_uart_rx_buffer[self->id]) = self->read_buffer.buf; + + #if USART_BUFFER_TX + ringbuf_alloc(&(self->write_buffer), txbuf_len + 1); + MP_STATE_PORT(samd_uart_tx_buffer[self->id]) = self->write_buffer.buf; + #endif + + // Step 1: Configure the Pin mux. + mp_hal_set_pin_mux(self->rx, self->rx_pad_config.alt_fct); + mp_hal_set_pin_mux(self->tx, self->tx_pad_config.alt_fct); + + // Next: Set up the clocks + enable_sercom_clock(self->id); + + // Next: Configure the USART + Sercom *uart = sercom_instance[self->id]; + // Reset (clear) the peripheral registers. + while (uart->USART.SYNCBUSY.bit.SWRST) { + } + uart->USART.CTRLA.bit.SWRST = 1; // Reset all Registers, disable peripheral + while (uart->USART.SYNCBUSY.bit.SWRST) { + } + + uint8_t txpo = self->tx_pad_config.pad_nr; + #if defined(MCU_SAMD21) + if (self->tx_pad_config.pad_nr == 2) { // Map pad 2 to TXPO = 1 + txpo = 1; + } + #endif + + uart->USART.CTRLA.reg = + SERCOM_USART_CTRLA_DORD // Data order + | SERCOM_USART_CTRLA_FORM(self->parity != 0 ? 1 : 0) // Enable parity or not + | SERCOM_USART_CTRLA_RXPO(self->rx_pad_config.pad_nr) // Set Pad# + | SERCOM_USART_CTRLA_TXPO(txpo) // Set Pad# + | SERCOM_USART_CTRLA_MODE(1) // USART with internal clock + ; + uart->USART.CTRLB.reg = + SERCOM_USART_CTRLB_RXEN // Enable Rx & Tx + | SERCOM_USART_CTRLB_TXEN + | ((self->parity & 1) << SERCOM_USART_CTRLB_PMODE_Pos) + | (self->stop << SERCOM_USART_CTRLB_SBMODE_Pos) + | SERCOM_USART_CTRLB_CHSIZE((self->bits & 7) | (self->bits & 1)) + ; + while (uart->USART.SYNCBUSY.bit.CTRLB) { + } + + // USART is driven by the clock of GCLK Generator 2, freq by get_apb_freq() + // baud rate; 65536 * (1 - 16 * 115200/bus_freq) + uint32_t baud = 65536 - ((uint64_t)(65536 * 16) * self->baudrate + get_apb_freq() / 2) / get_apb_freq(); + uart->USART.BAUD.bit.BAUD = baud; // Set Baud + + // Enable RXC interrupt + uart->USART.INTENSET.bit.RXC = 1; + #if defined(MCU_SAMD21) + NVIC_EnableIRQ(SERCOM0_IRQn + self->id); + #elif defined(MCU_SAMD51) + NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2); + #endif + sercom_register_irq(self->id, SERCOM_IRQ_TYPE_UART); + + sercom_enable(uart, 1); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + // Get UART bus. + int uart_id = mp_obj_get_int(args[0]); + if (uart_id < 0 || uart_id > SERCOM_INST_NUM) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) doesn't exist"), uart_id); + } + + // Create the UART object and fill it with defaults. + machine_uart_obj_t *self = mp_obj_malloc(machine_uart_obj_t, &machine_uart_type); + self->id = uart_id; + self->baudrate = DEFAULT_UART_BAUDRATE; + self->bits = 8; + self->stop = 0; + self->timeout = 1; + self->timeout_char = 1; + self->tx = 0xff; + self->rx = 0xff; + self->new = true; + uart_table[uart_id] = self; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + return machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args); +} + +// uart.init(baud, [kwargs]) +STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return machine_uart_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init); + +STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + Sercom *uart = sercom_instance[self->id]; + // clear table entry of uart + uart_table[self->id] = NULL; + // Disable interrupts + uart->USART.INTENCLR.reg = 0xff; + MP_STATE_PORT(samd_uart_rx_buffer[self->id]) = NULL; + #if USART_BUFFER_TX + MP_STATE_PORT(samd_uart_tx_buffer[self->id]) = NULL; + #endif + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit); + +STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + // get all bytes from the fifo first + uart_drain_rx_fifo(self, sercom_instance[self->id]); + return MP_OBJ_NEW_SMALL_INT(ringbuf_avail(&self->read_buffer)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any); + +STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint32_t break_time_us = 13 * 1000000 / self->baudrate; + + // Wait for the TX queue & register to clear + // Since the flags are not safe, just wait sufficiently long. + // Once tx buffering is implemented, wait as well for the buffer to clear. + mp_hal_delay_us(2 * break_time_us); + // Disable MUX + PORT->Group[self->tx / 32].PINCFG[self->tx % 32].bit.PMUXEN = 0; + // Set TX pin to low for break time + mp_hal_pin_low(self->tx); + mp_hal_delay_us(break_time_us); + mp_hal_pin_high(self->tx); + // Enable Mux again + mp_hal_set_pin_mux(self->tx, self->tx_pad_config.alt_fct); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak); + +void uart_deinit_all(void) { + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (uart_table[i] != NULL) { + machine_uart_deinit((mp_obj_t)uart_table[i]); + } + } +} + +STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) }, + + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) }, + + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table); + +STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint64_t t = mp_hal_ticks_ms() + self->timeout; + uint64_t timeout_char = self->timeout_char; + uint8_t *dest = buf_in; + Sercom *uart = sercom_instance[self->id]; + + // t.b.d. Cater timeout for timer wrap after 50 days. + for (size_t i = 0; i < size; i++) { + // Wait for the first/next character + while (ringbuf_avail(&self->read_buffer) == 0) { + if (uart->USART.INTFLAG.bit.RXC != 0) { + // Force a few incoming bytes to the buffer + uart_drain_rx_fifo(self, uart); + break; + } + if (mp_hal_ticks_ms() > t) { // timed out + if (i <= 0) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } else { + return i; + } + } + MICROPY_EVENT_POLL_HOOK + } + *dest++ = ringbuf_get(&(self->read_buffer)); + t = mp_hal_ticks_ms() + timeout_char; + } + return size; +} + +STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t remaining = size; + const uint8_t *src = buf_in; + Sercom *uart = sercom_instance[self->id]; + + while (remaining--) { + while (!(uart->USART.INTFLAG.bit.DRE)) { + } + uart->USART.DATA.bit.DATA = *src; + src += 1; + } + + return size; +} + +STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + machine_uart_obj_t *self = self_in; + mp_uint_t ret; + Sercom *uart = sercom_instance[self->id]; + if (request == MP_STREAM_POLL) { + uintptr_t flags = arg; + ret = 0; + if ((flags & MP_STREAM_POLL_RD) && (uart->USART.INTFLAG.bit.RXC != 0 || ringbuf_avail(&self->read_buffer) > 0)) { + ret |= MP_STREAM_POLL_RD; + } + if ((flags & MP_STREAM_POLL_WR) && (uart->USART.INTFLAG.bit.DRE != 0)) { + ret |= MP_STREAM_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_stream_p_t uart_stream_p = { + .read = machine_uart_read, + .write = machine_uart_write, + .ioctl = machine_uart_ioctl, + .is_text = false, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + machine_uart_type, + MP_QSTR_UART, + MP_TYPE_FLAG_ITER_IS_STREAM, + make_new, machine_uart_make_new, + print, machine_uart_print, + protocol, &uart_stream_p, + locals_dict, &machine_uart_locals_dict + ); + +MP_REGISTER_ROOT_POINTER(void *samd_uart_rx_buffer[SERCOM_INST_NUM]); diff --git a/ports/samd/main.c b/ports/samd/main.c index 520763b5aa4a..60b8e57faa44 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -36,6 +36,7 @@ extern uint8_t _sstack, _estack, _sheap, _eheap; extern void adc_deinit_all(void); extern void pin_irq_deinit_all(void); extern void pwm_deinit_all(void); +extern void uart_deinit_all(void); void samd_main(void) { mp_stack_set_top(&_estack); @@ -68,6 +69,7 @@ void samd_main(void) { adc_deinit_all(); pin_irq_deinit_all(); pwm_deinit_all(); + uart_deinit_all(); gc_sweep_all(); mp_deinit(); } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index eafe9972d065..8c3033f891bd 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -155,6 +155,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 00e72ede1a7f..30de339b4a2d 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -32,5 +32,6 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_pwm_type; +extern const mp_obj_type_t machine_uart_type; #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index fba4ee13d286..b8cb0f3eb74f 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -48,6 +48,7 @@ #define MICROPY_HELPER_REPL (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_ENABLE_SOURCE_LINE (1) +#define MICROPY_STREAMS_NON_BLOCK (1) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index a4e1dd708c41..0e0d84db6906 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -109,9 +109,9 @@ void PendSV_Handler(void) { static uint8_t sercom_irq_type[SERCOM_INST_NUM] = {}; +// Temporarily commented until the module is added void (*sercom_irq_handler_table[])(int num) = { - // Temporarily commented until the module is added - NULL, // common_uart_irq_handler, + common_uart_irq_handler, NULL, // common_spi_irq_handler, NULL // common_i2c_irq_handler }; From aa870708ac262824ab5829e0f163f8f1e1332ada Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 17:02:46 +0200 Subject: [PATCH 1818/4290] samd/machine_spi: Add the machine.SPI class. Suported by both SAMD21 and SAMD51. It follows the generic API, except for the bits=nn option, which is not implemented (yet). --- ports/samd/Makefile | 2 + ports/samd/machine_spi.c | 330 ++++++++++++++++++++++++++++++++++++++ ports/samd/main.c | 2 + ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + ports/samd/mpconfigport.h | 1 + ports/samd/samd_isr.c | 2 +- 7 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 ports/samd/machine_spi.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 196b7acf11bf..ca0309fa6993 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -93,6 +93,7 @@ SRC_C = \ machine_adc.c \ machine_led.c \ machine_pin.c \ + machine_spi.c \ machine_uart.c \ main.c \ modutime.c \ @@ -145,6 +146,7 @@ SRC_QSTR += \ machine_led.c \ machine_pin.c \ machine_pwm.c \ + machine_spi.c \ machine_uart.c \ modutime.c \ modmachine.c \ diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c new file mode 100644 index 000000000000..b3504aeba32b --- /dev/null +++ b/ports/samd/machine_spi.c @@ -0,0 +1,330 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "py/runtime.h" +#include "py/mphal.h" +#include "extmod/machine_spi.h" +#include "modmachine.h" +#include "samd_soc.h" +#include "pin_af.h" +#include "clock_config.h" + +#define DEFAULT_SPI_BAUDRATE (1000000) +#define DEFAULT_SPI_POLARITY (0) +#define DEFAULT_SPI_PHASE (0) +#define DEFAULT_SPI_BITS (8) +#define DEFAULT_SPI_FIRSTBIT (0) + +typedef struct _machine_spi_obj_t { + mp_obj_base_t base; + uint8_t id; + uint8_t polarity; + uint8_t phase; + uint8_t firstbit; + uint8_t sck; + uint8_t mosi; + uint8_t miso; + uint8_t new; + uint32_t baudrate; + sercom_pad_config_t sck_pad_config; + sercom_pad_config_t mosi_pad_config; + sercom_pad_config_t miso_pad_config; + uint8_t *dest; + size_t rxlen; +} machine_spi_obj_t; + +extern Sercom *sercom_instance[]; +void *sercom_table[SERCOM_INST_NUM] = {}; + +void common_spi_irq_handler(int spi_id) { + // handle Sercom IRQ RXC + machine_spi_obj_t *self = sercom_table[spi_id]; + // Handle IRQ + if (self != NULL) { + Sercom *spi = sercom_instance[self->id]; + if (spi->SPI.INTFLAG.bit.RXC != 0) { + if (self->rxlen > 0) { + *(self->dest)++ = spi->SPI.DATA.bit.DATA; + self->rxlen--; + } else { + // Just in the unlikely case there is data but no space in the buffer + // discard the data and clear the intflag + uint32_t temp; + (void)temp; + temp = spi->SPI.DATA.bit.DATA; + } + } + } +} + +STATIC void machine_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "SPI(%u), baudrate=%u, firstbit=%u, polarity=%u, phase=%u, bits=8", + self->id, self->baudrate, self->firstbit, self->polarity, self->phase); +} + +STATIC void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_firstbit, + ARG_sck, ARG_mosi, ARG_miso}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_firstbit, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + }; + + machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // Parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Set baudrate if configured. + if (args[ARG_baudrate].u_int >= 0) { + self->baudrate = args[ARG_baudrate].u_int; + } + + // Set polarity if configured. + if (args[ARG_polarity].u_int >= 0) { + self->polarity = args[ARG_polarity].u_int; + } + + // Set phase if configured. + if (args[ARG_phase].u_int >= 0) { + self->phase = args[ARG_phase].u_int; + } + + // Set firstbit if configured. + if (args[ARG_firstbit].u_int >= 0) { + self->firstbit = args[ARG_firstbit].u_int; + } + + // Set SCK/MOSI/MISO pins if configured. + if (args[ARG_sck].u_obj != mp_const_none) { + self->sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj); + } + if (args[ARG_mosi].u_obj != mp_const_none) { + self->mosi = mp_hal_get_pin_obj(args[ARG_mosi].u_obj); + } + if (args[ARG_miso].u_obj != mp_const_none) { + self->miso = mp_hal_get_pin_obj(args[ARG_miso].u_obj); + } + + // Initialise the SPI peripheral if any arguments given, or it was not initialised previously. + if (n_args > 0 || kw_args->used > 0 || self->new) { + self->new = false; + + // Get the pad and alt-fct numbers. + self->sck_pad_config = get_sercom_config(self->sck, self->id); + self->mosi_pad_config = get_sercom_config(self->mosi, self->id); + + uint8_t dopo = 0; + #if defined(MCU_SAMD21) + if (self->mosi_pad_config.pad_nr == 0 && self->sck_pad_config.pad_nr == 1) { + dopo = 0; + } else if (self->mosi_pad_config.pad_nr == 2 && self->sck_pad_config.pad_nr == 3) { + dopo = 1; + } else if (self->mosi_pad_config.pad_nr == 3 && self->sck_pad_config.pad_nr == 1) { + dopo = 2; + } else if (self->mosi_pad_config.pad_nr == 0 && self->sck_pad_config.pad_nr == 3) { + dopo = 3; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for sck or mosi")); + } + #elif defined(MCU_SAMD51) + if (self->mosi_pad_config.pad_nr == 0 && self->sck_pad_config.pad_nr == 1) { + dopo = 0; + } else if (self->mosi_pad_config.pad_nr == 3 && self->sck_pad_config.pad_nr == 1) { + dopo = 2; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for sck or mosi")); + } + #endif + + if (self->miso != 0xff) { // Miso may be undefined + self->miso_pad_config = get_sercom_config(self->miso, self->id); + mp_hal_set_pin_mux(self->miso, self->miso_pad_config.alt_fct); + } + // Configure the Pin mux. + mp_hal_set_pin_mux(self->sck, self->sck_pad_config.alt_fct); + mp_hal_set_pin_mux(self->mosi, self->mosi_pad_config.alt_fct); + + // Set up the clocks + enable_sercom_clock(self->id); + + // Configure the SPI + Sercom *spi = sercom_instance[self->id]; + // Reset (clear) the peripheral registers. + while (spi->SPI.SYNCBUSY.bit.SWRST) { + } + spi->SPI.CTRLA.bit.SWRST = 1; + while (spi->SPI.SYNCBUSY.bit.SWRST) { + } + + // Set the registers + spi->SPI.CTRLA.bit.MODE = 0x03; // SPI master mode + spi->SPI.CTRLA.bit.CPOL = self->polarity; + spi->SPI.CTRLA.bit.CPHA = self->phase; + spi->SPI.CTRLA.bit.DIPO = self->miso_pad_config.pad_nr; + spi->SPI.CTRLA.bit.DOPO = dopo; + spi->SPI.CTRLA.bit.DORD = self->firstbit; + + // Enable receive only if miso is defined + if (self->miso != 0xff) { + spi->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_RXEN; + while (spi->SPI.SYNCBUSY.bit.CTRLB) { + } + } + + #if defined(MCU_SAMD51) + spi->SPI.CTRLC.reg = 1; // 1 clock cycle character spacing + #endif + + // SPI is driven by the clock of GCLK Generator 2, freq in bus_freq + // baud = bus_freq / (2 * baudrate) - 1 + uint32_t baud = get_apb_freq() / (2 * self->baudrate) - 1; + spi->SPI.BAUD.reg = baud; // Set Baud + + // Enable RXC interrupt only if miso is defined + if (self->miso != 0xff) { + #if defined(MCU_SAMD21) + NVIC_EnableIRQ(SERCOM0_IRQn + self->id); + #elif defined(MCU_SAMD51) + NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2); + #endif + sercom_register_irq(self->id, SERCOM_IRQ_TYPE_SPI); + } + + sercom_enable(spi, 1); + } +} + +STATIC mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + // Get SPI bus. + int spi_id = mp_obj_get_int(args[0]); + if (spi_id < 0 || spi_id > SERCOM_INST_NUM) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), spi_id); + } + + // Create the SPI object and fill it with defaults. + machine_spi_obj_t *self = mp_obj_malloc(machine_spi_obj_t, &machine_spi_type); + self->id = spi_id; + self->baudrate = DEFAULT_SPI_BAUDRATE; + self->polarity = DEFAULT_SPI_POLARITY; + self->phase = DEFAULT_SPI_PHASE; + self->firstbit = DEFAULT_SPI_FIRSTBIT; + self->mosi = 0xff; // 0xff: pin not defined (yet) + self->miso = 0xff; + self->sck = 0xff; + + self->new = true; + sercom_table[spi_id] = self; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_spi_init((mp_obj_base_t *)self, n_args - 1, args + 1, &kw_args); + return self; +} + +void sercom_deinit_all(void) { + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_table[i] != NULL) { + machine_spi_obj_t *self = sercom_table[i]; + Sercom *spi = sercom_instance[self->id]; + // Disable interrupts (if any) + spi->SPI.INTENCLR.reg = 0xff; + // clear table entry of spi + sercom_table[i] = NULL; + sercom_enable(spi, 0); + } + } +} + +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; + + Sercom *spi = sercom_instance[self->id]; + size_t txlen = len; + // Clear the input queue, if needed + while (dest && spi->SPI.INTFLAG.bit.RXC) { + uint32_t temp; + (void)temp; + temp = spi->SPI.DATA.bit.DATA; + } + // Set up the irq data pointers and enable IRQ + if (dest) { + if (self->miso == 0xff) { + mp_raise_ValueError(MP_ERROR_TEXT("read is not enabled")); + } + spi->SPI.INTENSET.bit.RXC = 1; + self->dest = dest; + self->rxlen = len; + } + + // Send by polling & receive by IRQ + while (txlen) { + if (spi->SPI.INTFLAG.bit.DRE) { + spi->SPI.DATA.bit.DATA = *src; + src += 1; + txlen--; + } + } + // Receive the remaining data, if any and clear IRQ + // Do no wait forever. + if (dest) { + int32_t timeout = 1000; + while (self->rxlen > 0 && timeout) { + timeout--; + MICROPY_EVENT_POLL_HOOK + } + spi->SPI.INTENCLR.bit.RXC = 1; + } else { + // Wait for the data being shifted out. + while (!spi->SPI.INTFLAG.bit.TXC) { + } + } +} + + +STATIC const mp_machine_spi_p_t machine_spi_p = { + .init = machine_spi_init, + .transfer = machine_spi_transfer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + machine_spi_type, + MP_QSTR_SPI, + MP_TYPE_FLAG_NONE, + make_new, machine_spi_make_new, + print, machine_spi_print, + protocol, &machine_spi_p, + locals_dict, &mp_machine_spi_locals_dict + ); diff --git a/ports/samd/main.c b/ports/samd/main.c index 60b8e57faa44..1f056083a1f9 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -36,6 +36,7 @@ extern uint8_t _sstack, _estack, _sheap, _eheap; extern void adc_deinit_all(void); extern void pin_irq_deinit_all(void); extern void pwm_deinit_all(void); +extern void sercom_deinit_all(void); extern void uart_deinit_all(void); void samd_main(void) { @@ -69,6 +70,7 @@ void samd_main(void) { adc_deinit_all(); pin_irq_deinit_all(); pwm_deinit_all(); + sercom_deinit_all(); uart_deinit_all(); gc_sweep_all(); mp_deinit(); diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 8c3033f891bd..712b520f54fb 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -155,6 +155,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 30de339b4a2d..143e3488f098 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -32,6 +32,7 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_pwm_type; +extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_uart_type; #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index b8cb0f3eb74f..22fed00b2482 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -99,6 +99,7 @@ #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_UASYNCIO (1) #define MICROPY_PY_MACHINE_SOFTI2C (1) +#define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_INIT (0) diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index 0e0d84db6906..2a5a3e042ccf 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -112,7 +112,7 @@ static uint8_t sercom_irq_type[SERCOM_INST_NUM] = {}; // Temporarily commented until the module is added void (*sercom_irq_handler_table[])(int num) = { common_uart_irq_handler, - NULL, // common_spi_irq_handler, + common_spi_irq_handler, NULL // common_i2c_irq_handler }; From 94d27ae28fd4b815b3ace7dd91643aa0d1b620cd Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 18:11:06 +0200 Subject: [PATCH 1819/4290] samd/machine_i2c: Add the machine.I2C class. Using the common API. Tested with SAMD21 and SAMD51 boards. --- ports/samd/Makefile | 2 + ports/samd/machine_i2c.c | 270 ++++++++++++++++++++++++++++++++++++++ ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + ports/samd/mpconfigport.h | 1 + ports/samd/samd_isr.c | 4 +- 6 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 ports/samd/machine_i2c.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index ca0309fa6993..c5d36adda4b7 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -91,6 +91,7 @@ SRC_C = \ clock_config.c \ help.c \ machine_adc.c \ + machine_i2c.c \ machine_led.c \ machine_pin.c \ machine_spi.c \ @@ -143,6 +144,7 @@ endif # List of sources for qstr extraction SRC_QSTR += \ machine_adc.c \ + machine_i2c.c \ machine_led.c \ machine_pin.c \ machine_pwm.c \ diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c new file mode 100644 index 000000000000..4d1b03f7d578 --- /dev/null +++ b/ports/samd/machine_i2c.c @@ -0,0 +1,270 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" +#include "extmod/machine_i2c.h" +#include "modmachine.h" +#include "samd_soc.h" +#include "pin_af.h" +#include "clock_config.h" + +#define DEFAULT_I2C_FREQ (400000) +#define RISETIME_NS (300) +#define I2C_TIMEOUT (100) + +#define IS_BUS_BUSY (i2c->I2CM.STATUS.bit.BUSSTATE == 3) +#define NACK_RECVD (i2c->I2CM.STATUS.bit.RXNACK == 1) +#define IRQ_DATA_SENT (i2c->I2CM.INTFLAG.bit.MB == 1) +#define IRQ_DATA_RECVD (i2c->I2CM.INTFLAG.bit.SB == 1) +#define READ_MODE ((flags & MP_MACHINE_I2C_FLAG_READ) != 0) + +#define PREPARE_ACK i2c->I2CM.CTRLB.bit.ACKACT = 0 +#define PREPARE_NACK i2c->I2CM.CTRLB.bit.ACKACT = 1 +#define SET_STOP_STATE i2c_send_command(i2c, 0x03) + +enum state_t { + state_done = 0, + state_busy, + state_buserr, + state_nack +}; + +typedef struct _machine_i2c_obj_t { + mp_obj_base_t base; + Sercom *instance; + uint8_t id; + uint8_t scl; + uint8_t sda; + uint8_t state; + uint32_t freq; + uint32_t timeout; + size_t len; + uint8_t *buf; +} machine_i2c_obj_t; + +extern Sercom *sercom_instance[]; +extern void *sercom_table[SERCOM_INST_NUM]; + +STATIC void i2c_send_command(Sercom *i2c, uint8_t command) { + i2c->I2CM.CTRLB.bit.CMD = command; + while (i2c->I2CM.SYNCBUSY.bit.SYSOP) { + } +} + +void common_i2c_irq_handler(int i2c_id) { + // handle Sercom I2C IRQ + machine_i2c_obj_t *self = sercom_table[i2c_id]; + // Handle IRQ + if (self != NULL) { + Sercom *i2c = self->instance; + // For now, clear all interrupts + if (IRQ_DATA_RECVD) { + if (self->len > 0) { + *(self->buf)++ = i2c->I2CM.DATA.reg; + self->len--; + self->timeout = I2C_TIMEOUT; + } + if (self->len > 0) { // no ACK at the last byte + PREPARE_ACK; // Send ACK + i2c_send_command(i2c, 0x02); + } else { + PREPARE_NACK; // Send NACK after the last byte + self->state = state_done; + i2c->I2CM.INTFLAG.reg |= SERCOM_I2CM_INTFLAG_SB; + } + } else if (IRQ_DATA_SENT) { + if (NACK_RECVD) { // e.g. NACK after adress for both read and write. + self->state = state_nack; // force stop of transmission + i2c->I2CM.INTFLAG.reg |= SERCOM_I2CM_INTFLAG_MB; + } else if (self->len > 0) { // data to be sent + i2c->I2CM.DATA.bit.DATA = *(self->buf)++; + self->len--; + self->timeout = I2C_TIMEOUT; + } else { // No data left, if there was any. + self->state = state_done; + i2c->I2CM.INTFLAG.reg |= SERCOM_I2CM_INTFLAG_MB; + } + } else { // On any error, e.g. ARBLOST or BUSERROR, stop the transmission + self->len = 0; + self->state = state_buserr; + i2c->I2CM.INTFLAG.reg |= SERCOM_I2CM_INTFLAG_ERROR; + } + } +} + +STATIC void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "I2C(%u, freq=%u, scl=%u, sda=%u)", + self->id, self->freq, self->scl, self->sda); +} + +mp_obj_t machine_i2c_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_freq, ARG_scl, ARG_sda }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_freq, MP_ARG_INT, {.u_int = DEFAULT_I2C_FREQ} }, + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + }; + + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Get I2C bus. + int id = mp_obj_get_int(args[ARG_id].u_obj); + if (id < 0 || id >= SERCOM_INST_NUM) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), id); + } + + // Get the peripheral object. + machine_i2c_obj_t *self = mp_obj_malloc(machine_i2c_obj_t, &machine_hw_i2c_type); + self->id = id; + self->instance = sercom_instance[self->id]; + + // Set SCL/SDA pins. + sercom_pad_config_t scl_pad_config; + self->scl = mp_hal_get_pin_obj(args[ARG_scl].u_obj); + scl_pad_config = get_sercom_config(self->scl, self->id); + + sercom_pad_config_t sda_pad_config; + self->sda = mp_hal_get_pin_obj(args[ARG_sda].u_obj); + sda_pad_config = get_sercom_config(self->sda, self->id); + if (sda_pad_config.pad_nr != 0 || scl_pad_config.pad_nr != 1) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for sda or scl")); + } + sercom_table[self->id] = self; + self->freq = args[ARG_freq].u_int; + + // Configure the Pin mux. + mp_hal_set_pin_mux(self->scl, scl_pad_config.alt_fct); + mp_hal_set_pin_mux(self->sda, sda_pad_config.alt_fct); + + // Set up the clocks + enable_sercom_clock(self->id); + + // Initialise the I2C peripheral + Sercom *i2c = self->instance; + + // Reset the device + i2c->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_SWRST; + while (i2c->I2CM.SYNCBUSY.bit.SWRST == 1) { + } + // Set to master mode, inactivity timeout of 20 SCL cycles and speed. + i2c->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE(0x05) + | SERCOM_I2CM_CTRLA_INACTOUT(3) + | SERCOM_I2CM_CTRLA_SPEED(self->freq > 400000 ? 1 : 0); + + // I2C is driven by the clock of GCLK Generator 2, with it's freq in variable bus_freq + // baud = peripheral_freq / (2 * baudrate) - 5 - (rise_time * peripheral_freq) / 2 + // Just set the minimal configuration for standard and fast mode. + // Set Baud. Assume ~300ns rise time. Maybe set later by a keyword argument. + i2c->I2CM.BAUD.reg = get_apb_freq() / (2 * self->freq) - 5 - (get_apb_freq() / 1000000) * RISETIME_NS / 2000; + + // Enable interrupts + sercom_register_irq(self->id, SERCOM_IRQ_TYPE_SPI); + #if defined(MCU_SAMD21) + NVIC_EnableIRQ(SERCOM0_IRQn + self->id); + #elif defined(MCU_SAMD51) + NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id); // MB interrupt + NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 1); // SB interrupt + NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 3); // ERRROR interrupt + #endif + + // Now enable I2C. + sercom_enable(i2c, 1); + + // Force the bus state to idle + i2c->I2CM.STATUS.bit.BUSSTATE = 1; + + return MP_OBJ_FROM_PTR(self); +} + +STATIC int machine_i2c_transfer_single(mp_obj_base_t *self_in, uint16_t addr, size_t len, uint8_t *buf, unsigned int flags) { + machine_i2c_obj_t *self = (machine_i2c_obj_t *)self_in; + Sercom *i2c = self->instance; + + self->timeout = I2C_TIMEOUT; + self->len = len; + self->buf = buf; + // Wait a while if the bus is busy + while (IS_BUS_BUSY && self->timeout) { + MICROPY_EVENT_POLL_HOOK + if (--self->timeout == 0) { + return -MP_ETIMEDOUT; + } + } + // Enable interrupts and set the state + i2c->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR; + self->state = state_busy; + + // Send the adress, which kicks off the transfer + i2c->I2CM.ADDR.bit.ADDR = (addr << 1) | READ_MODE; + + // Transfer the data + self->timeout = I2C_TIMEOUT; + while (self->state == state_busy && self->timeout) { + self->timeout--; + MICROPY_EVENT_POLL_HOOK + } + i2c->I2CM.INTENCLR.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR; + + // Check the error states after the transfer is stopped + if (self->state == state_nack) { + SET_STOP_STATE; + return self->len == len ? -MP_ENODEV : -MP_EIO; + } else if (self->state == state_buserr) { + SET_STOP_STATE; + return -MP_EIO; + } else if (self->timeout == 0) { + SET_STOP_STATE; + return -MP_ETIMEDOUT; + } + + if (flags & MP_MACHINE_I2C_FLAG_STOP) { + SET_STOP_STATE; + } + + return len; +} + +STATIC const mp_machine_i2c_p_t machine_i2c_p = { + .transfer = mp_machine_i2c_transfer_adaptor, + .transfer_single = machine_i2c_transfer_single, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + machine_hw_i2c_type, + MP_QSTR_I2C, + MP_TYPE_FLAG_NONE, + make_new, machine_i2c_make_new, + print, machine_i2c_print, + protocol, &machine_i2c_p, + locals_dict, &mp_machine_i2c_locals_dict + ); diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 712b520f54fb..acd672fafef3 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -154,6 +154,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 143e3488f098..4319867190cc 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -29,6 +29,7 @@ #include "py/obj.h" extern const mp_obj_type_t machine_adc_type; +extern const mp_obj_type_t machine_hw_i2c_type; extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_pwm_type; diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 22fed00b2482..425ecc59777c 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -98,6 +98,7 @@ #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_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index 2a5a3e042ccf..5cb0668c2516 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -109,11 +109,11 @@ void PendSV_Handler(void) { static uint8_t sercom_irq_type[SERCOM_INST_NUM] = {}; -// Temporarily commented until the module is added + void (*sercom_irq_handler_table[])(int num) = { common_uart_irq_handler, common_spi_irq_handler, - NULL // common_i2c_irq_handler + common_i2c_irq_handler }; void sercom_register_irq(int sercom_id, int mode) { From 15212ae8d423dced7698219def0f2d13287a64b8 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 20:34:37 +0200 Subject: [PATCH 1820/4290] samd/moduos: Add uos.dupterm(). --- ports/samd/Makefile | 2 ++ ports/samd/moduos.c | 57 +++++++++++++++++++++++++++++++++++++++ ports/samd/mpconfigport.h | 2 ++ ports/samd/mphalport.c | 12 +++++++++ 4 files changed, 73 insertions(+) create mode 100644 ports/samd/moduos.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index c5d36adda4b7..f31e5ba6ece4 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -121,6 +121,7 @@ SRC_C = \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ lib/tinyusb/src/tusb.c \ drivers/bus/softspi.c \ + extmod/uos_dupterm.c \ shared/runtime/mpirq.c \ shared/libc/printf.c \ shared/libc/string0.c \ @@ -155,6 +156,7 @@ SRC_QSTR += \ modsamd.c \ samd_flash.c \ shared/readline/readline.c \ + extmod/uos_dupterm.c \ shared/runtime/mpirq.c \ SRC_QSTR += $(SRC_MOD) $(SRC_CXX) diff --git a/ports/samd/moduos.c b/ports/samd/moduos.c new file mode 100644 index 000000000000..b1118f0195b8 --- /dev/null +++ b/ports/samd/moduos.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * use of the TRNG by + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Artur Pacholec + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "modmachine.h" +#include "sam.h" + +#if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM +bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream) { + const mp_obj_type_t *type = mp_obj_get_type(stream); + return type == &machine_uart_type; +} +#endif + +#if MICROPY_PY_UOS_DUPTERM_NOTIFY +STATIC mp_obj_t mp_uos_dupterm_notify(mp_obj_t obj_in) { + (void)obj_in; + for (;;) { + int c = mp_uos_dupterm_rx_chr(); + if (c < 0) { + break; + } + ringbuf_put(&stdin_ringbuf, c); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_dupterm_notify_obj, mp_uos_dupterm_notify); +#endif diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 425ecc59777c..8238c3d2b55e 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -88,6 +88,7 @@ #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_UOS (1) +#define MICROPY_PY_UOS_INCLUDEFILE "ports/samd/moduos.c" #define MICROPY_READER_VFS (1) #define MICROPY_VFS (1) #define MICROPY_PY_UJSON (1) @@ -102,6 +103,7 @@ #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) +#define MICROPY_PY_OS_DUPTERM (3) #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_INIT (0) #define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index 7a3786be8c31..fc451023903c 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -97,6 +97,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { if (tud_cdc_connected() && tud_cdc_available()) { ret |= MP_STREAM_POLL_RD; } + #if MICROPY_PY_OS_DUPTERM + ret |= mp_uos_dupterm_poll(poll_flags); + #endif return ret; } @@ -109,6 +112,12 @@ int mp_hal_stdin_rx_chr(void) { return buf[0]; } } + #if MICROPY_PY_OS_DUPTERM + int dupterm_c = mp_uos_dupterm_rx_chr(); + if (dupterm_c >= 0) { + return dupterm_c; + } + #endif MICROPY_EVENT_POLL_HOOK } } @@ -128,4 +137,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { i += n2; } } + #if MICROPY_PY_OS_DUPTERM + mp_uos_dupterm_tx_strn(str, len); + #endif } From 45bf25a0022033474b9fe699267297f882ca9772 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 21:08:37 +0200 Subject: [PATCH 1821/4290] samd/moduos: Add uos.urandom() for SAMD51. Based on the hardware RNG. --- ports/samd/boards/mpconfig_samd51.h | 3 +++ ports/samd/moduos.c | 40 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/ports/samd/boards/mpconfig_samd51.h b/ports/samd/boards/mpconfig_samd51.h index 1b67b1d02d5c..d963fe1dd295 100644 --- a/ports/samd/boards/mpconfig_samd51.h +++ b/ports/samd/boards/mpconfig_samd51.h @@ -5,6 +5,9 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) +#define MICROPY_PY_UOS_URANDOM (1) +#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) +unsigned long trng_random_u32(void); // Due to a limitation in the TC counter for us, the ticks period is 2**29 #define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) diff --git a/ports/samd/moduos.c b/ports/samd/moduos.c index b1118f0195b8..e0237fd88f0c 100644 --- a/ports/samd/moduos.c +++ b/ports/samd/moduos.c @@ -34,6 +34,46 @@ #include "modmachine.h" #include "sam.h" +#if defined(MCU_SAMD51) +static bool initialized = false; + +STATIC void trng_start(void) { + if (!initialized) { + MCLK->APBCMASK.bit.TRNG_ = 1; + REG_TRNG_CTRLA = TRNG_CTRLA_ENABLE; + initialized = true; + } +} + +uint32_t trng_random_u32(void) { + trng_start(); + while ((REG_TRNG_INTFLAG & TRNG_INTFLAG_DATARDY) == 0) { + } + return REG_TRNG_DATA; +} + +#if MICROPY_PY_UOS_URANDOM +STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { + mp_int_t n = mp_obj_get_int(num); + vstr_t vstr; + vstr_init_len(&vstr, n); + uint32_t rngval = 0; + + trng_start(); + for (int i = 0; i < n; i++) { + if ((i % 4) == 0) { + rngval = trng_random_u32(); + } + vstr.buf[i] = rngval & 0xff; + rngval >>= 8; + } + return mp_obj_new_bytes_from_vstr(&vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); + +#endif // MICROPY_PY_UOS_URANDOM +#endif // defined(MCU_SAMD51) + #if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream) { const mp_obj_type_t *type = mp_obj_get_type(stream); From 4ef2da176f2ca1e7f3cb02488aba61a018033575 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 21:55:30 +0200 Subject: [PATCH 1822/4290] samd/main: Use the common execution mode of boot.py and main.py. Behaviour is: - Do not execute main.py if boot.py failed. - On a forced exit, do a soft reset. --- ports/samd/main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ports/samd/main.c b/ports/samd/main.c index 1f056083a1f9..5aab39e5099d 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -51,8 +51,17 @@ void samd_main(void) { pyexec_frozen_module("_boot.py"); // Execute user scripts. - pyexec_file_if_exists("boot.py"); - pyexec_file_if_exists("main.py"); + int ret = pyexec_file_if_exists("boot.py"); + if (ret & PYEXEC_FORCED_EXIT) { + goto soft_reset_exit; + } + // Do not execute main.py if boot.py failed + if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL && ret != 0) { + ret = pyexec_file_if_exists("main.py"); + if (ret & PYEXEC_FORCED_EXIT) { + goto soft_reset_exit; + } + } for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { @@ -66,6 +75,7 @@ void samd_main(void) { } } + soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); adc_deinit_all(); pin_irq_deinit_all(); From 009c51c13fc13233a28386d5e78ac79cd773cc79 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 5 Jun 2022 22:03:16 +0200 Subject: [PATCH 1823/4290] samd/mpconfigport: Enable a few more MicroPython features. Additional features are: - Support executing .mpy files. - Allow const(). - Enable auto-indent in REPL. - Enable enumerate, min/max, attrtuple, input. --- ports/samd/mpconfigport.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 8238c3d2b55e..c2c614e10b46 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -38,14 +38,20 @@ #define MICROPY_ALLOC_PATH_MAX (256) #define MICROPY_QSTR_BYTES_IN_HASH (1) +// MicroPython emitters +#define MICROPY_PERSISTENT_CODE_LOAD (1) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_INLINE_THUMB (0) + // Compiler configuration -#define MICROPY_COMP_CONST (0) +#define MICROPY_COMP_CONST (1) // Python internal features #define MICROPY_ENABLE_GC (1) #define MICROPY_ENABLE_FINALISER (1) #define MICROPY_KBD_EXCEPTION (1) #define MICROPY_HELPER_REPL (1) +#define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_STREAMS_NON_BLOCK (1) @@ -66,15 +72,16 @@ #define MICROPY_PY_BUILTINS_SET (0) #define MICROPY_PY_BUILTINS_FROZENSET (0) #define MICROPY_PY_BUILTINS_PROPERTY (0) -#define MICROPY_PY_BUILTINS_ENUMERATE (0) +#define MICROPY_PY_BUILTINS_ENUMERATE (1) #define MICROPY_PY_BUILTINS_FILTER (0) #define MICROPY_PY_BUILTINS_REVERSED (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_BUILTINS_MIN_MAX (0) +#define MICROPY_PY_BUILTINS_MIN_MAX (1) +#define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_PY___FILE__ (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) -#define MICROPY_PY_ATTRTUPLE (0) +#define MICROPY_PY_ATTRTUPLE (1) #define MICROPY_PY_COLLECTIONS (0) #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_PLATFORM "samd" From 3625388d8ce028df4bb23077e1a569c987fa91fb Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 6 Jun 2022 10:20:44 +0200 Subject: [PATCH 1824/4290] samd/samd_isr: Change the way a Sercom ISR is registered and called. Code size diff: +12 Bytes BSS diff: -12 Bytes RAM usage: +16 Bytes Speed increase: a few clock cycles per call Style improvement: ++ --- ports/samd/machine_i2c.c | 2 +- ports/samd/machine_spi.c | 2 +- ports/samd/machine_uart.c | 2 +- ports/samd/samd_isr.c | 18 +++++++----------- ports/samd/samd_soc.h | 5 +---- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c index 4d1b03f7d578..90ea5e10ca43 100644 --- a/ports/samd/machine_i2c.c +++ b/ports/samd/machine_i2c.c @@ -188,7 +188,7 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n i2c->I2CM.BAUD.reg = get_apb_freq() / (2 * self->freq) - 5 - (get_apb_freq() / 1000000) * RISETIME_NS / 2000; // Enable interrupts - sercom_register_irq(self->id, SERCOM_IRQ_TYPE_SPI); + sercom_register_irq(self->id, &common_i2c_irq_handler); #if defined(MCU_SAMD21) NVIC_EnableIRQ(SERCOM0_IRQn + self->id); #elif defined(MCU_SAMD51) diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c index b3504aeba32b..ddb8756e9a34 100644 --- a/ports/samd/machine_spi.c +++ b/ports/samd/machine_spi.c @@ -218,7 +218,7 @@ STATIC void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj #elif defined(MCU_SAMD51) NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2); #endif - sercom_register_irq(self->id, SERCOM_IRQ_TYPE_SPI); + sercom_register_irq(self->id, &common_spi_irq_handler); } sercom_enable(spi, 1); diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index 9c5cfce83994..0ed7fb95d0c3 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -281,7 +281,7 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args #elif defined(MCU_SAMD51) NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2); #endif - sercom_register_irq(self->id, SERCOM_IRQ_TYPE_UART); + sercom_register_irq(self->id, &common_uart_irq_handler); sercom_enable(uart, 1); } diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index 5cb0668c2516..ed88ca229dc5 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -108,21 +108,17 @@ void PendSV_Handler(void) { } -static uint8_t sercom_irq_type[SERCOM_INST_NUM] = {}; +void (*sercom_irq_handler_table[SERCOM_INST_NUM])(int num) = {}; -void (*sercom_irq_handler_table[])(int num) = { - common_uart_irq_handler, - common_spi_irq_handler, - common_i2c_irq_handler -}; - -void sercom_register_irq(int sercom_id, int mode) { - sercom_irq_type[sercom_id] = mode; +void sercom_register_irq(int sercom_id, void (*sercom_irq_handler)) { + if (sercom_id < SERCOM_INST_NUM) { + sercom_irq_handler_table[sercom_id] = sercom_irq_handler; + } } static inline void common_sercom_irq_handler(int sercom_id) { - if (sercom_irq_handler_table[sercom_irq_type[sercom_id]]) { - sercom_irq_handler_table[sercom_irq_type[sercom_id]](sercom_id); + if (sercom_irq_handler_table[sercom_id]) { + sercom_irq_handler_table[sercom_id](sercom_id); } } diff --git a/ports/samd/samd_soc.h b/ports/samd/samd_soc.h index b97159dc7fc5..e8560b50e846 100644 --- a/ports/samd/samd_soc.h +++ b/ports/samd/samd_soc.h @@ -39,11 +39,8 @@ void USB_1_Handler_wrapper(void); void USB_2_Handler_wrapper(void); void USB_3_Handler_wrapper(void); -void common_uart_irq_handler(int uart_nr); -void common_spi_irq_handler(int spi_nr); -void common_i2c_irq_handler(int i2c_nr); void sercom_enable(Sercom *spi, int state); -void sercom_register_irq(int sercom_id, int mode); +void sercom_register_irq(int sercom_id, void (*sercom_irq_handler)); #define SERCOM_IRQ_TYPE_UART (0) #define SERCOM_IRQ_TYPE_SPI (1) From 32c973d554a31d919ca582d77f4d524760093d4d Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 6 Jun 2022 11:13:25 +0200 Subject: [PATCH 1825/4290] samd/machine_timer: Add machine.Timer based on the shared soft-timer. --- ports/samd/Makefile | 4 + ports/samd/boards/mpconfig_samd21.h | 11 +++ ports/samd/boards/mpconfig_samd51.h | 20 ++++ ports/samd/machine_timer.c | 146 ++++++++++++++++++++++++++++ ports/samd/main.c | 2 + ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + ports/samd/mphalport.h | 4 + ports/samd/pendsv.c | 71 ++++++++++++++ ports/samd/pendsv.h | 41 ++++++++ ports/samd/samd_isr.c | 18 ++-- 11 files changed, 307 insertions(+), 12 deletions(-) create mode 100644 ports/samd/machine_timer.c create mode 100644 ports/samd/pendsv.c create mode 100644 ports/samd/pendsv.h diff --git a/ports/samd/Makefile b/ports/samd/Makefile index f31e5ba6ece4..e3d0d28f8f18 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -95,12 +95,14 @@ SRC_C = \ machine_led.c \ machine_pin.c \ machine_spi.c \ + machine_timer.c \ machine_uart.c \ main.c \ modutime.c \ modmachine.c \ modsamd.c \ mphalport.c \ + pendsv.c \ pin_af.c \ $(BUILD)/pins.c \ samd_flash.c \ @@ -128,6 +130,7 @@ SRC_C = \ shared/readline/readline.c \ shared/runtime/gchelper_native.c \ shared/runtime/pyexec.c \ + shared/runtime/softtimer.c \ shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ @@ -150,6 +153,7 @@ SRC_QSTR += \ machine_pin.c \ machine_pwm.c \ machine_spi.c \ + machine_timer.c \ machine_uart.c \ modutime.c \ modmachine.c \ diff --git a/ports/samd/boards/mpconfig_samd21.h b/ports/samd/boards/mpconfig_samd21.h index 1924f66f0604..587f3f4b3ad6 100644 --- a/ports/samd/boards/mpconfig_samd21.h +++ b/ports/samd/boards/mpconfig_samd21.h @@ -7,3 +7,14 @@ #define CPU_FREQ (48000000) #define APB_FREQ (48000000) + +#define IRQ_PRI_PENDSV ((1 << __NVIC_PRIO_BITS) - 1) + +static inline uint32_t raise_irq_pri(uint32_t pri) { + (void)pri; + return 0; +} + +static inline void restore_irq_pri(uint32_t basepri) { + (void)basepri; +} diff --git a/ports/samd/boards/mpconfig_samd51.h b/ports/samd/boards/mpconfig_samd51.h index d963fe1dd295..95fc635e5e32 100644 --- a/ports/samd/boards/mpconfig_samd51.h +++ b/ports/samd/boards/mpconfig_samd51.h @@ -22,3 +22,23 @@ unsigned long trng_random_u32(void); #define CPU_FREQ (120000000) #define APB_FREQ (48000000) #define DPLLx_REF_FREQ (32768) + +#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) +#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) + +static inline uint32_t raise_irq_pri(uint32_t pri) { + uint32_t basepri = __get_BASEPRI(); + // If non-zero, the processor does not process any exception with a + // priority value greater than or equal to BASEPRI. + // When writing to BASEPRI_MAX the write goes to BASEPRI only if either: + // - Rn is non-zero and the current BASEPRI value is 0 + // - Rn is non-zero and less than the current BASEPRI value + pri <<= (8 - __NVIC_PRIO_BITS); + __ASM volatile ("msr basepri_max, %0" : : "r" (pri) : "memory"); + return basepri; +} + +// "basepri" should be the value returned from raise_irq_pri +static inline void restore_irq_pri(uint32_t basepri) { + __set_BASEPRI(basepri); +} diff --git a/ports/samd/machine_timer.c b/ports/samd/machine_timer.c new file mode 100644 index 000000000000..640d1d200fa5 --- /dev/null +++ b/ports/samd/machine_timer.c @@ -0,0 +1,146 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared/runtime/softtimer.h" + +typedef soft_timer_entry_t machine_timer_obj_t; + +const mp_obj_type_t machine_timer_type; + +STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_timer_obj_t *self = MP_OBJ_TO_PTR(self_in); + qstr mode = self->mode == SOFT_TIMER_MODE_ONE_SHOT ? MP_QSTR_ONE_SHOT : MP_QSTR_PERIODIC; + mp_printf(print, "Timer(mode=%q, period=%u)", mode, self->delta_ms); +} + +STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_callback, ARG_period, ARG_tick_hz, ARG_freq, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SOFT_TIMER_MODE_PERIODIC} }, + { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} }, + { MP_QSTR_tick_hz, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, + { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + }; + + // Parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + self->mode = args[ARG_mode].u_int; + + uint64_t delta_ms = self->delta_ms; + if (args[ARG_freq].u_obj != mp_const_none) { + // Frequency specified in Hz + #if MICROPY_PY_BUILTINS_FLOAT + delta_ms = (uint32_t)(MICROPY_FLOAT_CONST(1000.0) / mp_obj_get_float(args[ARG_freq].u_obj)); + #else + delta_ms = 1000 / mp_obj_get_int(args[ARG_freq].u_obj); + #endif + } else if (args[ARG_period].u_int != 0xffffffff) { + // Period specified + delta_ms = (uint64_t)args[ARG_period].u_int * 1000 / args[ARG_tick_hz].u_int; + } + + if (delta_ms < 1) { + delta_ms = 1; + } else if (delta_ms >= 0x40000000) { + mp_raise_ValueError(MP_ERROR_TEXT("period too large")); + } + self->delta_ms = (uint32_t)delta_ms; + + if (args[ARG_callback].u_obj != MP_OBJ_NULL) { + self->py_callback = args[ARG_callback].u_obj; + } + + if (self->py_callback != mp_const_none) { + soft_timer_insert(self, self->delta_ms); + } + + return mp_const_none; +} + +STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t); + self->pairheap.base.type = &machine_timer_type; + self->flags = SOFT_TIMER_FLAG_PY_CALLBACK | SOFT_TIMER_FLAG_GC_ALLOCATED; + self->delta_ms = 1000; + self->py_callback = mp_const_none; + + // Get timer id (only soft timer (-1) supported at the moment) + mp_int_t id = -1; + if (n_args > 0) { + id = mp_obj_get_int(args[0]); + --n_args; + ++args; + } + if (id != -1) { + mp_raise_ValueError(MP_ERROR_TEXT("Timer doesn't exist")); + } + + if (n_args > 0 || n_kw > 0) { + // Start the timer + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_timer_init_helper(self, n_args, args, &kw_args); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t machine_timer_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + machine_timer_obj_t *self = MP_OBJ_TO_PTR(args[0]); + soft_timer_remove(self); + return machine_timer_init_helper(self, n_args - 1, args + 1, kw_args); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_timer_init_obj, 1, machine_timer_init); + +STATIC mp_obj_t machine_timer_deinit(mp_obj_t self_in) { + machine_timer_obj_t *self = MP_OBJ_TO_PTR(self_in); + soft_timer_remove(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_timer_deinit_obj, machine_timer_deinit); + +STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_timer_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_timer_deinit_obj) }, + + { MP_ROM_QSTR(MP_QSTR_ONE_SHOT), MP_ROM_INT(SOFT_TIMER_MODE_ONE_SHOT) }, + { MP_ROM_QSTR(MP_QSTR_PERIODIC), MP_ROM_INT(SOFT_TIMER_MODE_PERIODIC) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_timer_type, + MP_QSTR_Timer, + MP_TYPE_FLAG_NONE, + make_new, machine_timer_make_new, + print, machine_timer_print, + locals_dict, &machine_timer_locals_dict + ); diff --git a/ports/samd/main.c b/ports/samd/main.c index 5aab39e5099d..889af4a1e473 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -31,6 +31,7 @@ #include "py/stackctrl.h" #include "shared/runtime/gchelper.h" #include "shared/runtime/pyexec.h" +#include "shared/runtime/softtimer.h" extern uint8_t _sstack, _estack, _sheap, _eheap; extern void adc_deinit_all(void); @@ -82,6 +83,7 @@ void samd_main(void) { pwm_deinit_all(); sercom_deinit_all(); uart_deinit_all(); + soft_timer_deinit(); gc_sweep_all(); mp_deinit(); } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index acd672fafef3..852d10912d7c 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -157,6 +157,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 4319867190cc..b6da5e46f5ad 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -34,6 +34,7 @@ extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_spi_type; +extern const mp_obj_type_t machine_timer_type; extern const mp_obj_type_t machine_uart_type; #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index 6161d9821ff9..2eb4ce7ca680 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -40,6 +40,10 @@ extern volatile uint32_t systick_ms_upper; void mp_hal_set_interrupt_char(int c); +// Define an alias fo systick_ms, because the shared softtimer.c uses +// the symbol uwTick for the systick ms counter. +#define uwTick systick_ms + #define mp_hal_delay_us_fast mp_hal_delay_us static inline mp_uint_t mp_hal_ticks_ms(void) { diff --git a/ports/samd/pendsv.c b/ports/samd/pendsv.c new file mode 100644 index 000000000000..00dd6068d1e1 --- /dev/null +++ b/ports/samd/pendsv.c @@ -0,0 +1,71 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "sam.h" +#include "pendsv.h" + + +#if defined(PENDSV_DISPATCH_NUM_SLOTS) +uint32_t pendsv_dispatch_active; +pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS]; +#endif + +void pendsv_init(void) { + #if defined(PENDSV_DISPATCH_NUM_SLOTS) + pendsv_dispatch_active = false; + #endif + + // set PendSV interrupt at lowest priority + NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV); +} + +#if defined(PENDSV_DISPATCH_NUM_SLOTS) +void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) { + pendsv_dispatch_table[slot] = f; + pendsv_dispatch_active = true; + SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; +} + +void pendsv_dispatch_handler(void) { + for (size_t i = 0; i < PENDSV_DISPATCH_NUM_SLOTS; ++i) { + if (pendsv_dispatch_table[i] != NULL) { + pendsv_dispatch_t f = pendsv_dispatch_table[i]; + pendsv_dispatch_table[i] = NULL; + f(); + } + } +} + +void PendSV_Handler(void) { + if (pendsv_dispatch_active) { + pendsv_dispatch_handler(); + } +} +#endif diff --git a/ports/samd/pendsv.h b/ports/samd/pendsv.h new file mode 100644 index 000000000000..c21af906b438 --- /dev/null +++ b/ports/samd/pendsv.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_SAMD_PENDSV_H +#define MICROPY_INCLUDED_SAMD_PENDSV_H + +enum { + PENDSV_DISPATCH_SOFT_TIMER, // For later & for having at least one entry + PENDSV_DISPATCH_MAX +}; + +#define PENDSV_DISPATCH_NUM_SLOTS PENDSV_DISPATCH_MAX + +typedef void (*pendsv_dispatch_t)(void); + +void pendsv_init(void); +void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f); + +#endif // MICROPY_INCLUDED_SAMD_PENDSV_H diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index ed88ca229dc5..b507d5d1aa73 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -27,9 +27,9 @@ #include "py/runtime.h" #include "py/mphal.h" #include "samd_soc.h" -// includes for Softtimer -// #include "pendsv.h" -// #include "softtimer.h" + +#include "pendsv.h" +#include "shared/runtime/softtimer.h" typedef void (*ISR)(void); @@ -97,17 +97,11 @@ void SysTick_Handler(void) { systick_ms_upper += 1; } - // if (soft_timer_next == next_tick) { - // pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler); - // } -} - -// Temporary Handlers to allow builds. -// Will be removed when the respecitve module is added. -void PendSV_Handler(void) { + if (soft_timer_next == next_tick) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler); + } } - void (*sercom_irq_handler_table[SERCOM_INST_NUM])(int num) = {}; void sercom_register_irq(int sercom_id, void (*sercom_irq_handler)) { From 7a2f2d88f74dcad73acd1f4f7721a3575f68ffc2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 6 Jun 2022 11:23:09 +0200 Subject: [PATCH 1826/4290] samd/machine_wdt: Add the machine.WDT class. --- ports/samd/Makefile | 2 + ports/samd/machine_wdt.c | 141 +++++++++++++++++++++++++++++++++++++++ ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + 4 files changed, 145 insertions(+) create mode 100644 ports/samd/machine_wdt.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index e3d0d28f8f18..71a902a0a535 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -97,6 +97,7 @@ SRC_C = \ machine_spi.c \ machine_timer.c \ machine_uart.c \ + machine_wdt.c \ main.c \ modutime.c \ modmachine.c \ @@ -155,6 +156,7 @@ SRC_QSTR += \ machine_spi.c \ machine_timer.c \ machine_uart.c \ + machine_wdt.c \ modutime.c \ modmachine.c \ modsamd.c \ diff --git a/ports/samd/machine_wdt.c b/ports/samd/machine_wdt.c new file mode 100644 index 000000000000..c0fbfdbfbc7d --- /dev/null +++ b/ports/samd/machine_wdt.c @@ -0,0 +1,141 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "modmachine.h" + +#include "sam.h" + +#define MIN_TIMEOUT 512 +#define MAX_TIMEOUT 16384 + +typedef struct _machine_wdt_obj_t { + mp_obj_base_t base; +} machine_wdt_obj_t; + +extern mp_int_t log2i(mp_int_t num); + +STATIC const machine_wdt_obj_t machine_wdt = {{&machine_wdt_type}}; + +STATIC void set_timeout(uint32_t timeout) { + // Set new timeout. Have to disable WDT first. + + // Confine to the valid range + if (timeout < MIN_TIMEOUT) { + timeout = MIN_TIMEOUT; + } else if (timeout > MAX_TIMEOUT) { + timeout = MAX_TIMEOUT; + } + + #if defined(MCU_SAMD21) + WDT->CTRL.reg = 0; + while (WDT->STATUS.reg & WDT_STATUS_SYNCBUSY) { + } + WDT->CONFIG.reg = log2i(timeout) - 3; + WDT->CTRL.reg = WDT_CTRL_ENABLE; + while (WDT->STATUS.reg & WDT_STATUS_SYNCBUSY) { + } + #elif defined(MCU_SAMD51) + WDT->CTRLA.reg = 0; + while (WDT->SYNCBUSY.reg & WDT_SYNCBUSY_ENABLE) { + } + WDT->CONFIG.reg = log2i(timeout) - 3; + WDT->CTRLA.reg = WDT_CTRLA_ENABLE; + while (WDT->SYNCBUSY.reg & WDT_SYNCBUSY_ENABLE) { + } + #endif +} + +STATIC mp_obj_t machine_wdt_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_timeout, ARG_lock }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} }, + }; + + // Parse the arguments. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + #if defined(MCU_SAMD51) + // Verify the WDT id. SAMD51 only, saving a few bytes for SAMD21 + mp_int_t id = args[ARG_id].u_int; + if (id != 0) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("WDT(%d) doesn't exist"), id); + } + #endif + + // Start the watchdog (timeout is in milliseconds). + uint32_t timeout = args[ARG_timeout].u_int; + // Configure the WDT + #if defined(MCU_SAMD21) + + // Enable APBx clocks and GCLK clock + PM->APBAMASK.reg |= PM_APBAMASK_WDT; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK8 | GCLK_CLKCTRL_ID_WDT; + + #elif defined(MCU_SAMD51) + + // Enable APBx clocks and 1kHz clock + MCLK->APBAMASK.reg |= MCLK_APBAMASK_WDT; + OSC32KCTRL->OSCULP32K.bit.EN1K = 1; + + #endif + + set_timeout(timeout); + + return MP_OBJ_FROM_PTR(&machine_wdt); +} + +STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) { + (void)self_in; + WDT->CLEAR.reg = 0xa5; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed); + +STATIC mp_obj_t machine_wdt_timeout_ms(mp_obj_t self_in, mp_obj_t timout_in) { + uint32_t timeout = mp_obj_get_int(timout_in); + + set_timeout(timeout); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_wdt_timeout_ms_obj, machine_wdt_timeout_ms); + +STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&machine_wdt_feed_obj) }, + { MP_ROM_QSTR(MP_QSTR_timeout_ms), MP_ROM_PTR(&machine_wdt_timeout_ms_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_wdt_type, + MP_QSTR_WDT, + MP_TYPE_FLAG_NONE, + make_new, machine_wdt_make_new, + locals_dict, &machine_wdt_locals_dict + ); diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 852d10912d7c..cabd6b9c5782 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -159,6 +159,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, + { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) }, { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index b6da5e46f5ad..61b26a1fa302 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -36,5 +36,6 @@ extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_timer_type; extern const mp_obj_type_t machine_uart_type; +extern const mp_obj_type_t machine_wdt_type; #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H From 6e2dff6baea2a6109fa030a97d2ffdcafd6c3681 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 6 Jun 2022 12:26:13 +0200 Subject: [PATCH 1827/4290] samd/modsamd: Add pininfo() function to the samd module. samd.pininfo() returns the data stored in the pin af table for a pin. Using a small script, a nice representation of the table can be created. --- ports/samd/machine_pin.c | 2 -- ports/samd/modsamd.c | 44 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index a70e9ad0115d..bef19d177d9a 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -92,7 +92,6 @@ int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_ return wanted_pin; } - // Pin.init(mode, pull=None, *, value=None, drive=0). No 'alt' yet. STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt }; @@ -157,7 +156,6 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, if (self == NULL || self->base.type == NULL) { mp_raise_ValueError(MP_ERROR_TEXT("invalid pin")); } - self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin]; if (n_args > 1 || n_kw > 0) { // pin mode given, so configure this GPIO diff --git a/ports/samd/modsamd.c b/ports/samd/modsamd.c index 68fd6b53e56d..05ed69bad014 100644 --- a/ports/samd/modsamd.c +++ b/ports/samd/modsamd.c @@ -24,14 +24,56 @@ * THE SOFTWARE. */ +#include "string.h" #include "py/runtime.h" +#include "py/mphal.h" + +#include "sam.h" +#include "pin_af.h" +#include "pins.h" #include "samd_soc.h" extern const mp_obj_type_t samd_flash_type; +STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) { + mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_obj); + const pin_af_t *pin_af = get_pin_af_info(pin); + const char *name = ((machine_pin_obj_t *)MP_OBJ_TO_PTR(pin_obj))->name; + if (pin_af) { + #if defined(MCU_SAMD21) + mp_obj_t tuple[7] = { + tuple[0] = mp_obj_new_str(name, strlen(name)), + tuple[1] = mp_obj_new_int(pin_af->eic), + tuple[2] = mp_obj_new_int(pin_af->adc0), + tuple[3] = mp_obj_new_int(pin_af->sercom1), + tuple[4] = mp_obj_new_int(pin_af->sercom2), + tuple[5] = mp_obj_new_int(pin_af->tcc1), + tuple[6] = mp_obj_new_int(pin_af->tcc2), + }; + return mp_obj_new_tuple(7, tuple); + #elif defined(MCU_SAMD51) + mp_obj_t tuple[9] = { + tuple[0] = mp_obj_new_str(name, strlen(name)), + tuple[1] = mp_obj_new_int(pin_af->eic), + tuple[2] = mp_obj_new_int(pin_af->adc0), + tuple[3] = mp_obj_new_int(pin_af->adc1), + tuple[4] = mp_obj_new_int(pin_af->sercom1), + tuple[5] = mp_obj_new_int(pin_af->sercom2), + tuple[6] = mp_obj_new_int(pin_af->tc), + tuple[7] = mp_obj_new_int(pin_af->tcc1), + tuple[8] = mp_obj_new_int(pin_af->tcc2), + }; + return mp_obj_new_tuple(9, tuple); + #endif + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(samd_pininfo_obj, samd_pininfo); + STATIC const mp_rom_map_elem_t samd_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_samd) }, - { MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&samd_flash_type) }, + { MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&samd_flash_type) }, + { MP_ROM_QSTR(MP_QSTR_pininfo), MP_ROM_PTR(&samd_pininfo_obj) }, }; STATIC MP_DEFINE_CONST_DICT(samd_module_globals, samd_module_globals_table); From aa2d746ef4ef64cbf8093b22facabca2c495be1f Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 6 Jun 2022 13:35:16 +0200 Subject: [PATCH 1828/4290] samd/machine_led: Optimise size of the machine.LED class. By reducing the methods to on(), off(), toggle() and call, and using the method implementation of the machine.Pin class. The code size reduction is 756 byte. --- ports/samd/machine_led.c | 108 ++++----------------------------------- ports/samd/machine_pin.c | 6 +-- 2 files changed, 13 insertions(+), 101 deletions(-) diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index 9c157695818a..48ab869199ad 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -32,37 +32,16 @@ #include "modmachine.h" #include "pins.h" -// ASF4 (MCU package specific pin defs in 'boards') -#include "hal_gpio.h" +extern mp_obj_t machine_pin_low_obj; +extern mp_obj_t machine_pin_high_obj; +extern mp_obj_t machine_pin_toggle_obj; +extern mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_led_obj_t *self = self_in; mp_printf(print, "LED(%u)", self->id); } -// LED.init(mode, *, value=None) -STATIC mp_obj_t machine_led_obj_init_helper(const machine_led_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_mode, ARG_value }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // set initial value (do this before configuring mode/pull) - if (args[ARG_value].u_obj != mp_const_none) { - gpio_set_pin_level(self->id, mp_obj_is_true(args[ARG_value].u_obj)); - } - - // configure mode - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - - return mp_const_none; -} - // constructor(id, ...) mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); @@ -73,90 +52,23 @@ mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, if (0 <= wanted_led && wanted_led < MP_ARRAY_SIZE(machine_led_obj)) { self = (machine_led_obj_t *)&machine_led_obj[wanted_led]; } - // the array could be padded with 'nulls' (see other Ports). // Will also error if the asked for LED (index) is greater than the array row size. if (self == NULL || self->base.type == NULL) { mp_raise_ValueError(MP_ERROR_TEXT("invalid LED")); } - - if (n_args > 1 || n_kw > 0) { - // mode given, so configure this GPIO - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_led_obj_init_helper(self, n_args - 1, args + 1, &kw_args); - } + mp_hal_pin_output(self->id); + mp_hal_pin_low(self->id); return MP_OBJ_FROM_PTR(self); } -// fast method for getting/setting pin value -STATIC mp_obj_t machine_led_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); - machine_led_obj_t *self = self_in; - if (n_args == 0) { - // get pin - return MP_OBJ_NEW_SMALL_INT(gpio_get_pin_level(self->id)); - } else { - // set pin - bool value = mp_obj_is_true(args[0]); - gpio_set_pin_level(self->id, value); - - return mp_const_none; - } -} - -// pin.init(mode) -STATIC mp_obj_t machine_led_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - return machine_led_obj_init_helper(args[0], n_args - 1, args + 1, kw_args); -} -MP_DEFINE_CONST_FUN_OBJ_KW(machine_led_init_obj, 1, machine_led_obj_init); - -// pin.value([value]) -STATIC mp_obj_t machine_led_value(size_t n_args, const mp_obj_t *args) { - return machine_led_call(args[0], n_args - 1, 0, args + 1); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_led_value_obj, 1, 2, machine_led_value); - -// pin.low() -STATIC mp_obj_t machine_led_low(mp_obj_t self_in) { - machine_led_obj_t *self = MP_OBJ_TO_PTR(self_in); - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - gpio_set_pin_level(self->id, false); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_led_low_obj, machine_led_low); - -// pin.high() -STATIC mp_obj_t machine_led_high(mp_obj_t self_in) { - machine_led_obj_t *self = MP_OBJ_TO_PTR(self_in); - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - gpio_set_pin_level(self->id, true); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_led_high_obj, machine_led_high); - -// pin.toggle() -STATIC mp_obj_t machine_led_toggle(mp_obj_t self_in) { - machine_led_obj_t *self = MP_OBJ_TO_PTR(self_in); - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OUT); - gpio_toggle_pin_level(self->id); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_led_toggle_obj, machine_led_toggle); STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = { // instance methods - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_led_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_led_value_obj) }, - { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_led_low_obj) }, - { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_led_high_obj) }, - { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_led_low_obj) }, - { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_led_high_obj) }, - { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_led_toggle_obj) }, + { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) }, + { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_high_obj) }, + { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) }, }; STATIC MP_DEFINE_CONST_DICT(machine_led_locals_dict, machine_led_locals_dict_table); @@ -166,6 +78,6 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_TYPE_FLAG_NONE, make_new, mp_led_make_new, print, machine_led_print, - call, machine_led_call, + call, machine_pin_call, locals_dict, &machine_led_locals_dict ); diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index bef19d177d9a..e900174a9150 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -220,7 +220,7 @@ STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) { } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low); +MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low); // Pin.high() Totem-pole (push-pull) STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) { @@ -232,7 +232,7 @@ STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) { } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high); +MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high); // Pin.toggle(). Only TOGGLE pins set as OUTPUT. STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { @@ -254,7 +254,7 @@ STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle); +MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle); // Pin.drive(). Normal (0) is 2mA, High (1) allows 8mA. STATIC mp_obj_t machine_pin_drive(size_t n_args, const mp_obj_t *args) { From f5da77b5ce66a393984fe8f71627f93e95c39edc Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 7 Jun 2022 20:37:44 +0200 Subject: [PATCH 1829/4290] samd/machine_dac: Add the machine.DAC class. It suuports 1 channel @ 10 bit for SAMD21, 2 channels @ 12 bit for SAMD51. Instantiation by: dac = machine.DAC(ch) # 0 or 1 Method write: dac.write(value) The output voltage range is 0..Vdd. --- ports/samd/Makefile | 2 + ports/samd/machine_dac.c | 162 +++++++++++++++++++++++++++++++++++++++ ports/samd/modmachine.c | 1 + ports/samd/modmachine.h | 1 + ports/samd/pin_af.h | 1 + 5 files changed, 167 insertions(+) create mode 100644 ports/samd/machine_dac.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 71a902a0a535..43b6a1adc3f2 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -91,6 +91,7 @@ SRC_C = \ clock_config.c \ help.c \ machine_adc.c \ + machine_dac.c \ machine_i2c.c \ machine_led.c \ machine_pin.c \ @@ -149,6 +150,7 @@ endif # List of sources for qstr extraction SRC_QSTR += \ machine_adc.c \ + machine_dac.c \ machine_i2c.c \ machine_led.c \ machine_pin.c \ diff --git a/ports/samd/machine_dac.c b/ports/samd/machine_dac.c new file mode 100644 index 000000000000..41c6784cceb8 --- /dev/null +++ b/ports/samd/machine_dac.c @@ -0,0 +1,162 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Nick Moore + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "sam.h" +#include "pin_af.h" +#include "modmachine.h" + +typedef struct _dac_obj_t { + mp_obj_base_t base; + uint8_t id; + mp_hal_pin_obj_t gpio_id; +} dac_obj_t; + +STATIC const dac_obj_t dac_obj[] = { + #if defined(MCU_SAMD21) + {{&machine_dac_type}, 0, PIN_PA02}, + #elif defined(MCU_SAMD51) + {{&machine_dac_type}, 0, PIN_PA02}, + {{&machine_dac_type}, 1, PIN_PA05}, + #endif +}; +Dac *const dac_bases[] = DAC_INSTS; + +#if defined(MCU_SAMD21) +#define MAX_DAC_VALUE (1023) +#elif defined(MCU_SAMD51) +#define MAX_DAC_VALUE (4095) +static bool dac_init = false; +#endif + + +STATIC mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, + const mp_obj_t *args) { + + mp_arg_check_num(n_args, n_kw, 1, 1, true); + uint8_t id = mp_obj_get_int(args[0]); + const dac_obj_t *self = NULL; + if (0 <= id && id <= MP_ARRAY_SIZE(dac_obj)) { + self = &dac_obj[id]; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("invalid Pin for DAC")); + } + + Dac *dac = dac_bases[0]; // Just one DAC + + // Init DAC + #if defined(MCU_SAMD21) + + // Configuration SAMD21 + // Enable APBC clocks and PCHCTRL clocks; GCLK3 at 1 MHz + PM->APBCMASK.reg |= PM_APBCMASK_DAC; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID_DAC; + while (GCLK->STATUS.bit.SYNCBUSY) { + } + // Reset DAC registers + dac->CTRLA.bit.SWRST = 1; + while (dac->CTRLA.bit.SWRST) { + } + dac->CTRLB.reg = DAC_CTRLB_EOEN | DAC_CTRLB_REFSEL(DAC_CTRLB_REFSEL_AVCC_Val); + // Enable DAC and wait to be ready + dac->CTRLA.bit.ENABLE = 1; + while (dac->STATUS.bit.SYNCBUSY) { + } + + #elif defined(MCU_SAMD51) + + // Configuration SAMD51 + // Enable APBD clocks and PCHCTRL clocks; GCLK3 at 8 MHz + if (!dac_init) { + dac_init = true; + MCLK->APBDMASK.reg |= MCLK_APBDMASK_DAC; + GCLK->PCHCTRL[DAC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK3 | GCLK_PCHCTRL_CHEN; + + // Reset DAC registers + dac->CTRLA.bit.SWRST = 1; + while (dac->CTRLA.bit.SWRST) { + } + dac->CTRLB.reg = DAC_CTRLB_REFSEL(DAC_CTRLB_REFSEL_VDDANA_Val); + } else { + dac->CTRLA.bit.ENABLE = 0; + while (dac->SYNCBUSY.bit.ENABLE) { + } + } + dac->DACCTRL[self->id].reg = DAC_DACCTRL_ENABLE | DAC_DACCTRL_REFRESH(2) | DAC_DACCTRL_CCTRL_CC12M; + + // Enable DAC and wait to be ready + dac->CTRLA.bit.ENABLE = 1; + while (dac->SYNCBUSY.bit.ENABLE) { + } + #endif + + // Set the port as given in self->gpio_id as DAC + mp_hal_set_pin_mux(self->gpio_id, ALT_FCT_DAC); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void dac_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + dac_obj_t *self = self_in; + mp_printf(print, "DAC(%u) PIN_PA%02u", self->id, self->gpio_id); +} + +STATIC mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) { + Dac *dac = dac_bases[0]; // Just one DAC + int value = mp_obj_get_int(value_in); + if (value < 0 || value > MAX_DAC_VALUE) { + mp_raise_ValueError(MP_ERROR_TEXT("value out of range")); + } + #if defined(MCU_SAMD21) + dac->DATA.reg = value; + #elif defined(MCU_SAMD51) + dac_obj_t *self = self_in; + dac->DATA[self->id].reg = value; + #endif + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(dac_write_obj, dac_write); + +STATIC const mp_rom_map_elem_t dac_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&dac_write_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(dac_locals_dict, dac_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_dac_type, + MP_QSTR_DAC, + MP_TYPE_FLAG_NONE, + make_new, dac_make_new, + print, dac_print, + locals_dict, &dac_locals_dict + ); diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index cabd6b9c5782..f7ad47b3c529 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -150,6 +150,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) }, { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 61b26a1fa302..6a745da0675a 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -29,6 +29,7 @@ #include "py/obj.h" extern const mp_obj_type_t machine_adc_type; +extern const mp_obj_type_t machine_dac_type; extern const mp_obj_type_t machine_hw_i2c_type; extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; diff --git a/ports/samd/pin_af.h b/ports/samd/pin_af.h index f9dec6b7da05..b75f4ddd0256 100644 --- a/ports/samd/pin_af.h +++ b/ports/samd/pin_af.h @@ -81,6 +81,7 @@ typedef struct _pwm_config_t { #define ALT_FCT_EIC 0 #define ALT_FCT_ADC 1 +#define ALT_FCT_DAC 1 #define ALT_FCT_SERCOM1 2 #define ALT_FCT_SERCOM2 3 From 029e9af4576f3000aabf5e6eac589f6bb644af92 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 7 Jun 2022 21:52:03 +0200 Subject: [PATCH 1830/4290] samd/modmachine: Add machine.time_pulse_us. Software based. Resolution: - +/-2 microseconds on SAMD51. - +/-4 microseconds on SAMD21. --- ports/samd/modmachine.c | 6 ++++-- ports/samd/mpconfigport.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index f7ad47b3c529..c191afda7910 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -26,10 +26,11 @@ #include "py/runtime.h" #include "extmod/machine_mem.h" -#include "samd_soc.h" -#include "modmachine.h" +#include "extmod/machine_pulse.h" #include "extmod/machine_i2c.h" #include "extmod/machine_spi.h" +#include "modmachine.h" +#include "samd_soc.h" // ASF 4 #include "hal_flash.h" @@ -165,6 +166,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, { 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_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index c2c614e10b46..48631080d27f 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -111,6 +111,7 @@ #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_OS_DUPTERM (3) +#define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_INIT (0) #define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) From aa6dbbcffd4f0a5c7572b8aa1ef256794838f969 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 8 Jun 2022 10:54:02 +0200 Subject: [PATCH 1831/4290] samd/mcu: Factor out MCU policy for SAMD21 and SAMD51. Which contains a mpconfigmcu.h, mpconfigmcu.mk and manifest.py file for each MCU group. That looks better than the previous choice. --- ports/samd/Makefile | 16 +++++----------- .../samd21/mpconfigmcu.h} | 0 ports/samd/mcu/samd21/mpconfigmcu.mk | 1 + .../samd51/mpconfigmcu.h} | 0 ports/samd/mcu/samd51/mpconfigmcu.mk | 1 + ports/samd/mpconfigport.h | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) rename ports/samd/{boards/mpconfig_samd21.h => mcu/samd21/mpconfigmcu.h} (100%) create mode 100644 ports/samd/mcu/samd21/mpconfigmcu.mk rename ports/samd/{boards/mpconfig_samd51.h => mcu/samd51/mpconfigmcu.h} (100%) create mode 100644 ports/samd/mcu/samd51/mpconfigmcu.mk diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 43b6a1adc3f2..1455e748cc3a 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -9,14 +9,15 @@ ifeq ($(wildcard $(BOARD_DIR)/.),) $(error Invalid BOARD specified: $(BOARD_DIR)) endif +MCU_SERIES_LOWER = $(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]') + include ../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk +include mcu/$(MCU_SERIES_LOWER)/mpconfigmcu.mk # Qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h -QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h - -MCU_SERIES_LOWER = $(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]') +QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h mcu/$(MCU_SERIES_LOWER)/mpconfigmcu.h FROZEN_MANIFEST ?= boards/manifest.py @@ -30,6 +31,7 @@ INC += -I. INC += -I$(TOP) INC += -I$(BUILD) INC += -I$(BOARD_DIR) +INC += -Imcu/$(MCU_SERIES_LOWER) INC += -I$(TOP)/lib/cmsis/inc INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hal/include INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hal/utils/include @@ -62,8 +64,6 @@ CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += -DMPCONFIG_MCU_H='' CFLAGS += -DPIN_AF_TABLE_C='<$(BUILD)/$(GEN_PIN_AF)>' -QSTR_GLOBAL_DEPENDENCIES += boards/mpconfig_$(MCU_SERIES_LOWER).h - LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref LDFLAGS += $(LDFLAGS_MOD) @@ -141,12 +141,6 @@ SRC_C += $(SRC_MOD) SRC_CXX += $(SRC_MOD_CXX) -ifeq ($(MCU_SERIES),SAMD21) -SRC_S = shared/runtime/gchelper_m0.s -else -SRC_S = shared/runtime/gchelper_m3.s -endif - # List of sources for qstr extraction SRC_QSTR += \ machine_adc.c \ diff --git a/ports/samd/boards/mpconfig_samd21.h b/ports/samd/mcu/samd21/mpconfigmcu.h similarity index 100% rename from ports/samd/boards/mpconfig_samd21.h rename to ports/samd/mcu/samd21/mpconfigmcu.h diff --git a/ports/samd/mcu/samd21/mpconfigmcu.mk b/ports/samd/mcu/samd21/mpconfigmcu.mk new file mode 100644 index 000000000000..cc435da8cc91 --- /dev/null +++ b/ports/samd/mcu/samd21/mpconfigmcu.mk @@ -0,0 +1 @@ +SRC_S += shared/runtime/gchelper_m0.s diff --git a/ports/samd/boards/mpconfig_samd51.h b/ports/samd/mcu/samd51/mpconfigmcu.h similarity index 100% rename from ports/samd/boards/mpconfig_samd51.h rename to ports/samd/mcu/samd51/mpconfigmcu.h diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk new file mode 100644 index 000000000000..461a0182ef01 --- /dev/null +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -0,0 +1 @@ +SRC_S += shared/runtime/gchelper_m3.s diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 48631080d27f..8a067d348239 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -29,7 +29,7 @@ // Board specific definitions #include "mpconfigboard.h" // MCU-Specific definitions -#include MPCONFIG_MCU_H +#include "mpconfigmcu.h" // Memory allocation policies #define MICROPY_GC_STACK_ENTRY_TYPE uint16_t From 7da76639027057245cfee043733193b3265e7a54 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 9 Jun 2022 13:44:22 +0200 Subject: [PATCH 1832/4290] samd/mphalport: Add a mp_hal_ticks_ms_64() function. Returning a 64 bit number. This will be used by the utime module and the machine.UART module for timeout avoiding overflow. --- ports/samd/mphalport.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index 2eb4ce7ca680..c2aca8b0e273 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -50,6 +50,10 @@ static inline mp_uint_t mp_hal_ticks_ms(void) { return systick_ms; } +static inline uint64_t mp_hal_ticks_ms_64(void) { + return ((uint64_t)systick_ms_upper << 32) + systick_ms; +} + static inline mp_uint_t mp_hal_ticks_us(void) { #if defined(MCU_SAMD21) @@ -74,7 +78,7 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { } static inline uint64_t mp_hal_time_ns(void) { - return ((uint64_t)systick_ms + (uint64_t)systick_ms_upper * 0x100000000) * 1000000; + return mp_hal_ticks_ms_64() * 1000000; } // C-level pin HAL From 37449df821a47698779b48e6c101b084cfbdb6c7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 9 Jun 2022 14:33:31 +0200 Subject: [PATCH 1833/4290] samd/modutime: Enable time.time() based on systick_ms(). Allowing to set a time and retrieve the time. It is based on systick_ms() with the precision of the MCU clock. Unless that is based on a crystal, the error seen was about 0.5% at room temperature. --- ports/samd/modutime.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ports/samd/modutime.c b/ports/samd/modutime.c index bbeedcfda070..a54544e62c6c 100644 --- a/ports/samd/modutime.c +++ b/ports/samd/modutime.c @@ -27,6 +27,9 @@ #include "py/runtime.h" #include "extmod/utime_mphal.h" #include "shared/timeutils/timeutils.h" +#include "mphalport.h" + +static uint32_t time_offset = 0; // localtime([secs]) STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { @@ -34,9 +37,10 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { mp_int_t seconds; if (n_args == 0 || args[0] == mp_const_none) { // seconds = pyb_rtc_get_us_since_epoch() / 1000 / 1000; - seconds = mp_obj_get_int(args[0]); + seconds = mp_hal_ticks_ms_64() / 1000 + time_offset; } else { seconds = mp_obj_get_int(args[0]); + time_offset = seconds - mp_hal_ticks_ms_64() / 1000; } timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); mp_obj_t tuple[8] = { @@ -72,7 +76,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); // time() STATIC mp_obj_t time_time(void) { - mp_raise_NotImplementedError("time"); + return mp_obj_new_int_from_uint(mp_hal_ticks_ms_64() / 1000 + time_offset); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); From 9a567b04e7c43024a2a4dce2618b24f822dfe5bc Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 9 Jun 2022 13:46:54 +0200 Subject: [PATCH 1834/4290] samd/machine_uart: Support buffered TX for UART. It can be enabled/disabled by a configuration switch. The code size increase is 308 bytes, but it requires RAM space for buffers, the larger UART object and root pointers. --- ports/samd/machine_uart.c | 78 +++++++++++++++++++++++------ ports/samd/mcu/samd21/mpconfigmcu.h | 2 + ports/samd/mcu/samd51/mpconfigmcu.h | 2 + 3 files changed, 66 insertions(+), 16 deletions(-) diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index 0ed7fb95d0c3..92e63ee51e6f 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -37,7 +37,6 @@ #define DEFAULT_BUFFER_SIZE (256) #define MIN_BUFFER_SIZE (32) #define MAX_BUFFER_SIZE (32766) -#define USART_BUFFER_TX (0) typedef struct _machine_uart_obj_t { mp_obj_base_t base; @@ -54,7 +53,7 @@ typedef struct _machine_uart_obj_t { uint16_t timeout_char; // timeout waiting between chars (in ms) bool new; ringbuf_t read_buffer; - #if USART_BUFFER_TX + #if MICROPY_HW_UART_TXBUF ringbuf_t write_buffer; #endif } machine_uart_obj_t; @@ -91,7 +90,15 @@ void common_uart_irq_handler(int uart_id) { // Now handler the incoming data uart_drain_rx_fifo(self, uart); } else if (uart->USART.INTFLAG.bit.DRE != 0) { + #if MICROPY_HW_UART_TXBUF // handle the outgoing data + if (ringbuf_avail(&self->write_buffer) > 0) { + uart->USART.DATA.bit.DATA = ringbuf_get(&self->write_buffer); + } else { + // Stop the interrupt if there is no more data + uart->USART.INTENCLR.bit.DRE = 1; + } + #endif } else { // Disable the other interrupts, if set by error uart->USART.INTENCLR.reg = (uint8_t) ~(SERCOM_USART_INTENCLR_DRE | SERCOM_USART_INTENCLR_RXC); @@ -127,7 +134,7 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, - #if USART_BUFFER_TX + #if MICROPY_HW_UART_TXBUF { MP_QSTR_txbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, #endif }; @@ -191,7 +198,7 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args } } - #if USART_BUFFER_TX + #if MICROPY_HW_UART_TXBUF // Set the TX buffer size if configured. size_t txbuf_len = DEFAULT_BUFFER_SIZE; if (args[ARG_txbuf].u_int > 0) { @@ -224,7 +231,7 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args ringbuf_alloc(&(self->read_buffer), rxbuf_len + 1); MP_STATE_PORT(samd_uart_rx_buffer[self->id]) = self->read_buffer.buf; - #if USART_BUFFER_TX + #if MICROPY_HW_UART_TXBUF ringbuf_alloc(&(self->write_buffer), txbuf_len + 1); MP_STATE_PORT(samd_uart_tx_buffer[self->id]) = self->write_buffer.buf; #endif @@ -274,6 +281,8 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args uint32_t baud = 65536 - ((uint64_t)(65536 * 16) * self->baudrate + get_apb_freq() / 2) / get_apb_freq(); uart->USART.BAUD.bit.BAUD = baud; // Set Baud + sercom_register_irq(self->id, &common_uart_irq_handler); + // Enable RXC interrupt uart->USART.INTENSET.bit.RXC = 1; #if defined(MCU_SAMD21) @@ -281,7 +290,13 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args #elif defined(MCU_SAMD51) NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2); #endif - sercom_register_irq(self->id, &common_uart_irq_handler); + #if MICROPY_HW_UART_TXBUF + // Enable DRE interrupt + // SAMD21 has just 1 IRQ for all USART events, so no need for an additional NVIC enable + #if defined(MCU_SAMD51) + NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 0); + #endif + #endif sercom_enable(uart, 1); } @@ -330,7 +345,7 @@ STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) { // Disable interrupts uart->USART.INTENCLR.reg = 0xff; MP_STATE_PORT(samd_uart_rx_buffer[self->id]) = NULL; - #if USART_BUFFER_TX + #if MICROPY_HW_UART_TXBUF MP_STATE_PORT(samd_uart_tx_buffer[self->id]) = NULL; #endif return mp_const_none; @@ -339,7 +354,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit); STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - // get all bytes from the fifo first + // get all bytes from the fifo first. May be obsolete. uart_drain_rx_fifo(self, sercom_instance[self->id]); return MP_OBJ_NEW_SMALL_INT(ringbuf_avail(&self->read_buffer)); } @@ -349,9 +364,14 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); uint32_t break_time_us = 13 * 1000000 / self->baudrate; + // Wait for the tx buffer to drain. + #if MICROPY_HW_UART_TXBUF + while (ringbuf_avail(&self->write_buffer) > 0) { + MICROPY_EVENT_POLL_HOOK + } + #endif // Wait for the TX queue & register to clear // Since the flags are not safe, just wait sufficiently long. - // Once tx buffering is implemented, wait as well for the buffer to clear. mp_hal_delay_us(2 * break_time_us); // Disable MUX PORT->Group[self->tx / 32].PINCFG[self->tx % 32].bit.PMUXEN = 0; @@ -389,7 +409,7 @@ STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_t STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint64_t t = mp_hal_ticks_ms() + self->timeout; + uint64_t t = mp_hal_ticks_ms_64() + self->timeout; uint64_t timeout_char = self->timeout_char; uint8_t *dest = buf_in; Sercom *uart = sercom_instance[self->id]; @@ -403,7 +423,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz uart_drain_rx_fifo(self, uart); break; } - if (mp_hal_ticks_ms() > t) { // timed out + if (mp_hal_ticks_ms_64() > t) { // timed out if (i <= 0) { *errcode = MP_EAGAIN; return MP_STREAM_ERROR; @@ -421,17 +441,40 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - size_t remaining = size; + size_t i = 0; const uint8_t *src = buf_in; Sercom *uart = sercom_instance[self->id]; - while (remaining--) { - while (!(uart->USART.INTFLAG.bit.DRE)) { + #if MICROPY_HW_UART_TXBUF + uint64_t t = mp_hal_ticks_ms_64() + self->timeout; + + while (i < size) { + // Wait for the first/next character to be sent. + while (ringbuf_free(&(self->write_buffer)) == 0) { + if (mp_hal_ticks_ms_64() > t) { // timed out + if (i <= 0) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } else { + return i; + } + } + MICROPY_EVENT_POLL_HOOK } - uart->USART.DATA.bit.DATA = *src; - src += 1; + ringbuf_put(&(self->write_buffer), *src++); + i++; + uart->USART.INTENSET.bit.DRE = 1; // kick off the IRQ } + #else + + while (i < size) { + while (!(uart->USART.INTFLAG.bit.DRE)) { + } + uart->USART.DATA.bit.DATA = *src++; + i++; + } + #endif return size; } @@ -473,3 +516,6 @@ MP_DEFINE_CONST_OBJ_TYPE( ); MP_REGISTER_ROOT_POINTER(void *samd_uart_rx_buffer[SERCOM_INST_NUM]); +#if MICROPY_HW_UART_TXBUF +MP_REGISTER_ROOT_POINTER(void *samd_uart_tx_buffer[SERCOM_INST_NUM]); +#endif diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 587f3f4b3ad6..7b91be1430a0 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -5,6 +5,8 @@ #define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; +#define MICROPY_HW_UART_TXBUF (1) + #define CPU_FREQ (48000000) #define APB_FREQ (48000000) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 95fc635e5e32..089ca48de88b 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -19,6 +19,8 @@ unsigned long trng_random_u32(void); #define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // +#define MICROPY_HW_UART_TXBUF (1) + #define CPU_FREQ (120000000) #define APB_FREQ (48000000) #define DPLLx_REF_FREQ (32768) From a9304af8fa7165c41be1cad3d55042a5cc14d13c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 6 Jun 2022 21:06:09 +0200 Subject: [PATCH 1835/4290] samd/boards: Add missing/lost board config and pin definitions. Fixes are: - Pin definitions for ADAFRUIT_FEATHER_Mx_EXPRESS and ADAFRUIT_ITSYBITSY_M4_EXPRESS. - For ADAFRUIT_ITSYBITSY_M0_EXPRESS, change the MISO/MOSI name. - For MINISAM_M4, add the default SPI pins. - For boards with 32k crystal, add the XOSC32K setting. --- .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h | 2 ++ ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv | 3 +++ .../boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h | 2 ++ ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv | 9 +++++++++ .../samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv | 6 +++--- .../samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv | 10 ++++++++-- ports/samd/boards/MINISAM_M4/pins.csv | 3 +++ ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h | 2 ++ ports/samd/boards/SEEED_XIAO/mpconfigboard.h | 2 ++ 9 files changed, 34 insertions(+), 5 deletions(-) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h index cec9e9ccdda4..815597899c4a 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/mpconfigboard.h @@ -1,2 +1,4 @@ #define MICROPY_HW_BOARD_NAME "Feather M0 Express" #define MICROPY_HW_MCU_NAME "SAMD21G18A" + +#define MICROPY_HW_XOSC32K (1) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv index 84e68157acbc..0985ee1646d1 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv @@ -29,6 +29,9 @@ PIN_PB22,TX PIN_PB23,RX PIN_PA23,SCL PIN_PA22,SDA +PIN_PB10,MOSI +PIN_PA12,MISO +PIN_PB11,SCK PIN_PA06,NEOPIXEL PIN_PA13,FLASH_CS diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h index 48599eec4729..35945395fcc0 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h @@ -1,2 +1,4 @@ #define MICROPY_HW_BOARD_NAME "Feather M4 Express" #define MICROPY_HW_MCU_NAME "SAMD51J19A" + +#define MICROPY_HW_XOSC32K (1) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv index 5b999c39e022..32daac3d0f4c 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv @@ -7,6 +7,8 @@ PIN_PB17,D0 PIN_PB16,D1 +- +- PIN_PA14,D4 PIN_PA16,D5 PIN_PA18,D6 @@ -30,5 +32,12 @@ PIN_PB22,MISO PIN_PA17,SCK PIN_PB01,VDIV PIN_PA03,AREF +PIN_PB03,NEOPIXEL +PIN_PB11,FLASH_CS +PIN_PB10,FLASH_SCK +PIN_PA08,FLASH_MOSI +PIN_PA09,FLASH_MISO +PIN_PA10,FLASH_WP +PIN_PA11,FLASH_HOLD LED_PA17,LED diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv index 50c3c1cf68f5..d7d59c23575d 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv @@ -8,7 +8,7 @@ PIN_PA11,D0 PIN_PA10,D1 PIN_PA14,D2 -PIN_PB09,D3 +PIN_PA09,D3 PIN_PA08,D4 PIN_PA15,D5 - @@ -27,8 +27,8 @@ PIN_PA05,A4 PIN_PB02,A5 PIN_PA22,SDA PIN_PA23,SCL -PIN_PB10,MO -PIN_PA12,MI +PIN_PB10,MOSI +PIN_PA12,MISO PIN_PB11,SCK PIN_PA00,DOTSTAR_CLK PIN_PA01,DOTSTAR_DATA diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv index 90e38761a10c..ce760a269c24 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv @@ -27,10 +27,16 @@ PIN_PA04,A4 PIN_PA06,A5 PIN_PA12,SDA PIN_PA13,SCL -PIN_PA00,MO -PIN_PB23,MI +PIN_PA00,MOSI +PIN_PB23,MISO PIN_PA01,SCK PIN_PB02,DOTSTAR_CLK PIN_PB03,DOTSTAR_DATA +PIN_PB11,FLASH_CS +PIN_PB10,FLASH_SCK +PIN_PA08,FLASH_MOSI +PIN_PA09,FLASH_MISO +PIN_PA10,FLASH_WP +PIN_PA11,FLASH_HOLD LED_PA22,LED diff --git a/ports/samd/boards/MINISAM_M4/pins.csv b/ports/samd/boards/MINISAM_M4/pins.csv index 7442a028d12a..cf9a3bd19b21 100644 --- a/ports/samd/boards/MINISAM_M4/pins.csv +++ b/ports/samd/boards/MINISAM_M4/pins.csv @@ -21,6 +21,9 @@ PIN_PA00,BUTTON PIN_PA03,AREF PIN_PA12,SDA PIN_PA13,SCL +PIN_PB22,MOSI +PIN_PB23,MISO +PIN_PA01,SCK PIN_PB03,DOTSTAR_DATA PIN_PB02,DOTSTAR_CLK diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h index c69b5b4c149d..064d1ecc0d03 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/mpconfigboard.h @@ -1,2 +1,4 @@ #define MICROPY_HW_BOARD_NAME "SAMD21-XPLAINED-PRO" #define MICROPY_HW_MCU_NAME "SAMD21J18A" + +#define MICROPY_HW_XOSC32K (1) diff --git a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h index 2026efc6b153..98994a5bc06b 100644 --- a/ports/samd/boards/SEEED_XIAO/mpconfigboard.h +++ b/ports/samd/boards/SEEED_XIAO/mpconfigboard.h @@ -1,2 +1,4 @@ #define MICROPY_HW_BOARD_NAME "Seeed Xiao" #define MICROPY_HW_MCU_NAME "SAMD21G18A" + +#define MICROPY_HW_XOSC32K (1) From fd7b57dd22ce0105e04c5f9b2d12ca3a3075ca0a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 10 Jun 2022 08:23:09 +0200 Subject: [PATCH 1836/4290] samd/mphalport: Use CYCCNT for SAMD51's mp_hal_ticks_cpu(). And use mp_hal_ticks_us() for SAM21's mp_hal_ticks_cpu(). The SAMD21 has no CYCCNT register, and the SysTick register has only a 1 ms span (== 48000 count range). --- ports/samd/mphalport.h | 16 +++++++++++++--- ports/samd/samd_soc.c | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index c2aca8b0e273..b7e65da35dc0 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -71,11 +71,21 @@ static inline mp_uint_t mp_hal_ticks_us(void) { #endif } -// ticks_cpu is limited to a 1 ms period, since the CPU SysTick counter -// is used for the 1 ms SysTick_Handler interrupt. +#if defined (MCU_SAMD21) + +#define mp_hal_ticks_cpu mp_hal_ticks_us + +#elif defined (MCU_SAMD51) +static inline void mp_hal_ticks_cpu_enable(void) { + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CYCCNT = 0; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; +} + static inline mp_uint_t mp_hal_ticks_cpu(void) { - return (system_time_t)SysTick->VAL; + return (system_time_t)DWT->CYCCNT; } +#endif static inline uint64_t mp_hal_time_ns(void) { return mp_hal_ticks_ms_64() * 1000000; diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 8d6e808f6390..aca6df0dd88e 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -36,6 +36,7 @@ #include "samd_soc.h" #include "sam.h" #include "tusb.h" +#include "mphalport.h" static void usb_init(void) { // Init USB clock @@ -110,4 +111,7 @@ void samd_init(void) { SysTick_Config(get_cpu_freq() / 1000); init_us_counter(); usb_init(); + #if defined (MCU_SAMD51) + mp_hal_ticks_cpu_enable(); + #endif } From a4157521731878c7363ff59f15d68eb68b486cb5 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 10 Jun 2022 16:40:50 +0200 Subject: [PATCH 1837/4290] samd/machine_bitstream: Add the machine.bitstream() function. The SAMD21 implementation is an adaption of @jimmo's code for STM32Lxx. The only changes are the addresses and names of the port registers and the timing parameters. SAMD21: The precision is about +/-25ns at 48MHz clock frequency. The first two cycles are about 40-60 ns longer than set. But still good enough to drive a neopixel device. SAMD51: The precision is about +/-30ns at 120MHz clock frequency. Good enough to drive a neopixel device. --- ports/samd/Makefile | 3 +- ports/samd/machine_bitstream.c | 206 +++++++++++++++++++++++++++++++++ ports/samd/modmachine.c | 2 + ports/samd/mpconfigport.h | 1 + ports/samd/mphalport.h | 4 +- ports/samd/samd_soc.c | 2 +- 6 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 ports/samd/machine_bitstream.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 1455e748cc3a..f1bc67e6ee4d 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -87,10 +87,11 @@ LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)" LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif -SRC_C = \ +SRC_C += \ clock_config.c \ help.c \ machine_adc.c \ + machine_bitstream.c \ machine_dac.c \ machine_i2c.c \ machine_led.c \ diff --git a/ports/samd/machine_bitstream.c b/ports/samd/machine_bitstream.c new file mode 100644 index 000000000000..9959d947cb44 --- /dev/null +++ b/ports/samd/machine_bitstream.c @@ -0,0 +1,206 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jim Mussared + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c. + +#include "py/mpconfig.h" +#include "py/mphal.h" +#include "clock_config.h" + +#if MICROPY_PY_MACHINE_BITSTREAM + +#if __CORTEX_M == 0 + +// No cycle counter on M0, do manual cycle counting instead. + +// STM32F091 @ 48MHz +#define NS_CYCLES_PER_ITER_HIGH (3) +#define NS_CYCLES_PER_ITER_LOW (3) +#define NS_OVERHEAD_CYCLES_HIGH (12) +#define NS_OVERHEAD_CYCLES_LOW (15) + +uint32_t mp_hal_delay_ns_calc(uint32_t ns, bool high) { + uint32_t ncycles = (get_cpu_freq() / 1000000 * ns + 500) / 1000; // + 500 for proper rounding + uint32_t overhead = MIN(ncycles, high ? NS_OVERHEAD_CYCLES_HIGH : NS_OVERHEAD_CYCLES_LOW); + return MAX(1, MP_ROUND_DIVIDE(ncycles - overhead, high ? NS_CYCLES_PER_ITER_HIGH : NS_CYCLES_PER_ITER_LOW)); +} + +void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { + volatile const uint32_t mask = 1 << (pin % 32); + volatile uint32_t *outclr = &PORT->Group[pin / 32].OUTCLR.reg; + volatile uint32_t *outset = &PORT->Group[pin / 32].OUTSET.reg; + + // Convert ns to loop iterations [high_time_0, low_time_0, high_time_1, low_time_1]. + for (size_t i = 0; i < 4; ++i) { + timing_ns[i] = mp_hal_delay_ns_calc(timing_ns[i], i % 2 == 0); + } + + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + + // Measured timing for SAMD21 at 48MHz (cycle=20.83ns) + // timing_ns = (1,1,1,1) + // high: 310 + // low: 375 + // high0: 375 + // low0: 400 + // timing_ns = (500, 500, 500, 500) + // high: 500 + // low: 500 + // high0: 565 + // low0: 540 + // timing_ns = (1000, 1000, 1000, 1000) + // high: 1000 + // low: 1000 + // high0: 1065 + // low0: 1040 + + // --> high is 12 + n*3 cycles + // low is 15 + n*3 cycles + + // NeoPixel timing (400, 850, 800, 450) (+/-150ns) gives timing_ns=(2, 9, 8, 3) which in cycles is + // (12 + 6, 15 + 27, 15 + 24, 12 + 9) = (18, 42, 39, 21) + // --> (375, 875, 812, 437) nanoseconds. + // Measured output on logic analyser is (375, 875, 815, 435) (+/-5ns at 200MHz) + + // Note: the first high/low cycle is longer by 2-3 cycles (40-60ns). + // This is slightly outside spec, but doesn't seem to cause a problem. + + __asm volatile ( + // Force consistent register assignment. + // r6 = len + "ldr r6, %0\n" + // r4 = buf + "ldr r4, %1\n" + // r5 = timing_ms + "ldr r5, %2\n" + + // Must align for consistent timing. + ".align 4\n" + + // Don't increment/decrement before first iteration. + "b .outer2\n" + ".outer:\n" + // ++buf, --len + " add r4, #1\n" + " sub r6, #1\n" + + // len iterations + ".outer2:\n" + " cmp r6, #0\n" + " beq .done\n" + + // r0 = *buf + " ldrb r0, [r4, #0]\n" + + // 8 bits in byte + " mov r7, #8\n" + " .inner:\n" + // *outset = mask + " ldr r2, %3\n" + " ldr r1, %5\n" + " str r1, [r2, #0]\n" + + // r3 = (r0 >> 4) & 8 (r0 is 8 if high bit is 1 else 0) + " mov r8, r6\n" + " lsr r3, r0, #4\n" + " mov r6, #8\n" + " and r3, r6\n" + " mov r6, r8\n" + + // r2 = timing_ns[r2] + " ldr r2, [r5, r3]\n" + " .loop1:\n sub r2, #1\n bne .loop1\n" + + // *outclr = mask + " ldr r2, %4\n" + " str r1, [r2, #0]\n" + + // r2 = timing_ns[r3 + 4] + " add r3, #4\n" + " ldr r2, [r5, r3]\n" + " .loop2:\n sub r2, #1\n bne .loop2\n" + + // b >>= 1 + " lsl r0, r0, #1\n" + + " sub r7, #1\n" + // end of inner loop + " beq .outer\n" + // continue inner loop + " b .inner\n" + + ".done:\n" + : + : "m" (len), "m" (buf), "m" (timing_ns), "m" (outset), "m" (outclr), "m" (mask) + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8" + ); + + MICROPY_END_ATOMIC_SECTION(atomic_state); +} + +#else // > CORTEX_M0 + +#define NS_TICKS_OVERHEAD (70) + +void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { + uint32_t fcpu_mhz = get_cpu_freq() / 1000000; + uint32_t ticks_overhead = fcpu_mhz * NS_TICKS_OVERHEAD / 1000; + // Convert ns to us ticks [high_time_0, period_0, high_time_1, period_1]. + for (size_t i = 0; i < 4; ++i) { + timing_ns[i] = fcpu_mhz * timing_ns[i] / 1000; + if (timing_ns[i] > ticks_overhead) { + timing_ns[i] -= ticks_overhead; + } + if (i % 2 == 1) { + // Convert low_time to period (i.e. add high_time). + timing_ns[i] += timing_ns[i - 1] - ticks_overhead; + } + } + + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + DWT->CYCCNT = 0; + + for (size_t i = 0; i < len; ++i) { + uint8_t b = buf[i]; + for (size_t j = 0; j < 8; ++j) { + uint32_t start_ticks = mp_hal_ticks_cpu(); + uint32_t *t = &timing_ns[b >> 6 & 2]; + mp_hal_pin_high(pin); + while ((mp_hal_ticks_cpu() - start_ticks) < t[0]) { + } + b <<= 1; + mp_hal_pin_low(pin); + while ((mp_hal_ticks_cpu() - start_ticks) < t[1]) { + } + } + } + MICROPY_END_ATOMIC_SECTION(atomic_state); + +} + +#endif // > CORTEX_M0 + +#endif // MICROPY_PY_MACHINE_BITSTREAM diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index c191afda7910..f6cf7f8155c9 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -25,6 +25,7 @@ */ #include "py/runtime.h" +#include "extmod/machine_bitstream.h" #include "extmod/machine_mem.h" #include "extmod/machine_pulse.h" #include "extmod/machine_i2c.h" @@ -167,6 +168,7 @@ 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_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, + { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 8a067d348239..986c42fc7f84 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -111,6 +111,7 @@ #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_OS_DUPTERM (3) +#define MICROPY_PY_MACHINE_BITSTREAM (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PWM (1) #define MICROPY_PY_MACHINE_PWM_INIT (0) diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index b7e65da35dc0..f1efd550035a 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -71,11 +71,11 @@ static inline mp_uint_t mp_hal_ticks_us(void) { #endif } -#if defined (MCU_SAMD21) +#if defined(MCU_SAMD21) #define mp_hal_ticks_cpu mp_hal_ticks_us -#elif defined (MCU_SAMD51) +#elif defined(MCU_SAMD51) static inline void mp_hal_ticks_cpu_enable(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT = 0; diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index aca6df0dd88e..d0df4a7e28cc 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -111,7 +111,7 @@ void samd_init(void) { SysTick_Config(get_cpu_freq() / 1000); init_us_counter(); usb_init(); - #if defined (MCU_SAMD51) + #if defined(MCU_SAMD51) mp_hal_ticks_cpu_enable(); #endif } From 929dfc66a30c361d2a0bd5b64dec021a49c7b471 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 15 Jun 2022 15:16:07 +0200 Subject: [PATCH 1838/4290] samd/mpconfigport: Restructure to use ROM feature levels. Changes are: - Set the feature level for each MCU: CORE features for SAMD21, and EXTRA features for SAMD51. - Remove all definitions that are included in the core feature level. - Keep the default settings for feature level and float, to make the choice obvious. --- ports/samd/Makefile | 1 + ports/samd/mcu/samd21/mpconfigmcu.h | 22 +++++++++++++++------- ports/samd/mcu/samd51/mpconfigmcu.h | 25 ++++++++++++++++--------- ports/samd/mpconfigport.h | 23 +---------------------- 4 files changed, 33 insertions(+), 38 deletions(-) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index f1bc67e6ee4d..5b268286c3a2 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -161,6 +161,7 @@ SRC_QSTR += \ shared/readline/readline.c \ extmod/uos_dupterm.c \ shared/runtime/mpirq.c \ + shared/runtime/sys_stdio_mphal.c \ SRC_QSTR += $(SRC_MOD) $(SRC_CXX) diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 7b91be1430a0..dd16a6c8affd 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -1,16 +1,24 @@ // Deinitions common to all SAMD21 boards #include "samd21.h" -#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES) -#define MICROPY_HW_UART_TXBUF (1) +// MicroPython emitters +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_INLINE_THUMB (0) -#define CPU_FREQ (48000000) -#define APB_FREQ (48000000) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) -#define IRQ_PRI_PENDSV ((1 << __NVIC_PRIO_BITS) - 1) +#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; + +#define MICROPY_HW_UART_TXBUF (1) + +#define CPU_FREQ (48000000) +#define APB_FREQ (48000000) + +#define IRQ_PRI_PENDSV ((1 << __NVIC_PRIO_BITS) - 1) static inline uint32_t raise_irq_pri(uint32_t pri) { (void)pri; diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 089ca48de88b..c3253fcbecb7 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -1,10 +1,17 @@ // Deinitions common to all SAMD51 boards #include "samd51.h" +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES) + +// MicroPython emitters +#define MICROPY_EMIT_THUMB (1) +#define MICROPY_EMIT_INLINE_THUMB (1) + #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) + #define MICROPY_PY_UOS_URANDOM (1) #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) unsigned long trng_random_u32(void); @@ -15,18 +22,18 @@ unsigned long trng_random_u32(void); // samd_flash.c flash parameters // Build a 128k Flash storage at top. 512k-128k=384k=0x60000 // 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) -#define VFS_BLOCK_SIZE_BYTES (1536) // +#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) +#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) +#define VFS_BLOCK_SIZE_BYTES (1536) // -#define MICROPY_HW_UART_TXBUF (1) +#define MICROPY_HW_UART_TXBUF (1) -#define CPU_FREQ (120000000) -#define APB_FREQ (48000000) -#define DPLLx_REF_FREQ (32768) +#define CPU_FREQ (120000000) +#define APB_FREQ (48000000) +#define DPLLx_REF_FREQ (32768) -#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) -#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) +#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) +#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) static inline uint32_t raise_irq_pri(uint32_t pri) { uint32_t basepri = __get_BASEPRI(); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 986c42fc7f84..8b8305f0b47e 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -40,8 +40,6 @@ // MicroPython emitters #define MICROPY_PERSISTENT_CODE_LOAD (1) -#define MICROPY_EMIT_THUMB (0) -#define MICROPY_EMIT_INLINE_THUMB (0) // Compiler configuration #define MICROPY_COMP_CONST (1) @@ -56,33 +54,18 @@ #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_STREAMS_NON_BLOCK (1) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) -#define MICROPY_CPYTHON_COMPAT (0) -#define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_TEXT samd_help_text #define MICROPY_PY_BUILTINS_HELP_MODULES (1) #define MICROPY_ENABLE_SCHEDULER (1) -// fixes sys/usys import issue #define MICROPY_MODULE_WEAK_LINKS (1) + // Control over Python builtins -#define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_BYTES_HEX (1) -#define MICROPY_PY_BUILTINS_STR_COUNT (0) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) -#define MICROPY_PY_BUILTINS_SET (0) -#define MICROPY_PY_BUILTINS_FROZENSET (0) -#define MICROPY_PY_BUILTINS_PROPERTY (0) -#define MICROPY_PY_BUILTINS_ENUMERATE (1) -#define MICROPY_PY_BUILTINS_FILTER (0) -#define MICROPY_PY_BUILTINS_REVERSED (0) -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_BUILTINS_MIN_MAX (1) #define MICROPY_PY_BUILTINS_INPUT (1) -#define MICROPY_PY___FILE__ (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) -#define MICROPY_PY_ATTRTUPLE (1) -#define MICROPY_PY_COLLECTIONS (0) #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_PLATFORM "samd" #define MICROPY_PY_SYS_EXIT (1) @@ -118,10 +101,6 @@ #define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/samd/machine_pwm.c" -// Use VfsLfs's types for fileio/textio -#define mp_type_fileio mp_type_vfs_lfs1_fileio -#define mp_type_textio mp_type_vfs_lfs1_textio - #define MP_STATE_PORT MP_STATE_VM // Miscellaneous settings From f00356a486ed7ea9650f59f1259b2732d9a1bb21 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 15 Jun 2022 18:49:24 +0200 Subject: [PATCH 1839/4290] samd/clock_config: Split clock_config.c to separate SAMD21/SAMD51 files. And put the file into the mcu directory. The file got a little bit long and hard to read. --- ports/samd/Makefile | 2 +- ports/samd/mcu/samd21/clock_config.c | 168 +++++++++++++++++++++ ports/samd/{ => mcu/samd51}/clock_config.c | 131 ---------------- 3 files changed, 169 insertions(+), 132 deletions(-) create mode 100644 ports/samd/mcu/samd21/clock_config.c rename ports/samd/{ => mcu/samd51}/clock_config.c (59%) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 5b268286c3a2..8d49778b3bcc 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -88,7 +88,7 @@ LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif SRC_C += \ - clock_config.c \ + mcu/$(MCU_SERIES_LOWER)/clock_config.c \ help.c \ machine_adc.c \ machine_bitstream.c \ diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c new file mode 100644 index 000000000000..3d189d67e18c --- /dev/null +++ b/ports/samd/mcu/samd21/clock_config.c @@ -0,0 +1,168 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * This file provides functions for configuring the clocks. + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "samd_soc.h" + +static uint32_t cpu_freq = CPU_FREQ; +static uint32_t apb_freq = APB_FREQ; + +int sercom_gclk_id[] = { + GCLK_CLKCTRL_ID_SERCOM0_CORE, GCLK_CLKCTRL_ID_SERCOM1_CORE, + GCLK_CLKCTRL_ID_SERCOM2_CORE, GCLK_CLKCTRL_ID_SERCOM3_CORE, + GCLK_CLKCTRL_ID_SERCOM4_CORE, GCLK_CLKCTRL_ID_SERCOM5_CORE +}; + +uint32_t get_cpu_freq(void) { + return cpu_freq; +} + +uint32_t get_apb_freq(void) { + return apb_freq; +} + +void set_cpu_freq(uint32_t cpu_freq_arg) { + cpu_freq = cpu_freq_arg; +} + + +void init_clocks(uint32_t cpu_freq) { + + // SAMD21 Clock settings + // GCLK0: 48MHz from DFLL open loop mode or closed loop mode from 32k Crystal + // GCLK1: 32768 Hz from 32K ULP or 32k Crystal + // GCLK2: 48MHz from DFLL for Peripherals + // GCLK3: 1Mhz for the us-counter (TC4/TC5) + // GCLK8: 1kHz clock for WDT + + NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" + NVMCTRL->CTRLB.bit.RWS = 1; // 1 read wait state for 48MHz + + #if MICROPY_HW_XOSC32K + // Set up OSC32K according datasheet 17.6.3 + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP(0x3) | SYSCTRL_XOSC32K_EN32K | + SYSCTRL_XOSC32K_XTALEN; + SYSCTRL->XOSC32K.bit.ENABLE = 1; + while (SYSCTRL->PCLKSR.bit.XOSC32KRDY == 0) { + } + // Set up the DFLL48 according to the data sheet 17.6.7.1.2 + // Step 1: Set up the reference clock + // Connect the OSC32K via GCLK1 to the DFLL input and for further use. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(1); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_DFLL48 | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_CLKEN; + // Enable access to the DFLLCTRL reg acc. to Errata 1.2.1 + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; + while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { + } + // Step 2: Set the coarse and fine values. + // The coarse setting will be taken from the calibration data. So the value used here + // does not matter. Get the coarse value from the calib data. In case it is not set, + // set a midrange value. + uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) + >> FUSES_DFLL48M_COARSE_CAL_Pos; + if (coarse == 0x3f) { + coarse = 0x1f; + } + SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); + while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { + } + // Step 3: Set the multiplication values. The offset of 16384 to the freq is for rounding. + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_MUL((CPU_FREQ + 16384) / 32768) | + SYSCTRL_DFLLMUL_FSTEP(1) | SYSCTRL_DFLLMUL_CSTEP(1); + while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { + } + // Step 4: Start the DFLL and wait for the PLL lock. We just wait for the fine lock, since + // coarse adjusting is bypassed. + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK | + SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_ENABLE; + while (SYSCTRL->PCLKSR.bit.DFLLLCKF == 0) { + } + + #else // MICROPY_HW_XOSC32K + + // Enable DFLL48M + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { + } + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | SYSCTRL_DFLLMUL_FSTEP(1) + | SYSCTRL_DFLLMUL_MUL(48000); + uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) + >> FUSES_DFLL48M_COARSE_CAL_Pos; + if (coarse == 0x3f) { + coarse = 0x1f; + } + SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_USBCRM + | SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_ENABLE; + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { + } + // Enable 32768 Hz on GCLK1 for consistency + GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(48016384 / 32768); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(1); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + #endif // MICROPY_HW_XOSC32K + + // Enable GCLK output: 48M on both CCLK0 and GCLK2 + GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(2); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + // Enable GCLK output: 1MHz on GCLK3 for TC4 + GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(48); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(3); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + // Set GCLK8 to 1 kHz. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); + while (GCLK->STATUS.bit.SYNCBUSY) { + } +} + +void enable_sercom_clock(int id) { + // Next: Set up the clocks + // Enable synchronous clock. The bits are nicely arranged + PM->APBCMASK.reg |= 0x04 << id; + // Select multiplexer generic clock source and enable. + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | sercom_gclk_id[id]; + // Wait while it updates synchronously. + while (GCLK->STATUS.bit.SYNCBUSY) { + } +} diff --git a/ports/samd/clock_config.c b/ports/samd/mcu/samd51/clock_config.c similarity index 59% rename from ports/samd/clock_config.c rename to ports/samd/mcu/samd51/clock_config.c index 0f5634fdb737..3a3f40385f5d 100644 --- a/ports/samd/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -34,13 +34,6 @@ static uint32_t cpu_freq = CPU_FREQ; static uint32_t apb_freq = APB_FREQ; -#if defined(MCU_SAMD21) -int sercom_gclk_id[] = { - GCLK_CLKCTRL_ID_SERCOM0_CORE, GCLK_CLKCTRL_ID_SERCOM1_CORE, - GCLK_CLKCTRL_ID_SERCOM2_CORE, GCLK_CLKCTRL_ID_SERCOM3_CORE, - GCLK_CLKCTRL_ID_SERCOM4_CORE, GCLK_CLKCTRL_ID_SERCOM5_CORE -}; -#elif defined(MCU_SAMD51) int sercom_gclk_id[] = { SERCOM0_GCLK_ID_CORE, SERCOM1_GCLK_ID_CORE, SERCOM2_GCLK_ID_CORE, SERCOM3_GCLK_ID_CORE, @@ -49,7 +42,6 @@ int sercom_gclk_id[] = { SERCOM6_GCLK_ID_CORE, SERCOM7_GCLK_ID_CORE, #endif }; -#endif uint32_t get_cpu_freq(void) { return cpu_freq; @@ -59,12 +51,6 @@ uint32_t get_apb_freq(void) { return apb_freq; } -#if defined(MCU_SAMD21) -void set_cpu_freq(uint32_t cpu_freq_arg) { - cpu_freq = cpu_freq_arg; -} - -#elif defined(MCU_SAMD51) void set_cpu_freq(uint32_t cpu_freq_arg) { cpu_freq = cpu_freq_arg; @@ -97,113 +83,8 @@ void set_cpu_freq(uint32_t cpu_freq_arg) { while (GCLK->SYNCBUSY.bit.GENCTRL0) { } } -#endif void init_clocks(uint32_t cpu_freq) { - #if defined(MCU_SAMD21) - - // SAMD21 Clock settings - // GCLK0: 48MHz from DFLL open loop mode or closed loop mode from 32k Crystal - // GCLK1: 32768 Hz from 32K ULP or 32k Crystal - // GCLK2: 48MHz from DFLL for Peripherals - // GCLK3: 1Mhz for the us-counter (TC3/TC4) - // GCLK8: 1kHz clock for WDT - - NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" - NVMCTRL->CTRLB.bit.RWS = 1; // 1 read wait state for 48MHz - - #if MICROPY_HW_XOSC32K - // Set up OSC32K according datasheet 17.6.3 - SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP(0x3) | SYSCTRL_XOSC32K_EN32K | - SYSCTRL_XOSC32K_XTALEN; - SYSCTRL->XOSC32K.bit.ENABLE = 1; - while (SYSCTRL->PCLKSR.bit.XOSC32KRDY == 0) { - } - // Set up the DFLL48 according to the data sheet 17.6.7.1.2 - // Step 1: Set up the reference clock - // Connect the OSC32K via GCLK1 to the DFLL input and for further use. - GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(1); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(1); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_DFLL48 | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_CLKEN; - // Enable access to the DFLLCTRL reg acc. to Errata 1.2.1 - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; - while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { - } - // Step 2: Set the coarse and fine values. - // The coarse setting will be taken from the calibration data. So the value used here - // does not matter. Get the coarse value from the calib data. In case it is not set, - // set a midrange value. - uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) - >> FUSES_DFLL48M_COARSE_CAL_Pos; - if (coarse == 0x3f) { - coarse = 0x1f; - } - SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); - while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { - } - // Step 3: Set the multiplication values. The offset of 16384 to the freq is for rounding. - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_MUL((CPU_FREQ + 16384) / 32768) | - SYSCTRL_DFLLMUL_FSTEP(1) | SYSCTRL_DFLLMUL_CSTEP(1); - while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { - } - // Step 4: Start the DFLL and wait for the PLL lock. We just wait for the fine lock, since - // coarse adjusting is bypassed. - SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK | - SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_ENABLE; - while (SYSCTRL->PCLKSR.bit.DFLLLCKF == 0) { - } - - #else // MICROPY_HW_XOSC32K - - // Enable DFLL48M - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; - while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { - } - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | SYSCTRL_DFLLMUL_FSTEP(1) - | SYSCTRL_DFLLMUL_MUL(48000); - uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) - >> FUSES_DFLL48M_COARSE_CAL_Pos; - if (coarse == 0x3f) { - coarse = 0x1f; - } - SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_USBCRM - | SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_ENABLE; - while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { - } - // Enable 32768 Hz on GCLK1 for consistency - GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(48016384 / 32768); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(1); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - #endif // MICROPY_HW_XOSC32K - - // Enable GCLK output: 48M on both CCLK0 and GCLK2 - GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(1); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(2); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - // Enable GCLK output: 1MHz on GCLK3 for TC3 - GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(48); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(3); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - // Set GCLK8 to 1 kHz. - GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - #elif defined(MCU_SAMD51) - // SAMD51 clock settings // GCLK0: 48MHz from DFLL48M or 48 - 200 MHz from DPLL0 (SAMD51) // GCLK1: DPLLx_REF_FREQ 32768 Hz from 32KULP or 32k Crystal @@ -299,21 +180,10 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL[3].reg = GCLK_GENCTRL_DIV(6) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL3) { } - - #endif // defined(MCU_SAMD51) } void enable_sercom_clock(int id) { // Next: Set up the clocks - #if defined(MCU_SAMD21) - // Enable synchronous clock. The bits are nicely arranged - PM->APBCMASK.reg |= 0x04 << id; - // Select multiplexer generic clock source and enable. - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | sercom_gclk_id[id]; - // Wait while it updates synchronously. - while (GCLK->STATUS.bit.SYNCBUSY) { - } - #elif defined(MCU_SAMD51) GCLK->PCHCTRL[sercom_gclk_id[id]].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; // no easy way to set the clocks, except enabling all of them switch (id) { @@ -344,5 +214,4 @@ void enable_sercom_clock(int id) { break; #endif } - #endif } From 20e7313453b34778df7cddbe3bc6bd72d3b737d7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 15 Jun 2022 18:58:02 +0200 Subject: [PATCH 1840/4290] samd/clock_config: Add HW_DFLL_USB_SYNC and HW_MCU_OSC32KULP extensions. Two new compile flags are: MICROPY_HW_DFLL_USB_SYNC: Effective only if DFLL48 does not run from the crystal. It will synchronize the DFLL48M clock with the USB's SOF pulse. If no USB is connected, it will fall back to open loop mode. The DFLL48M clock is then pretty precise, but with a higher clock jitter at SAMD51 devices. MICROPY_HW_MCU_OSC32KULP: Effective only if the devics uses a crystal as clock source. Run the MCU clock from the ULP 32kHz oszillator instead of the crystal. This flag was added to cater for a interference problem of the crystal and Neopixel/Debug pins at Adafruit FEATHER Mx boards, which causes the board to crash. Drawback: ticks_ms() and time.time() vs. than ticks_us() and the peripherals like PWM run at not synchronous clocks. --- .../mpconfigboard.h | 3 +- .../mpconfigboard.h | 2 + .../mpconfigboard.h | 2 + ports/samd/clock_config.h | 1 + ports/samd/mcu/samd21/clock_config.c | 68 +++++++++++++--- ports/samd/mcu/samd51/clock_config.c | 78 +++++++++++++++++-- ports/samd/samd_soc.c | 1 + 7 files changed, 137 insertions(+), 18 deletions(-) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h index 35945395fcc0..b78c003b19a5 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.h @@ -1,4 +1,5 @@ #define MICROPY_HW_BOARD_NAME "Feather M4 Express" #define MICROPY_HW_MCU_NAME "SAMD51J19A" -#define MICROPY_HW_XOSC32K (1) +#define MICROPY_HW_XOSC32K (1) +#define MICROPY_HW_MCU_OSC32KULP (1) diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h index d647af9312ed..160c61ea2aaa 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/mpconfigboard.h @@ -1,2 +1,4 @@ #define MICROPY_HW_BOARD_NAME "ItsyBitsy M0 Express" #define MICROPY_HW_MCU_NAME "SAMD21G18A" + +#define MICROPY_HW_DFLL_USB_SYNC (1) diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h index 2fffc9c7de28..f53481d63191 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.h @@ -1,2 +1,4 @@ #define MICROPY_HW_BOARD_NAME "ItsyBitsy M4 Express" #define MICROPY_HW_MCU_NAME "SAMD51G19A" + +#define MICROPY_HW_DFLL_USB_SYNC (1) diff --git a/ports/samd/clock_config.h b/ports/samd/clock_config.h index 0e7a9e3280ec..6e48b286f498 100644 --- a/ports/samd/clock_config.h +++ b/ports/samd/clock_config.h @@ -30,4 +30,5 @@ void init_clocks(uint32_t cpu_freq); void set_cpu_freq(uint32_t cpu_freq); uint32_t get_cpu_freq(void); uint32_t get_apb_freq(void); +void check_usb_recovery_mode(void); void enable_sercom_clock(int id); diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index 3d189d67e18c..e330d7ba6af2 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -29,10 +29,12 @@ #include #include "py/runtime.h" +#include "py/mphal.h" #include "samd_soc.h" static uint32_t cpu_freq = CPU_FREQ; static uint32_t apb_freq = APB_FREQ; +static uint32_t dfll48m_calibration; int sercom_gclk_id[] = { GCLK_CLKCTRL_ID_SERCOM0_CORE, GCLK_CLKCTRL_ID_SERCOM1_CORE, @@ -52,14 +54,28 @@ void set_cpu_freq(uint32_t cpu_freq_arg) { cpu_freq = cpu_freq_arg; } +void check_usb_recovery_mode(void) { + #if !MICROPY_HW_XOSC32K + mp_hal_delay_ms(500); + // Check USB status. If not connected, switch DFLL48M back to open loop + if (USB->DEVICE.DeviceEndpoint[0].EPCFG.reg == 0) { + // Set/keep the open loop mode of the device. + SYSCTRL->DFLLVAL.reg = dfll48m_calibration; + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_ENABLE; + } + #endif // MICROPY_HW_XOSC32K +} void init_clocks(uint32_t cpu_freq) { + dfll48m_calibration = 0; // please the compiler + // SAMD21 Clock settings // GCLK0: 48MHz from DFLL open loop mode or closed loop mode from 32k Crystal - // GCLK1: 32768 Hz from 32K ULP or 32k Crystal + // GCLK1: 32768 Hz from 32K ULP or DFLL48M // GCLK2: 48MHz from DFLL for Peripherals // GCLK3: 1Mhz for the us-counter (TC4/TC5) + // GCLK4: 32kHz from crystal, if present // GCLK8: 1kHz clock for WDT NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" @@ -74,19 +90,34 @@ void init_clocks(uint32_t cpu_freq) { } // Set up the DFLL48 according to the data sheet 17.6.7.1.2 // Step 1: Set up the reference clock - // Connect the OSC32K via GCLK1 to the DFLL input and for further use. + + #if MICROPY_HW_MCU_OSC32KULP + // Connect the GCLK1 to the XOSC32KULP + GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(1); + #else + // Connect the GCLK1 to OSC32K via GCLK1 to the DFLL input and for further use. GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(1); GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(1); + #endif + while (GCLK->STATUS.bit.SYNCBUSY) { } - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_DFLL48 | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_CLKEN; + + // Connect the GCLK4 to OSC32K via GCLK1 to the DFLL input and for further use. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(4) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(4); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + // Connect GCLK4 to the DFLL input and for further use. + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_DFLL48 | GCLK_CLKCTRL_GEN_GCLK4 | GCLK_CLKCTRL_CLKEN; // Enable access to the DFLLCTRL reg acc. to Errata 1.2.1 SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; while (SYSCTRL->PCLKSR.bit.DFLLRDY == 0) { } // Step 2: Set the coarse and fine values. - // The coarse setting will be taken from the calibration data. So the value used here - // does not matter. Get the coarse value from the calib data. In case it is not set, + // Get the coarse value from the calib data. In case it is not set, // set a midrange value. uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos; @@ -103,7 +134,7 @@ void init_clocks(uint32_t cpu_freq) { } // Step 4: Start the DFLL and wait for the PLL lock. We just wait for the fine lock, since // coarse adjusting is bypassed. - SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK | + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK | SYSCTRL_DFLLCTRL_STABLE | SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_ENABLE; while (SYSCTRL->PCLKSR.bit.DFLLLCKF == 0) { } @@ -114,18 +145,33 @@ void init_clocks(uint32_t cpu_freq) { SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { } - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | SYSCTRL_DFLLMUL_FSTEP(1) - | SYSCTRL_DFLLMUL_MUL(48000); + uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos; if (coarse == 0x3f) { coarse = 0x1f; } - SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_USBCRM + SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(511); + + #if MICROPY_HW_DFLL_USB_SYNC + // Configure the DFLL48M for USB clock recovery. + // Will have to switch back if no USB + SYSCTRL->DFLLSYNC.bit.READREQ = 1; + dfll48m_calibration = SYSCTRL->DFLLVAL.reg; + // Set the Multiplication factor. + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | SYSCTRL_DFLLMUL_FSTEP(1) + | SYSCTRL_DFLLMUL_MUL(48000); + // Set the mode to closed loop USB Recovery mode + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_USBCRM | SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_ENABLE; + #else + // Set/keep the open loop mode of the device. + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | SYSCTRL_DFLLCTRL_ENABLE; + #endif + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) { } + // Enable 32768 Hz on GCLK1 for consistency GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(48016384 / 32768); GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(1); @@ -154,10 +200,10 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); while (GCLK->STATUS.bit.SYNCBUSY) { } + } void enable_sercom_clock(int id) { - // Next: Set up the clocks // Enable synchronous clock. The bits are nicely arranged PM->APBCMASK.reg |= 0x04 << id; // Select multiplexer generic clock source and enable. diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index 3a3f40385f5d..62c05193dd8b 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -29,10 +29,12 @@ #include #include "py/runtime.h" +#include "py/mphal.h" #include "samd_soc.h" static uint32_t cpu_freq = CPU_FREQ; static uint32_t apb_freq = APB_FREQ; +static uint32_t dfll48m_calibration; int sercom_gclk_id[] = { SERCOM0_GCLK_ID_CORE, SERCOM1_GCLK_ID_CORE, @@ -84,12 +86,43 @@ void set_cpu_freq(uint32_t cpu_freq_arg) { } } +void check_usb_recovery_mode(void) { + #if !MICROPY_HW_XOSC32K + mp_hal_delay_ms(500); + // Check USB status. If not connected, switch DFLL48M back to open loop + if (USB->DEVICE.DeviceEndpoint[0].EPCFG.reg == 0) { + // as per Errata 2.8.3 + OSCCTRL->DFLLMUL.reg = 0; + while (OSCCTRL->DFLLSYNC.bit.DFLLMUL == 1) { + } + // Set the mode to open loop mode + OSCCTRL->DFLLCTRLB.reg = 0; + while (OSCCTRL->DFLLSYNC.bit.DFLLCTRLB == 1) { + } + OSCCTRL->DFLLCTRLA.reg = OSCCTRL_DFLLCTRLA_RUNSTDBY | OSCCTRL_DFLLCTRLA_ENABLE; + while (OSCCTRL->DFLLSYNC.bit.ENABLE == 1) { + } + OSCCTRL->DFLLVAL.reg = dfll48m_calibration; // Reload DFLLVAL register + while (OSCCTRL->DFLLSYNC.bit.DFLLVAL == 1) { + } + // Set the mode to open loop mode + OSCCTRL->DFLLCTRLB.reg = 0; + while (OSCCTRL->DFLLSYNC.bit.DFLLCTRLB == 1) { + } + } + #endif // MICROPY_HW_XOSC32K +} + void init_clocks(uint32_t cpu_freq) { + + dfll48m_calibration = 0; // please the compiler + // SAMD51 clock settings // GCLK0: 48MHz from DFLL48M or 48 - 200 MHz from DPLL0 (SAMD51) - // GCLK1: DPLLx_REF_FREQ 32768 Hz from 32KULP or 32k Crystal + // GCLK1: 32768 Hz from 32KULP or DFLL48M // GCLK2: 48MHz from DFLL48M for Peripheral devices // GCLK3: 16Mhz for the us-counter (TC0/TC1) + // GCLK4: 32kHz from crystal, if present // DPLL0: 48 - 200 MHz // Steps to set up clocks: @@ -102,6 +135,7 @@ void init_clocks(uint32_t cpu_freq) { // Setup GCLK0 to 120MHz // Setup GCLK2 to 48MHz for Peripherals // Setup GCLK3 to 8MHz for TC0/TC1 + // Setup GCLK4 to 32kHz crystal, if present // Setup GCLK0 for 48MHz as default state to keep the MCU running during config change. GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; @@ -124,15 +158,26 @@ void init_clocks(uint32_t cpu_freq) { while (OSC32KCTRL->STATUS.bit.XOSC32KRDY == 0) { } + #if MICROPY_HW_MCU_OSC32KULP + // Setup GCLK1 for 32kHz ULP + GCLK->GENCTRL[1].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K; + #else // Setup GCLK1 for 32kHz crystal GCLK->GENCTRL[1].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K; + #endif + while (GCLK->SYNCBUSY.bit.GENCTRL1) { } + // Setup GCLK4 for 32kHz crystal + GCLK->GENCTRL[4].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K; + while (GCLK->SYNCBUSY.bit.GENCTRL4) { + } + // Set-up the DFLL48M in closed loop mode with input from the 32kHz crystal - // Step 1: Peripheral channel 0 is driven by GCLK1 and it feeds DFLL48M - GCLK->PCHCTRL[0].reg = GCLK_PCHCTRL_GEN_GCLK1 | GCLK_PCHCTRL_CHEN; + // Step 1: Peripheral channel 0 is driven by GCLK4 and it feeds DFLL48M + GCLK->PCHCTRL[0].reg = GCLK_PCHCTRL_GEN_GCLK4 | GCLK_PCHCTRL_CHEN; while (GCLK->PCHCTRL[0].bit.CHEN == 0) { } // Step 2: Set the multiplication values. The offset of 16384 to the freq is for rounding. @@ -141,7 +186,7 @@ void init_clocks(uint32_t cpu_freq) { while (OSCCTRL->DFLLSYNC.bit.DFLLMUL == 1) { } // Step 3: Set the mode to closed loop - OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_BPLCKC | OSCCTRL_DFLLCTRLB_MODE; + OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_BPLCKC | OSCCTRL_DFLLCTRLB_STABLE | OSCCTRL_DFLLCTRLB_MODE; while (OSCCTRL->DFLLSYNC.bit.DFLLCTRLB == 1) { } // Wait for lock fine @@ -154,12 +199,34 @@ void init_clocks(uint32_t cpu_freq) { #else // MICROPY_HW_XOSC32K - // Set GCLK1 to DPLL0_REF_FREQ as defined in mpconfigboard.h (e.g. 32768 Hz) + // Derive GCLK1 from DFLL48M at DPLL0_REF_FREQ as defined in mpconfigboard.h (e.g. 32768 Hz) GCLK->GENCTRL[1].reg = ((APB_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) << GCLK_GENCTRL_DIV_Pos | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL1) { } + OSCCTRL->DFLLCTRLA.bit.RUNSTDBY = 1; + OSCCTRL->DFLLCTRLA.bit.ONDEMAND = 0; + + OSCCTRL->DFLLCTRLA.bit.ENABLE = 1; + while (OSCCTRL->DFLLSYNC.bit.ENABLE == 1) { + } + + #if MICROPY_HW_DFLL_USB_SYNC + // Configure the DFLL48M for USB clock recovery. + // Will have to switch back if no USB + dfll48m_calibration = OSCCTRL->DFLLVAL.reg; + // Set the Multiplication factor. + OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_MUL(48000) | + OSCCTRL_DFLLMUL_FSTEP(1) | OSCCTRL_DFLLMUL_CSTEP(1); + while (OSCCTRL->DFLLSYNC.bit.DFLLMUL == 1) { + } + // Set the mode to closed loop USB Recovery + OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_USBCRM | OSCCTRL_DFLLCTRLB_CCDIS | OSCCTRL_DFLLCTRLB_MODE; + while (OSCCTRL->DFLLSYNC.bit.DFLLCTRLB == 1) { + } + #endif + #endif // MICROPY_HW_XOSC32K // Peripheral channel 1 is driven by GCLK1 and it feeds DPLL0 @@ -183,7 +250,6 @@ void init_clocks(uint32_t cpu_freq) { } void enable_sercom_clock(int id) { - // Next: Set up the clocks GCLK->PCHCTRL[sercom_gclk_id[id]].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; // no easy way to set the clocks, except enabling all of them switch (id) { diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index d0df4a7e28cc..f4a27f3df740 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -111,6 +111,7 @@ void samd_init(void) { SysTick_Config(get_cpu_freq() / 1000); init_us_counter(); usb_init(); + check_usb_recovery_mode(); #if defined(MCU_SAMD51) mp_hal_ticks_cpu_enable(); #endif From 85fb8b8b027d0af560a2b74e5bd4a0554600f6bd Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 16 Jun 2022 11:32:21 +0200 Subject: [PATCH 1841/4290] samd/pin_af: Simplify the pin-af-table handling. Changes are: - The pin-af-table-SAMDxx.csv file are moved to the mcu directories with the name as pin-af-table.csv. - The handling in Makefile and pin_af.c is simplified. --- ports/samd/Makefile | 3 +-- .../samd21/pin-af-table.csv} | 8 ++++---- .../samd51/pin-af-table.csv} | 0 ports/samd/pin_af.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) rename ports/samd/{boards/pin-af-table-SAMD21.csv => mcu/samd21/pin-af-table.csv} (95%) rename ports/samd/{boards/pin-af-table-SAMD51.csv => mcu/samd51/pin-af-table.csv} (100%) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 8d49778b3bcc..9a03502abcdd 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -48,7 +48,7 @@ INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include/pio INC += -I$(TOP)/lib/tinyusb/src MAKE_PIN_AF = boards/make-pin-af.py -PIN_AF_TABLE_CSV = boards/pin-af-table-$(MCU_SERIES).csv +PIN_AF_TABLE_CSV = mcu/$(MCU_SERIES_LOWER)/pin-af-table.csv GEN_PIN_AF = pin_af_table.c MAKE_PINS = boards/make-pins.py @@ -62,7 +62,6 @@ CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERI CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += -DMPCONFIG_MCU_H='' -CFLAGS += -DPIN_AF_TABLE_C='<$(BUILD)/$(GEN_PIN_AF)>' LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref LDFLAGS += $(LDFLAGS_MOD) diff --git a/ports/samd/boards/pin-af-table-SAMD21.csv b/ports/samd/mcu/samd21/pin-af-table.csv similarity index 95% rename from ports/samd/boards/pin-af-table-SAMD21.csv rename to ports/samd/mcu/samd21/pin-af-table.csv index d8ab903c9e7c..6445d148b8fa 100644 --- a/ports/samd/boards/pin-af-table-SAMD21.csv +++ b/ports/samd/mcu/samd21/pin-af-table.csv @@ -59,7 +59,7 @@ pa30,10,,,12,10, pa31,11,,,13,11, pb30,14,,,50,00,12 pb31,15,,,51,01,13 -pb00,0,,,52,70, -pb01,1,,,53,71, -pb02,2,,,50,60, -pb03,3,,,51,61, +pb00,0,8,,52,70, +pb01,1,9,,53,71, +pb02,2,10,,50,60, +pb03,3,11,,51,61, diff --git a/ports/samd/boards/pin-af-table-SAMD51.csv b/ports/samd/mcu/samd51/pin-af-table.csv similarity index 100% rename from ports/samd/boards/pin-af-table-SAMD51.csv rename to ports/samd/mcu/samd51/pin-af-table.csv diff --git a/ports/samd/pin_af.c b/ports/samd/pin_af.c index 8c152e0d8be0..926c4ae0c23a 100644 --- a/ports/samd/pin_af.c +++ b/ports/samd/pin_af.c @@ -38,7 +38,7 @@ extern const uint8_t tcc_channel_count[]; -#include PIN_AF_TABLE_C +#include "pin_af_table.c" // Just look for an table entry for a given pin and raise an error // in case of no match (which should not happen). From 560170de024353354b4bcd1682392f2bb282c12d Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 21 Jun 2022 18:00:51 +0200 Subject: [PATCH 1842/4290] samd/samd_flash: Remove obsolete printf's and return values instead. Returning values is much more useful. --- ports/samd/samd_flash.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ports/samd/samd_flash.c b/ports/samd/samd_flash.c index 522522ef8473..2fffd614f972 100644 --- a/ports/samd/samd_flash.c +++ b/ports/samd/samd_flash.c @@ -96,21 +96,17 @@ STATIC mp_obj_t eraseblock(uint32_t sector_in) { } STATIC mp_obj_t samd_flash_version(void) { - printf("Flash Driver Version: %lu\n", flash_get_version()); - return mp_const_none; + return MP_OBJ_NEW_SMALL_INT(flash_get_version()); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(samd_flash_version_obj, samd_flash_version); -STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(samd_flash_version_static_obj, MP_ROM_PTR(&samd_flash_version_obj)); STATIC mp_obj_t samd_flash_size(void) { // ASF4 API calls mp_int_t PAGES = flash_get_total_pages(&flash_desc); mp_int_t PAGE_SIZE = flash_get_page_size(&flash_desc); - printf("Flash Size: %u Bytes\n", PAGES * PAGE_SIZE); - return mp_const_none; + return MP_OBJ_NEW_SMALL_INT(PAGES * PAGE_SIZE); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(samd_flash_size_obj, samd_flash_size); -STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(samd_flash_size_static_obj, MP_ROM_PTR(&samd_flash_size_obj)); STATIC mp_obj_t samd_flash_readblocks(size_t n_args, const mp_obj_t *args) { uint32_t offset = (mp_obj_get_int(args[1]) * BLOCK_SIZE) + samd_flash_obj.flash_base; @@ -172,8 +168,8 @@ STATIC mp_obj_t samd_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg STATIC MP_DEFINE_CONST_FUN_OBJ_3(samd_flash_ioctl_obj, samd_flash_ioctl); STATIC const mp_rom_map_elem_t samd_flash_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_flash_version), MP_ROM_PTR(&samd_flash_version_static_obj) }, - { MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&samd_flash_size_static_obj) }, + { MP_ROM_QSTR(MP_QSTR_flash_version), MP_ROM_PTR(&samd_flash_version_obj) }, + { MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&samd_flash_size_obj) }, { MP_ROM_QSTR(MP_QSTR_flash_init), MP_ROM_PTR(&samd_flash_init_obj) }, { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&samd_flash_readblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&samd_flash_writeblocks_obj) }, From b0017304625b5d33bea548166b010bd2c3bf465d Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 24 Jun 2022 08:27:23 +0200 Subject: [PATCH 1843/4290] samd/Makefile: Fix a dependency problem with "make -j". The build directory was not created before attempting to create the generated files in it. --- ports/samd/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 9a03502abcdd..d8ca0f8ba698 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -194,12 +194,13 @@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin pin_af.c: $(BUILD)/$(GEN_PIN_AF) -$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) +$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) | $(HEADER_BUILD) $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES) +machine_led.c machine_pin.c modsamd.c: $(GEN_PINS_HDR) -$(GEN_PINS_SRC): $(BOARD_PINS) +$(GEN_PINS_SRC) $(GEN_PINS_HDR): $(BOARD_PINS) | $(HEADER_BUILD) $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --pins $(GEN_PINS_SRC) --inc $(GEN_PINS_HDR) From e9a76310ec567dd94712a92876ca150bac43f103 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 28 Jun 2022 16:59:01 +0200 Subject: [PATCH 1844/4290] samd/mphalport: Fix USB endpoint handling ignoring Ctrl-C. Porting PR #8040 by @hoihu to SAMD, following the commit 587339022689187a1acbccc1d0e2425a67385ff7. One small addition: before executing keyboard interrupt, the input buffer is cleared. --- ports/samd/Makefile | 1 + ports/samd/mphalport.c | 75 +++++++++++++++++++++++++++++++----------- ports/samd/mphalport.h | 1 + 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index d8ca0f8ba698..5ff00f21f926 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -131,6 +131,7 @@ SRC_C += \ shared/libc/string0.c \ shared/readline/readline.c \ shared/runtime/gchelper_native.c \ + shared/runtime/interrupt_char.c \ shared/runtime/pyexec.c \ shared/runtime/softtimer.c \ shared/runtime/stdout_helpers.c \ diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index fc451023903c..ad3817768f77 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -33,22 +33,54 @@ #include "samd_soc.h" #include "tusb.h" -#if MICROPY_KBD_EXCEPTION -int mp_interrupt_char = -1; - -void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { - (void)itf; - (void)wanted_char; - tud_cdc_read_char(); // discard interrupt char - mp_sched_keyboard_interrupt(); -} +#ifndef MICROPY_HW_STDIN_BUFFER_LEN +#define MICROPY_HW_STDIN_BUFFER_LEN 128 +#endif + +STATIC uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN]; +ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0 }; -void mp_hal_set_interrupt_char(int c) { - mp_interrupt_char = c; - tud_cdc_set_wanted_char(c); +uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll + +void poll_cdc_interfaces(void) { + // any CDC interfaces left to poll? + if (cdc_itf_pending && ringbuf_free(&stdin_ringbuf)) { + for (uint8_t itf = 0; itf < 8; ++itf) { + if (cdc_itf_pending & (1 << itf)) { + tud_cdc_rx_cb(itf); + if (!cdc_itf_pending) { + break; + } + } + } + } } -#endif +void tud_cdc_rx_cb(uint8_t itf) { + // consume pending USB data immediately to free usb buffer and keep the endpoint from stalling. + // in case the ringbuffer is full, mark the CDC interface that need attention later on for polling + cdc_itf_pending &= ~(1 << itf); + for (uint32_t bytes_avail = tud_cdc_n_available(itf); bytes_avail > 0; --bytes_avail) { + if (ringbuf_free(&stdin_ringbuf)) { + int data_char = tud_cdc_read_char(); + #if MICROPY_KBD_EXCEPTION + if (data_char == mp_interrupt_char) { + // Clear the ring buffer + stdin_ringbuf.iget = stdin_ringbuf.iput = 0; + // and stop + mp_sched_keyboard_interrupt(); + } else { + ringbuf_put(&stdin_ringbuf, data_char); + } + #else + ringbuf_put(&stdin_ringbuf, data_char); + #endif + } else { + cdc_itf_pending |= (1 << itf); + return; + } + } +} void mp_hal_set_pin_mux(mp_hal_pin_obj_t pin, uint8_t mux) { int pin_grp = pin / 32; @@ -94,9 +126,12 @@ void mp_hal_delay_us(mp_uint_t us) { uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { uintptr_t ret = 0; - if (tud_cdc_connected() && tud_cdc_available()) { + + poll_cdc_interfaces(); + if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) { ret |= MP_STREAM_POLL_RD; } + #if MICROPY_PY_OS_DUPTERM ret |= mp_uos_dupterm_poll(poll_flags); #endif @@ -105,13 +140,13 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { int mp_hal_stdin_rx_chr(void) { for (;;) { - if (tud_cdc_connected() && tud_cdc_available()) { - uint8_t buf[1]; - uint32_t count = tud_cdc_read(buf, sizeof(buf)); - if (count) { - return buf[0]; - } + + poll_cdc_interfaces(); + int c = ringbuf_get(&stdin_ringbuf); + if (c != -1) { + return c; } + #if MICROPY_PY_OS_DUPTERM int dupterm_c = mp_uos_dupterm_rx_chr(); if (dupterm_c >= 0) { diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index f1efd550035a..ced0d642b4ed 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -27,6 +27,7 @@ #ifndef MICROPY_INCLUDED_SAMD_MPHALPORT_H #define MICROPY_INCLUDED_SAMD_MPHALPORT_H +#include "py/ringbuf.h" #include "py/mpconfig.h" // ASF4 From d9338aabc5647979f4a0ec3cb0a7e987a2a2249f Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 30 Jun 2022 16:50:15 +0200 Subject: [PATCH 1845/4290] samd: Change the symbol names for the peripheral clocks. From APB_FREQ to DFLL48M_FREQ, and from apb_freq to peripheral_freq. --- ports/samd/clock_config.h | 2 +- ports/samd/machine_i2c.c | 2 +- ports/samd/machine_pwm.c | 3 ++- ports/samd/machine_spi.c | 4 ++-- ports/samd/machine_uart.c | 4 ++-- ports/samd/mcu/samd21/clock_config.c | 6 +++--- ports/samd/mcu/samd21/mpconfigmcu.h | 2 +- ports/samd/mcu/samd51/clock_config.c | 12 ++++++------ ports/samd/mcu/samd51/mpconfigmcu.h | 2 +- 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/ports/samd/clock_config.h b/ports/samd/clock_config.h index 6e48b286f498..35b7e532814b 100644 --- a/ports/samd/clock_config.h +++ b/ports/samd/clock_config.h @@ -29,6 +29,6 @@ void init_clocks(uint32_t cpu_freq); void set_cpu_freq(uint32_t cpu_freq); uint32_t get_cpu_freq(void); -uint32_t get_apb_freq(void); +uint32_t get_peripheral_freq(void); void check_usb_recovery_mode(void); void enable_sercom_clock(int id); diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c index 90ea5e10ca43..25dfa99340ff 100644 --- a/ports/samd/machine_i2c.c +++ b/ports/samd/machine_i2c.c @@ -185,7 +185,7 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n // baud = peripheral_freq / (2 * baudrate) - 5 - (rise_time * peripheral_freq) / 2 // Just set the minimal configuration for standard and fast mode. // Set Baud. Assume ~300ns rise time. Maybe set later by a keyword argument. - i2c->I2CM.BAUD.reg = get_apb_freq() / (2 * self->freq) - 5 - (get_apb_freq() / 1000000) * RISETIME_NS / 2000; + i2c->I2CM.BAUD.reg = get_peripheral_freq() / (2 * self->freq) - 5 - (get_peripheral_freq() / 1000000) * RISETIME_NS / 2000; // Enable interrupts sercom_register_irq(self->id, &common_i2c_irq_handler); diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c index 6f9ca42b1b2a..d987927d310c 100644 --- a/ports/samd/machine_pwm.c +++ b/ports/samd/machine_pwm.c @@ -28,6 +28,7 @@ #include "py/runtime.h" #include "py/mphal.h" #include "modmachine.h" +#include "clock_config.h" #include "sam.h" #include "pin_af.h" @@ -50,7 +51,7 @@ typedef struct _machine_pwm_obj_t { #define PWM_NOT_INIT (0) #define PWM_CLK_READY (1) #define PWM_TCC_ENABLED (2) -#define PWM_MASTER_CLK (48000000) +#define PWM_MASTER_CLK (get_peripheral_freq()) #define PWM_FULL_SCALE (65536) static Tcc *tcc_instance[] = TCC_INSTS; diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c index ddb8756e9a34..8321f19cf0dd 100644 --- a/ports/samd/machine_spi.c +++ b/ports/samd/machine_spi.c @@ -206,9 +206,9 @@ STATIC void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj spi->SPI.CTRLC.reg = 1; // 1 clock cycle character spacing #endif - // SPI is driven by the clock of GCLK Generator 2, freq in bus_freq + // SPI is driven by the clock of GCLK Generator 2, freq by get_peripheral_freq() // baud = bus_freq / (2 * baudrate) - 1 - uint32_t baud = get_apb_freq() / (2 * self->baudrate) - 1; + uint32_t baud = get_peripheral_freq() / (2 * self->baudrate) - 1; spi->SPI.BAUD.reg = baud; // Set Baud // Enable RXC interrupt only if miso is defined diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index 92e63ee51e6f..1031f26c2648 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -276,9 +276,9 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args while (uart->USART.SYNCBUSY.bit.CTRLB) { } - // USART is driven by the clock of GCLK Generator 2, freq by get_apb_freq() + // USART is driven by the clock of GCLK Generator 2, freq by get_peripheral_freq() // baud rate; 65536 * (1 - 16 * 115200/bus_freq) - uint32_t baud = 65536 - ((uint64_t)(65536 * 16) * self->baudrate + get_apb_freq() / 2) / get_apb_freq(); + uint32_t baud = 65536 - ((uint64_t)(65536 * 16) * self->baudrate + get_peripheral_freq() / 2) / get_peripheral_freq(); uart->USART.BAUD.bit.BAUD = baud; // Set Baud sercom_register_irq(self->id, &common_uart_irq_handler); diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index e330d7ba6af2..2402ed2e3107 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -33,7 +33,7 @@ #include "samd_soc.h" static uint32_t cpu_freq = CPU_FREQ; -static uint32_t apb_freq = APB_FREQ; +static uint32_t peripheral_freq = DFLL48M_FREQ; static uint32_t dfll48m_calibration; int sercom_gclk_id[] = { @@ -46,8 +46,8 @@ uint32_t get_cpu_freq(void) { return cpu_freq; } -uint32_t get_apb_freq(void) { - return apb_freq; +uint32_t get_peripheral_freq(void) { + return peripheral_freq; } void set_cpu_freq(uint32_t cpu_freq_arg) { diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index dd16a6c8affd..ecb125bbdb77 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -16,7 +16,7 @@ #define MICROPY_HW_UART_TXBUF (1) #define CPU_FREQ (48000000) -#define APB_FREQ (48000000) +#define DFLL48M_FREQ (48000000) #define IRQ_PRI_PENDSV ((1 << __NVIC_PRIO_BITS) - 1) diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index 62c05193dd8b..31c8f5a8654c 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -33,7 +33,7 @@ #include "samd_soc.h" static uint32_t cpu_freq = CPU_FREQ; -static uint32_t apb_freq = APB_FREQ; +static uint32_t peripheral_freq = DFLL48M_FREQ; static uint32_t dfll48m_calibration; int sercom_gclk_id[] = { @@ -49,8 +49,8 @@ uint32_t get_cpu_freq(void) { return cpu_freq; } -uint32_t get_apb_freq(void) { - return apb_freq; +uint32_t get_peripheral_freq(void) { + return peripheral_freq; } void set_cpu_freq(uint32_t cpu_freq_arg) { @@ -181,7 +181,7 @@ void init_clocks(uint32_t cpu_freq) { while (GCLK->PCHCTRL[0].bit.CHEN == 0) { } // Step 2: Set the multiplication values. The offset of 16384 to the freq is for rounding. - OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_MUL((APB_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) | + OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_MUL((DFLL48M_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) | OSCCTRL_DFLLMUL_FSTEP(1) | OSCCTRL_DFLLMUL_CSTEP(1); while (OSCCTRL->DFLLSYNC.bit.DFLLMUL == 1) { } @@ -200,7 +200,7 @@ void init_clocks(uint32_t cpu_freq) { #else // MICROPY_HW_XOSC32K // Derive GCLK1 from DFLL48M at DPLL0_REF_FREQ as defined in mpconfigboard.h (e.g. 32768 Hz) - GCLK->GENCTRL[1].reg = ((APB_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) << GCLK_GENCTRL_DIV_Pos + GCLK->GENCTRL[1].reg = ((DFLL48M_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) << GCLK_GENCTRL_DIV_Pos | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL1) { } @@ -236,7 +236,7 @@ void init_clocks(uint32_t cpu_freq) { set_cpu_freq(cpu_freq); - apb_freq = APB_FREQ; // To be changed if CPU_FREQ < 48M + peripheral_freq = DFLL48M_FREQ; // To be changed if CPU_FREQ < 48M // Setup GCLK2 for DPLL1 output (48 MHz) GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index c3253fcbecb7..2c1ea7fee257 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -29,7 +29,7 @@ unsigned long trng_random_u32(void); #define MICROPY_HW_UART_TXBUF (1) #define CPU_FREQ (120000000) -#define APB_FREQ (48000000) +#define DFLL48M_FREQ (48000000) #define DPLLx_REF_FREQ (32768) #define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) From 00dcf0464318764066f81f90992d5bfc40acebf1 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 21 Jun 2022 17:32:48 +0200 Subject: [PATCH 1846/4290] samd/mcu: Add floating point suport for SAMD21 devices. For consistency it should be there. --- ports/samd/mcu/samd21/mpconfigmcu.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index ecb125bbdb77..9329a6eb89bc 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -7,7 +7,10 @@ #define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_INLINE_THUMB (0) -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_PY_BUILTINS_COMPLEX (0) +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_CMATH (0) #define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) #define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) From 387025f5d12ec6313b396e63e770dd9f22f9daeb Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 21 Jun 2022 20:31:20 +0200 Subject: [PATCH 1847/4290] samd/mcu: Enable the math module on SAMD51. --- ports/samd/mcu/samd51/mpconfigmcu.h | 3 ++- ports/samd/mcu/samd51/mpconfigmcu.mk | 29 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 2c1ea7fee257..0e5a8856556e 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -9,7 +9,8 @@ #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) #define MICROPY_PY_BUILTINS_COMPLEX (0) -#define MICROPY_PY_MATH (0) +#define MICROPY_PY_MATH (1) +#define MP_NEED_LOG2 (1) #define MICROPY_PY_CMATH (0) #define MICROPY_PY_UOS_URANDOM (1) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk index 461a0182ef01..0aedbbe28a37 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.mk +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -1 +1,30 @@ SRC_S += shared/runtime/gchelper_m3.s + +SRC_MOD += $(addprefix lib/libm/,\ + acoshf.c \ + asinfacosf.c \ + asinhf.c \ + atan2f.c \ + atanf.c \ + atanhf.c \ + ef_rem_pio2.c \ + erf_lgamma.c \ + fmodf.c \ + kf_cos.c \ + kf_rem_pio2.c \ + kf_sin.c \ + kf_tan.c \ + log1pf.c \ + math.c \ + nearbyintf.c \ + roundf.c \ + sf_cos.c \ + sf_erf.c \ + sf_frexp.c \ + sf_ldexp.c \ + sf_modf.c \ + sf_sin.c \ + sf_tan.c \ + wf_lgamma.c \ + wf_tgamma.c \ + ) From 9f4df86016d8181dc06683d528dbd85473a1dbb9 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 2 Jul 2022 16:26:17 +0200 Subject: [PATCH 1848/4290] samd/boards: Move the flash filesystem definitions to the linker files. They used to be in mpconfigmcu.h, but have to be different for different chip variants, like the SAMD51x20. --- ports/samd/boards/samd21x18a.ld | 3 +++ ports/samd/boards/samd51g19a.ld | 3 +++ ports/samd/boards/samd51j19a.ld | 3 +++ ports/samd/boards/samd51p19a.ld | 3 +++ ports/samd/mcu/samd21/mpconfigmcu.h | 2 -- ports/samd/mcu/samd51/mpconfigmcu.h | 7 +------ ports/samd/samd_flash.c | 6 ++++-- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ports/samd/boards/samd21x18a.ld b/ports/samd/boards/samd21x18a.ld index b7d59c315b64..81a84a15d7d7 100644 --- a/ports/samd/boards/samd21x18a.ld +++ b/ports/samd/boards/samd21x18a.ld @@ -13,5 +13,8 @@ MEMORY _estack = ORIGIN(RAM) + LENGTH(RAM) - 8; _sstack = _estack - 8K; +_oflash_fs = ORIGIN(FLASH) + 192K - 8K; +_sflash_fs = LENGTH(FLASH) - 192K + 8K - 1; + _sheap = _ebss; _eheap = _sstack; diff --git a/ports/samd/boards/samd51g19a.ld b/ports/samd/boards/samd51g19a.ld index e0baa9bba028..cd03320ba43d 100644 --- a/ports/samd/boards/samd51g19a.ld +++ b/ports/samd/boards/samd51g19a.ld @@ -13,5 +13,8 @@ MEMORY _estack = ORIGIN(RAM) + LENGTH(RAM) - 8; _sstack = _estack - 16K; +_oflash_fs = ORIGIN(FLASH) + 384K - 16K; +_sflash_fs = LENGTH(FLASH) - 384K + 16K - 1; + _sheap = _ebss; _eheap = _sstack; diff --git a/ports/samd/boards/samd51j19a.ld b/ports/samd/boards/samd51j19a.ld index e0baa9bba028..cd03320ba43d 100644 --- a/ports/samd/boards/samd51j19a.ld +++ b/ports/samd/boards/samd51j19a.ld @@ -13,5 +13,8 @@ MEMORY _estack = ORIGIN(RAM) + LENGTH(RAM) - 8; _sstack = _estack - 16K; +_oflash_fs = ORIGIN(FLASH) + 384K - 16K; +_sflash_fs = LENGTH(FLASH) - 384K + 16K - 1; + _sheap = _ebss; _eheap = _sstack; diff --git a/ports/samd/boards/samd51p19a.ld b/ports/samd/boards/samd51p19a.ld index e0baa9bba028..cd03320ba43d 100644 --- a/ports/samd/boards/samd51p19a.ld +++ b/ports/samd/boards/samd51p19a.ld @@ -13,5 +13,8 @@ MEMORY _estack = ORIGIN(RAM) + LENGTH(RAM) - 8; _sstack = _estack - 16K; +_oflash_fs = ORIGIN(FLASH) + 384K - 16K; +_sflash_fs = LENGTH(FLASH) - 384K + 16K - 1; + _sheap = _ebss; _eheap = _sstack; diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 9329a6eb89bc..7ee23b59b159 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -12,8 +12,6 @@ #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) -#define MICROPY_HW_FLASH_STORAGE_BASE (0x30000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0xFFFF) #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; #define MICROPY_HW_UART_TXBUF (1) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 0e5a8856556e..19193992f058 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -19,12 +19,7 @@ unsigned long trng_random_u32(void); // Due to a limitation in the TC counter for us, the ticks period is 2**29 #define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) -// MicroPython configs -// samd_flash.c flash parameters -// Build a 128k Flash storage at top. 512k-128k=384k=0x60000 -// 512*1024= 0x80000 minus 128*1024= 0x20000 = 0x60000 -#define MICROPY_HW_FLASH_STORAGE_BASE (0x60000) -#define MICROPY_HW_FLASH_STORAGE_BYTES (0x1FFFF) + #define VFS_BLOCK_SIZE_BYTES (1536) // #define MICROPY_HW_UART_TXBUF (1) diff --git a/ports/samd/samd_flash.c b/ports/samd/samd_flash.c index 2fffd614f972..6d9ee96895b0 100644 --- a/ports/samd/samd_flash.c +++ b/ports/samd/samd_flash.c @@ -53,11 +53,13 @@ typedef struct _samd_flash_obj_t { uint32_t flash_size; } samd_flash_obj_t; +extern uint8_t _oflash_fs, _sflash_fs; + // Build a Flash storage at top. STATIC samd_flash_obj_t samd_flash_obj = { .base = { &samd_flash_type }, - .flash_base = MICROPY_HW_FLASH_STORAGE_BASE, // Board specific: mpconfigboard.h - .flash_size = MICROPY_HW_FLASH_STORAGE_BYTES, // Board specific: mpconfigboard.h + .flash_base = (uint32_t)&_oflash_fs, // Get from MCU-Specific loader script. + .flash_size = (uint32_t)&_sflash_fs, // Get from MCU-Specific loader script. }; // FLASH stuff From 65f99e371d3459cdaca4ae01895e706ff93ab285 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 2 Jul 2022 16:36:11 +0200 Subject: [PATCH 1849/4290] samd/boards: Use the same linker file for all SAMD51x19 variants. --- .../mpconfigboard.mk | 2 +- .../mpconfigboard.mk | 2 +- ports/samd/boards/MINISAM_M4/mpconfigboard.mk | 2 +- .../SEEED_WIO_TERMINAL/mpconfigboard.mk | 2 +- ports/samd/boards/samd51j19a.ld | 20 ------------------- ports/samd/boards/samd51p19a.ld | 20 ------------------- .../boards/{samd51g19a.ld => samd51x19a.ld} | 0 7 files changed, 4 insertions(+), 44 deletions(-) delete mode 100644 ports/samd/boards/samd51j19a.ld delete mode 100644 ports/samd/boards/samd51p19a.ld rename ports/samd/boards/{samd51g19a.ld => samd51x19a.ld} (100%) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk index d29e2b1097b1..781faa24106d 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/mpconfigboard.mk @@ -1,6 +1,6 @@ MCU_SERIES = SAMD51 CMSIS_MCU = SAMD51J19A -LD_FILES = boards/samd51j19a.ld sections.ld +LD_FILES = boards/samd51x19a.ld sections.ld TEXT0 = 0x4000 # The ?='s allow overriding in mpconfigboard.mk. diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk index 6b0192c77b9e..da3e47589ad0 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/mpconfigboard.mk @@ -1,6 +1,6 @@ MCU_SERIES = SAMD51 CMSIS_MCU = SAMD51G19A -LD_FILES = boards/samd51g19a.ld sections.ld +LD_FILES = boards/samd51x19a.ld sections.ld TEXT0 = 0x4000 # The ?='s allow overriding in mpconfigboard.mk. diff --git a/ports/samd/boards/MINISAM_M4/mpconfigboard.mk b/ports/samd/boards/MINISAM_M4/mpconfigboard.mk index 6ed0ff552b01..73afb0210446 100644 --- a/ports/samd/boards/MINISAM_M4/mpconfigboard.mk +++ b/ports/samd/boards/MINISAM_M4/mpconfigboard.mk @@ -1,7 +1,7 @@ # https://www.minifigboards.com/mini-sam-m4/mini-sam-m4-hardware/ MCU_SERIES = SAMD51 CMSIS_MCU = SAMD51G19A -LD_FILES = boards/samd51g19a.ld sections.ld +LD_FILES = boards/samd51x19a.ld sections.ld TEXT0 = 0x4000 # The ?='s allow overriding in mpconfigboard.mk. diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk index 90fb7f2dd076..c2c4da615273 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/mpconfigboard.mk @@ -1,6 +1,6 @@ MCU_SERIES = SAMD51 CMSIS_MCU = SAMD51P19A -LD_FILES = boards/samd51p19a.ld sections.ld +LD_FILES = boards/samd51x19a.ld sections.ld TEXT0 = 0x4000 # The ?='s allow overriding in mpconfigboard.mk. diff --git a/ports/samd/boards/samd51j19a.ld b/ports/samd/boards/samd51j19a.ld deleted file mode 100644 index cd03320ba43d..000000000000 --- a/ports/samd/boards/samd51j19a.ld +++ /dev/null @@ -1,20 +0,0 @@ -/* - GNU linker script for SAMD51 -*/ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 512K - 16K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K -} - -/* Top end of the stack, with room for double-tap variable */ -_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; -_sstack = _estack - 16K; - -_oflash_fs = ORIGIN(FLASH) + 384K - 16K; -_sflash_fs = LENGTH(FLASH) - 384K + 16K - 1; - -_sheap = _ebss; -_eheap = _sstack; diff --git a/ports/samd/boards/samd51p19a.ld b/ports/samd/boards/samd51p19a.ld deleted file mode 100644 index cd03320ba43d..000000000000 --- a/ports/samd/boards/samd51p19a.ld +++ /dev/null @@ -1,20 +0,0 @@ -/* - GNU linker script for SAMD51 -*/ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 512K - 16K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K -} - -/* Top end of the stack, with room for double-tap variable */ -_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; -_sstack = _estack - 16K; - -_oflash_fs = ORIGIN(FLASH) + 384K - 16K; -_sflash_fs = LENGTH(FLASH) - 384K + 16K - 1; - -_sheap = _ebss; -_eheap = _sstack; diff --git a/ports/samd/boards/samd51g19a.ld b/ports/samd/boards/samd51x19a.ld similarity index 100% rename from ports/samd/boards/samd51g19a.ld rename to ports/samd/boards/samd51x19a.ld From 4cf527eb05d9b9a93a92ec427e719bf81a8de305 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 15 Jul 2022 22:44:23 +0200 Subject: [PATCH 1850/4290] samd/main: Initialize readline on start up. Somehow that was forgotten. --- ports/samd/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/samd/main.c b/ports/samd/main.c index 889af4a1e473..0f24e2382ee8 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -29,6 +29,7 @@ #include "py/gc.h" #include "py/mperrno.h" #include "py/stackctrl.h" +#include "shared/readline/readline.h" #include "shared/runtime/gchelper.h" #include "shared/runtime/pyexec.h" #include "shared/runtime/softtimer.h" @@ -48,6 +49,9 @@ void samd_main(void) { gc_init(&_sheap, &_eheap); mp_init(); + // Initialise sub-systems. + readline_init0(); + // Execute _boot.py to set up the filesystem. pyexec_frozen_module("_boot.py"); From 972212907ddc7f611f41d7e267ceca396f1bb4ba Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 10 Jul 2022 11:55:56 +0200 Subject: [PATCH 1851/4290] samd/mcu: Use lf2s for SAMD51 and lfs1 for SAMD21. Using lfs1 gives a smaller code, but lfs2 has more features. --- ports/samd/mcu/samd21/mpconfigmcu.h | 1 + ports/samd/mcu/samd51/mpconfigmcu.mk | 2 ++ ports/samd/modules/_boot.py | 8 +++++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 7ee23b59b159..a84b31276b42 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -6,6 +6,7 @@ // MicroPython emitters #define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_INLINE_THUMB (0) +#define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) #define MICROPY_PY_BUILTINS_COMPLEX (0) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk index 0aedbbe28a37..e83e8911ddbf 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.mk +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -1,3 +1,5 @@ +MICROPY_VFS_LFS2 ?= 1 + SRC_S += shared/runtime/gchelper_m3.s SRC_MOD += $(addprefix lib/libm/,\ diff --git a/ports/samd/modules/_boot.py b/ports/samd/modules/_boot.py index 84b02480b745..e183125f2e4b 100644 --- a/ports/samd/modules/_boot.py +++ b/ports/samd/modules/_boot.py @@ -6,11 +6,13 @@ bdev = samd.Flash() # Try to mount the filesystem, and format the flash if it doesn't exist. +fs_type = uos.VfsLfs2 if hasattr(uos, "VfsLfs2") else uos.VfsLfs1 + try: - vfs = uos.VfsLfs1(bdev) + vfs = fs_type(bdev) except: - uos.VfsLfs1.mkfs(bdev) - vfs = uos.VfsLfs1(bdev) + fs_type.mkfs(bdev) + vfs = fs_type(bdev) uos.mount(vfs, "/") gc.collect() From 366c801b3553191241e329c2f6d7f718f49af105 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 4 Oct 2022 09:17:29 +0200 Subject: [PATCH 1852/4290] samd/machine_pin: Change the printing of Pin and LED objects. It now prints lines like: Pin("D9", mode=IN, pull=PULL_UP, GPIO=PA07) or LED("LED") showing for consistency the names as given in pins.csv. For pins, the GPIO numer is printed as well for a reference. --- ports/samd/boards/make-pins.py | 2 +- ports/samd/machine_led.c | 2 +- ports/samd/machine_pin.c | 14 +++++++++++++- ports/samd/mphalport.h | 12 +++++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ports/samd/boards/make-pins.py b/ports/samd/boards/make-pins.py index 2b62ba7c5959..679e2c9d192c 100644 --- a/ports/samd/boards/make-pins.py +++ b/ports/samd/boards/make-pins.py @@ -68,7 +68,7 @@ def print_pins(self, pins_filename): if self.board_leds: pins_file.write("\nconst machine_led_obj_t machine_led_obj[] = {\n") for pin in self.board_leds: - pins_file.write(" {{&machine_pin_type}, ") + pins_file.write(" {{&machine_led_type}, ") pins_file.write(pin[0] + ', "' + pin[1]) pins_file.write('"},\n') pins_file.write("};\n") diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index 48ab869199ad..54c2cb18bc86 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -39,7 +39,7 @@ extern mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_led_obj_t *self = self_in; - mp_printf(print, "LED(%u)", self->id); + mp_printf(print, "LED(\"%s\")", self->name); } // constructor(id, ...) diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index e900174a9150..fc72c8f7569f 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -64,7 +64,19 @@ uint32_t machine_pin_open_drain_mask[4]; STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pin_obj_t *self = self_in; - mp_printf(print, "GPIO P%c%02u", "ABCD"[self->id / 32], self->id % 32); + char *mode_str; + char *pull_str[] = {"PULL_OFF", "PULL_UP", "PULL_DOWN"}; + if (GPIO_IS_OPEN_DRAIN(self->id)) { + mode_str = "OPEN_DRAIN"; + } else { + mode_str = (mp_hal_get_pin_direction(self->id) == GPIO_DIRECTION_OUT) ? "OUT" : "IN"; + } + + mp_printf(print, "Pin(\"%s\", mode=%s, pull=%s, GPIO=P%c%02u)", + self->name, + mode_str, + pull_str[mp_hal_get_pull_mode(self->id)], + "ABCD"[self->id / 32], self->id % 32); } STATIC void pin_validate_drive(bool strength) { diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index ced0d642b4ed..6f4f838cfba2 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -126,7 +126,17 @@ static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) { } static inline unsigned int mp_hal_get_pin_direction(mp_hal_pin_obj_t pin) { - return (PORT->Group[pin / 32].DIR.reg & (1 << (pin % 32))) >> (pin % 32); + return (PORT->Group[pin / 32].DIR.reg & (1 << (pin % 32))) ? + GPIO_DIRECTION_OUT : GPIO_DIRECTION_IN; +} + +static inline unsigned int mp_hal_get_pull_mode(mp_hal_pin_obj_t pin) { + bool pull_en = (PORT->Group[pin / 32].PINCFG[pin % 32].reg & PORT_PINCFG_PULLEN) != 0; + if (pull_en) { + return gpio_get_pin_level(pin) ? GPIO_PULL_UP : GPIO_PULL_DOWN; + } else { + return GPIO_PULL_OFF; + } } static inline int mp_hal_pin_read(mp_hal_pin_obj_t pin) { From f6d06b3ce0f476f9edeaeae855876c83b61d9175 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 6 Oct 2022 10:06:56 +1100 Subject: [PATCH 1853/4290] tools/verifygitlog.py: Ignore comment lines in commit messages. The "signed-off" check assumes that the Signed-off-by: line is the last, but there may me many lines of comments after this. Signed-off-by: Jim Mussared --- tools/verifygitlog.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/verifygitlog.py b/tools/verifygitlog.py index f9d98106d6f3..5d45e4a4cc61 100755 --- a/tools/verifygitlog.py +++ b/tools/verifygitlog.py @@ -102,7 +102,10 @@ def run(args): filename = args[-1] verbose("checking commit message from", filename) with open(args[-1]) as f: - lines = [line.rstrip("\r\n") for line in f] + # Remove comment lines as well as any empty lines at the end. + lines = [line.rstrip("\r\n") for line in f if not line.startswith("#")] + while not lines[-1]: + lines.pop() verify_message_body(lines, err) else: # Normal operation, pass arguments to git log for sha in git_log("%h", *args): From b8982ec5f90a5aa9d802e9d54912dc4e7ba0916a Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 5 Aug 2022 13:55:56 +1000 Subject: [PATCH 1854/4290] tools/verifygitlog.py: Add additional help for subject line issues. This check used to just show the regular expression that failed to match, but the rules are pretty subtle and hard to interpret from the regular expression alone. Add some basic checks for the main things that go wrong: - Missing capitalisation. - Missing full-stop. - Missing path. - Single-word subject. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- tools/verifygitlog.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tools/verifygitlog.py b/tools/verifygitlog.py index 5d45e4a4cc61..c237cb46beef 100755 --- a/tools/verifygitlog.py +++ b/tools/verifygitlog.py @@ -46,6 +46,23 @@ def git_log(pretty_format, *args): yield line.decode().rstrip("\r\n") +def diagnose_subject_line(subject_line, subject_line_format, err): + err.error("Subject line: " + subject_line) + if not subject_line.endswith("."): + err.error('* should end with "."') + if not re.match(r"^[^!]+: ", subject_line): + err.error('* should start with "path: "') + if re.match(r"^[^!]+: *$", subject_line): + err.error("* should contain a subject after the path.") + m = re.match(r"^[^!]+: ([a-z][^ ]*)", subject_line) + if m: + err.error('* first word of subject ("{}") should be capitalised.'.format(m.group(1))) + if re.match(r"^[^!]+: [^ ]+$", subject_line): + err.error("* subject should contain more than one word.") + err.error("* should match: " + repr(subject_line_format)) + err.error('* Example: "py/runtime: Add support for foo to bar."') + + def verify(sha, err): verbose("verify", sha) err.prefix = "commit " + sha + ": " @@ -75,9 +92,9 @@ def verify_message_body(raw_body, err): very_verbose("subject_line", subject_line) subject_line_format = r"^[^!]+: [A-Z]+.+ .+\.$" if not re.match(subject_line_format, subject_line): - err.error("Subject line should match " + repr(subject_line_format) + ": " + subject_line) + diagnose_subject_line(subject_line, subject_line_format, err) if len(subject_line) >= 73: - err.error("Subject line should be 72 or less characters: " + subject_line) + err.error("Subject line should be 72 or fewer characters: " + subject_line) # Second one divides subject and body. if len(raw_body) > 1 and raw_body[1]: @@ -90,7 +107,7 @@ def verify_message_body(raw_body, err): err.error("Message lines should be 75 or less characters: " + line) if not raw_body[-1].startswith("Signed-off-by: ") or "@" not in raw_body[-1]: - err.warning("Message should be signed-off") + err.warning('Message should be signed-off. Use "git commit -s".') def run(args): From 4fc543c829add6bb13b111b5e12103893bbc0706 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 6 Oct 2022 00:43:28 +1100 Subject: [PATCH 1855/4290] CODECONVENTIONS.md: Update pre-commit instructions. Signed-off-by: Jim Mussared --- CODECONVENTIONS.md | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md index 2daea8431f99..53b202ea371e 100644 --- a/CODECONVENTIONS.md +++ b/CODECONVENTIONS.md @@ -72,16 +72,27 @@ different formatting, and the configuration file formats are often incompatible. Automatic Pre-Commit Hooks ========================== -To have code formatting and commit message conventions automatically checked -using [pre-commit](https://pre-commit.com/), run the following commands in your -local MicroPython directory: +To have code formatting and commit message conventions automatically checked, +a configuration file is provided for the [pre-commit] +(https://pre-commit.com/) tool. +First install `pre-commit`, either from your system package manager or via +`pip`. When installing `pre-commit` via pip, it is recommended to use a +virtual environment. Other sources, such as Brew are also available, see +[the docs](https://pre-commit.com/index.html#install) for details. + +``` +$ apt install pre-commit # Ubuntu +$ pacman -Sy python-precommit # Arch Linux +$ brew install pre-commit # Brew +$ pip install pre-commit # PyPI ``` -$ pip install pre-commit -$ pre-commit install +Then inside the MicroPython repository, register the git hooks for pre-commit +by running: -$ pre-commit install --hook-type commit-msg +``` +$ pre-commit install --hook-type pre-commit --hook-type commit-msg ``` pre-commit will now automatically run during `git commit` for both code and @@ -91,6 +102,12 @@ The same formatting checks will be run by CI for any Pull Request submitted to MicroPython. Pre-commit allows you to see any failure more quickly, and in many cases will automatically correct it in your local working copy. +To unregister `pre-commit` from your MicroPython repository, run: + +``` +$ pre-commit uninstall --hook-type pre-commit --hook-type commit-msg +``` + Tips: * To skip pre-commit checks on a single commit, use `git commit -n` (for @@ -98,8 +115,6 @@ Tips: * To ignore the pre-commit message format check temporarily, start the commit message subject line with "WIP" (for "Work In Progress"). -(It is also possible to install pre-commit using Brew or other sources, see -[the docs](https://pre-commit.com/index.html#install) for details.) Python code conventions ======================= From c44b3927b8f464e1e01c07b2431e7db251e6d8c0 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 7 Oct 2022 11:06:43 +1100 Subject: [PATCH 1856/4290] py/objstr: Add a helper to set mp_obj_str_t data. Signed-off-by: Jim Mussared --- py/objstr.c | 6 ++++++ py/objstr.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/py/objstr.c b/py/objstr.c index 55e737fffc4f..8c639e735493 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2045,6 +2045,12 @@ mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_u } } +void mp_obj_str_set_data(mp_obj_str_t *str, const byte *data, size_t len) { + str->data = data; + str->len = len; + str->hash = qstr_compute_hash(data, len); +} + // This locals table is used for the following types: str, bytes, bytearray, array.array. // Each type takes a different section (start to end offset) of this table. STATIC const mp_rom_map_elem_t array_bytearray_str_bytes_locals_table[] = { diff --git a/py/objstr.h b/py/objstr.h index 6c6735bf5efa..72fe1cfef01a 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -94,6 +94,8 @@ mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte *data, siz mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in); mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); +void mp_obj_str_set_data(mp_obj_str_t *str, const byte *data, size_t len); + const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, mp_obj_t index, bool is_slice); const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction); From 0e8dfaf5384c672fc61bc10926688809db2b2ab2 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 7 Oct 2022 02:13:58 +1100 Subject: [PATCH 1857/4290] py/modsys: Add support for sys.executable. Only intended to be used on Unix and other "OS" ports. Matches CPython. This should give the absolute path to the executing binary. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared Signed-off-by: Damien George --- py/modsys.c | 10 ++++++++++ py/mpconfig.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/py/modsys.c b/py/modsys.c index 56e83029c465..35af761a08f1 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -115,6 +115,12 @@ STATIC const mp_rom_obj_tuple_t mp_sys_implementation_obj = { STATIC const MP_DEFINE_STR_OBJ(mp_sys_platform_obj, MICROPY_PY_SYS_PLATFORM); #endif +#ifdef MICROPY_PY_SYS_EXECUTABLE +// executable - the path to the micropython binary +// This object is non-const and is populated at startup in main() +MP_DEFINE_STR_OBJ(mp_sys_executable_obj, ""); +#endif + // exit([retval]): raise SystemExit, with optional argument given to the exception STATIC mp_obj_t mp_sys_exit(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { @@ -262,6 +268,10 @@ STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_getsizeof), MP_ROM_PTR(&mp_sys_getsizeof_obj) }, #endif + #if MICROPY_PY_SYS_EXECUTABLE + { MP_ROM_QSTR(MP_QSTR_executable), MP_ROM_PTR(&mp_sys_executable_obj) }, + #endif + /* * Extensions to CPython */ diff --git a/py/mpconfig.h b/py/mpconfig.h index 698d264d2e80..99fa87e5c153 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1372,6 +1372,13 @@ typedef double mp_float_t; #define MICROPY_PY_SYS_EXC_INFO (0) #endif +// Whether to provide "sys.executable", which is the absolute path to the +// micropython binary +// Intended for use on the "OS" ports (e.g. Unix) +#ifndef MICROPY_PY_SYS_EXECUTABLE +#define MICROPY_PY_SYS_EXECUTABLE (0) +#endif + // Whether to provide "sys.exit" function #ifndef MICROPY_PY_SYS_EXIT #define MICROPY_PY_SYS_EXIT (1) From 8e912a501a926f59f330f8a71c2ac1bd4af88a9e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 7 Oct 2022 02:13:58 +1100 Subject: [PATCH 1858/4290] unix: Enable sys.executable. Gives the absolute path to the unix micropython binary. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared Signed-off-by: Damien George --- ports/unix/main.c | 16 ++++++++++++++++ ports/unix/mpconfigport.h | 3 +++ tests/unix/extra_coverage.py.exp | 9 +++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ports/unix/main.c b/ports/unix/main.c index 44823ee17477..7920db02f29a 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -43,6 +43,7 @@ #include "py/builtin.h" #include "py/repl.h" #include "py/gc.h" +#include "py/objstr.h" #include "py/stackctrl.h" #include "py/mphal.h" #include "py/mpthread.h" @@ -435,6 +436,17 @@ STATIC void set_sys_argv(char *argv[], int argc, int start_arg) { } } +#if MICROPY_PY_SYS_EXECUTABLE +extern mp_obj_str_t mp_sys_executable_obj; +STATIC char executable_path[MICROPY_ALLOC_PATH_MAX]; + +STATIC void sys_set_excecutable(char *argv0) { + if (realpath(argv0, executable_path)) { + mp_obj_str_set_data(&mp_sys_executable_obj, (byte *)executable_path, strlen(executable_path)); + } +} +#endif + #ifdef _WIN32 #define PATHLIST_SEP_CHAR ';' #else @@ -598,6 +610,10 @@ MP_NOINLINE int main_(int argc, char **argv) { printf(" peak %d\n", m_get_peak_bytes_allocated()); */ + #if MICROPY_PY_SYS_EXECUTABLE + sys_set_excecutable(argv[0]); + #endif + const int NOTHING_EXECUTED = -2; int ret = NOTHING_EXECUTED; bool inspect = false; diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 08ddd21f63ba..a67d11b9e7e4 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -154,6 +154,9 @@ typedef long mp_off_t; // Don't default sys.argv because we do that in main. #define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) +// Enable sys.executable. +#define MICROPY_PY_SYS_EXECUTABLE (1) + #define MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128) // Bare-metal ports don't have stderr. Printing debug to stderr may give tests diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 29411545569d..2f5409b85b45 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -62,10 +62,11 @@ ime utime utimeq argv atexit byteorder exc_info -exit getsizeof implementation maxsize -modules path platform print_exception -ps1 ps2 stderr stdin -stdout tracebacklimit version version_info +executable exit getsizeof implementation +maxsize modules path platform +print_exception ps1 ps2 +stderr stdin stdout tracebacklimit +version version_info ementation # attrtuple (start=1, stop=2, step=3) From 17f2783e4aa4534823e2dc33e77389ad498f2d24 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 8 Oct 2022 23:08:53 +1100 Subject: [PATCH 1859/4290] all: Use += rather than = everywhere for CFLAGS/LDFLAGS/LIBS. This avoids a surprise where an = can cancel out an earlier +=. Signed-off-by: Jim Mussared --- docs/develop/porting.rst | 4 ++-- examples/embedding/Makefile | 4 ++-- examples/embedding/Makefile.upylib | 4 ++-- ports/cc3200/Makefile | 4 ++-- ports/esp8266/Makefile | 6 +++--- ports/mimxrt/Makefile | 2 +- ports/minimal/Makefile | 8 ++++---- ports/nrf/Makefile | 2 +- ports/pic16bit/Makefile | 6 +++--- ports/powerpc/Makefile | 4 ++-- ports/renesas-ra/Makefile | 2 +- ports/samd/Makefile | 6 +++--- ports/stm32/Makefile | 2 +- ports/stm32/mboot/Makefile | 6 +++--- ports/teensy/Makefile | 4 ++-- ports/windows/Makefile | 4 ++-- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/docs/develop/porting.rst b/docs/develop/porting.rst index 0511f5d276d8..74974a39e1b4 100644 --- a/docs/develop/porting.rst +++ b/docs/develop/porting.rst @@ -98,8 +98,8 @@ We also need a Makefile at this point for the port: include $(TOP)/extmod/extmod.mk # Set CFLAGS and libraries. - CFLAGS = -I. -I$(BUILD) -I$(TOP) - LIBS = -lm + CFLAGS += -I. -I$(BUILD) -I$(TOP) + LIBS += -lm # Define the required source files. SRC_C = \ diff --git a/examples/embedding/Makefile b/examples/embedding/Makefile index 7de1219b2644..edaa577f5734 100644 --- a/examples/embedding/Makefile +++ b/examples/embedding/Makefile @@ -1,6 +1,6 @@ MPTOP = ../.. -CFLAGS = -std=c99 -I. -I$(MPTOP) -DNO_QSTR -LDFLAGS = -L./build +CFLAGS += -std=c99 -I. -I$(MPTOP) -DNO_QSTR +LDFLAGS += -L./build hello-embed: hello-embed.o -lmicropython diff --git a/examples/embedding/Makefile.upylib b/examples/embedding/Makefile.upylib index a8e2b91d5610..99ce94b7add0 100644 --- a/examples/embedding/Makefile.upylib +++ b/examples/embedding/Makefile.upylib @@ -20,7 +20,7 @@ INC += -I$(BUILD) # compiler settings CWARN = -Wall -Werror CWARN += -Wpointer-arith -Wuninitialized -CFLAGS = $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) +CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) # Some systems (eg MacOS) need -fno-common so that mp_state_ctx is placed in the BSS. CFLAGS += -fno-common @@ -70,7 +70,7 @@ else # Use gcc syntax for map file LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref endif -LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) +LDFLAGS += $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) ifeq ($(MICROPY_FORCE_32BIT),1) # Note: you may need to install i386 versions of dependency packages, diff --git a/ports/cc3200/Makefile b/ports/cc3200/Makefile index b880ad646bb3..6c034c58637e 100644 --- a/ports/cc3200/Makefile +++ b/ports/cc3200/Makefile @@ -20,7 +20,7 @@ include ../../py/mkenv.mk CROSS_COMPILE ?= arm-none-eabi- CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=cortex-m4 -msoft-float -mfloat-abi=soft -fsingle-precision-constant -Wdouble-promotion -CFLAGS = -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os +CFLAGS += -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access CFLAGS += -Iboards/$(BOARD) CFLAGS += $(CFLAGS_MOD) @@ -28,7 +28,7 @@ CFLAGS += $(CFLAGS_MOD) # Workaround gcc 12.1 bug. CFLAGS += -Wno-array-bounds -LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map +LDFLAGS += -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map FLASH_SIZE_WIPY = 2M FLASH_SIZE_LAUNCHXL = 1M diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index c027f690fb10..6002dc5e5ab5 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -57,12 +57,12 @@ CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \ -Wl,-EL -mlongcalls -mtext-section-literals -mforce-l32 \ -DLWIP_OPEN_SRC -CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ +CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ $(CFLAGS_XTENSA) $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) -I$(BOARD_DIR) LD_FILES ?= boards/esp8266_2m.ld -LDFLAGS = -nostdlib -T $(LD_FILES) -Map=$(@:.elf=.map) --cref -LIBS = -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 $(LDFLAGS_MOD) +LDFLAGS += -nostdlib -T $(LD_FILES) -Map=$(@:.elf=.map) --cref +LIBS += -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 $(LDFLAGS_MOD) LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LIBS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 6a18879ac583..8493c47a715c 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -393,7 +393,7 @@ CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) # Linker Flags # ============================================================================= -LDFLAGS = \ +LDFLAGS += \ --cref \ --gc-sections \ --print-memory-usage \ diff --git a/ports/minimal/Makefile b/ports/minimal/Makefile index 0e875cc2491a..2e85bd912e41 100644 --- a/ports/minimal/Makefile +++ b/ports/minimal/Makefile @@ -23,12 +23,12 @@ ifeq ($(CROSS), 1) DFU = $(TOP)/tools/dfu.py PYDFU = $(TOP)/tools/pydfu.py CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mcpu=cortex-m4 -msoft-float -fsingle-precision-constant -Wdouble-promotion -Wfloat-conversion -CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT) -LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref --gc-sections +CFLAGS += $(INC) -Wall -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT) +LDFLAGS += -nostdlib -T stm32f405.ld -Map=$@.map --cref --gc-sections else LD = gcc -CFLAGS = $(INC) -Wall -Werror -Wdouble-promotion -Wfloat-conversion -std=c99 $(COPT) -LDFLAGS = -Wl,-Map=$@.map,--cref -Wl,--gc-sections +CFLAGS += $(INC) -Wall -Werror -Wdouble-promotion -Wfloat-conversion -std=c99 $(COPT) +LDFLAGS += -Wl,-Map=$@.map,--cref -Wl,--gc-sections endif CSUPEROPT = -Os # save some code space diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index bc295cac808e..38d0bd7fce72 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -129,7 +129,7 @@ CFLAGS += -fno-strict-aliasing CFLAGS += -Iboards/$(BOARD) CFLAGS += -DNRF5_HAL_H='<$(MCU_VARIANT)_hal.h>' -LDFLAGS = $(CFLAGS) +LDFLAGS += $(CFLAGS) LDFLAGS += -Xlinker -Map=$(@:.elf=.map) LDFLAGS += -mthumb -mabi=aapcs $(addprefix -T,$(LD_FILES)) -L boards/ diff --git a/ports/pic16bit/Makefile b/ports/pic16bit/Makefile index 392196cbc260..d2c8df4707e0 100644 --- a/ports/pic16bit/Makefile +++ b/ports/pic16bit/Makefile @@ -21,7 +21,7 @@ INC += -I$(XC16)/include INC += -I$(XC16)/support/$(PARTFAMILY)/h CFLAGS_PIC16BIT = -mcpu=$(PART) -mlarge-code -CFLAGS = $(INC) -Wall -Werror -std=gnu99 -nostdlib $(CFLAGS_PIC16BIT) $(COPT) +CFLAGS += $(INC) -Wall -Werror -std=gnu99 -nostdlib $(CFLAGS_PIC16BIT) $(COPT) #Debugging/Optimization ifeq ($(DEBUG), 1) @@ -30,8 +30,8 @@ else CFLAGS += -O1 -DNDEBUG endif -LDFLAGS = --heap=0 -nostdlib -T $(XC16)/support/$(PARTFAMILY)/gld/p$(PART).gld -Map=$@.map --cref -p$(PART) -LIBS = -L$(XC16)/lib -L$(XC16)/lib/$(PARTFAMILY) -lc -lm -lpic30 +LDFLAGS += --heap=0 -nostdlib -T $(XC16)/support/$(PARTFAMILY)/gld/p$(PART).gld -Map=$@.map --cref -p$(PART) +LIBS += -L$(XC16)/lib -L$(XC16)/lib/$(PARTFAMILY) -lc -lm -lpic30 SRC_C = \ main.c \ diff --git a/ports/powerpc/Makefile b/ports/powerpc/Makefile index 0986fd13eba0..8fc9b11166e6 100644 --- a/ports/powerpc/Makefile +++ b/ports/powerpc/Makefile @@ -21,14 +21,14 @@ INC += -I. INC += -I$(TOP) INC += -I$(BUILD) -CFLAGS = $(INC) -g -Wall -Wdouble-promotion -Wfloat-conversion -std=c99 $(COPT) +CFLAGS += $(INC) -g -Wall -Wdouble-promotion -Wfloat-conversion -std=c99 $(COPT) CFLAGS += -mno-string -mno-multiple -mno-vsx -mno-altivec -nostdlib CFLAGS += -mlittle-endian -mstrict-align -msoft-float CFLAGS += -Os CFLAGS += -fdata-sections -ffunction-sections -fno-stack-protector -ffreestanding CFLAGS += -U_FORTIFY_SOURCE -LDFLAGS = -N -T powerpc.lds -nostdlib +LDFLAGS += -N -T powerpc.lds -nostdlib LIBS = diff --git a/ports/renesas-ra/Makefile b/ports/renesas-ra/Makefile index 92d8be0692af..6c37aeb1e198 100644 --- a/ports/renesas-ra/Makefile +++ b/ports/renesas-ra/Makefile @@ -139,7 +139,7 @@ CFLAGS += -fsingle-precision-constant endif endif -LDFLAGS = -nostdlib -L $(LD_DIR) $(addprefix -T,$(LD_FILES)) -Map=$(@:.elf=.map) --cref +LDFLAGS += -nostdlib -L $(LD_DIR) $(addprefix -T,$(LD_FILES)) -Map=$(@:.elf=.map) --cref LDFLAGS += --defsym=_estack_reserve=8 LIBS += "$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)" diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 5ff00f21f926..512820088a68 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -58,15 +58,15 @@ GEN_PINS_HDR = $(BUILD)/pins.h CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion +CFLAGS += $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += -DMPCONFIG_MCU_H='' -LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref +LDFLAGS += -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref LDFLAGS += $(LDFLAGS_MOD) -LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Tune for Debugging or Optimization CFLAGS += -g # always include debug info in the ELF diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 4b4a9f0ce380..903730982ea0 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -99,7 +99,7 @@ CFLAGS += -fsingle-precision-constant endif endif -LDFLAGS = -nostdlib -L $(LD_DIR) $(addprefix -T,$(LD_FILES)) -Wl,-Map=$(@:.elf=.map) -Wl,--cref +LDFLAGS += -nostdlib -L $(LD_DIR) $(addprefix -T,$(LD_FILES)) -Wl,-Map=$(@:.elf=.map) -Wl,--cref LDFLAGS += -Wl,--defsym=_estack_reserve=8 LIBS += "$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)" diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index 4c903b4ff603..176092f8c0a5 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -58,7 +58,7 @@ INC += -I../$(USBDEV_DIR)/core/inc -I../$(USBDEV_DIR)/class/inc # the compiler does not optimise these functions in terms of themselves. CFLAGS_BUILTIN ?= -ffreestanding -fno-builtin -fno-lto -CFLAGS = $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += -D$(CMSIS_MCU) CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) CFLAGS += $(COPT) @@ -75,8 +75,8 @@ CFLAGS += -DMICROPY_HW_STM32WB_FLASH_SYNCRONISATION=0 CFLAGS += -DBOOTLOADER_DFU_USB_VID=$(BOOTLOADER_DFU_USB_VID) -DBOOTLOADER_DFU_USB_PID=$(BOOTLOADER_DFU_USB_PID) MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld -LDFLAGS = -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref -LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +LDFLAGS += -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref +LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Remove uncalled code from the final image. CFLAGS += -fdata-sections -ffunction-sections diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index d7161fcbbc3b..52fc812ad4e7 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -75,8 +75,8 @@ INC += -I$(TOP)/ports/stm32 INC += -I$(BUILD) INC += -Icore -CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) -LDFLAGS = -nostdlib -T mk20dx256.ld -msoft-float -mfloat-abi=soft +CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) +LDFLAGS += -nostdlib -T mk20dx256.ld -msoft-float -mfloat-abi=soft ifeq ($(USE_ARDUINO_TOOLCHAIN),1) diff --git a/ports/windows/Makefile b/ports/windows/Makefile index 1e793800f804..64334bc18b27 100644 --- a/ports/windows/Makefile +++ b/ports/windows/Makefile @@ -32,8 +32,8 @@ INC += -I$(BUILD) INC += -I$(VARIANT_DIR) # compiler settings -CFLAGS = $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) -LDFLAGS = $(LDFLAGS_MOD) -lm -lbcrypt $(LDFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) +LDFLAGS += -lm -lbcrypt $(LDFLAGS_EXTRA) # Debugging/Optimization ifdef DEBUG From 67d05ed02b26b6ba2dcc638f2deed937a08417d7 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 8 Oct 2022 23:23:52 +1100 Subject: [PATCH 1860/4290] ports: Make generated pin.c handling more consistent across ports. Signed-off-by: Jim Mussared --- ports/mimxrt/Makefile | 7 +++--- ports/nrf/Makefile | 26 ++++++++++---------- ports/samd/Makefile | 5 +++- ports/stm32/Makefile | 57 +++++++++++++++++++++---------------------- ports/teensy/Makefile | 26 ++++++++++---------- 5 files changed, 61 insertions(+), 60 deletions(-) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 8493c47a715c..6095f5fd2335 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -15,7 +15,7 @@ MICROPY_VFS_LFS2 ?= 1 MICROPY_VFS_FAT ?= 1 # qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h +QSTR_DEFS += qstrdefsport.h QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h # Generation scripts @@ -49,7 +49,6 @@ GEN_FLEXRAM_CONFIG_SRC = $(BUILD)/flexram_config.s GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h GEN_PINS_AF_PY = $(BUILD)/pins_af.py GEN_PINS_HDR = $(HEADER_BUILD)/pins.h -GEN_PINS_QSTR = $(BUILD)/pins_qstr.h GEN_PINS_SRC = $(BUILD)/pins_gen.c # ============================================================================= @@ -435,7 +434,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) -OBJ += $(BUILD)/pins_gen.o +OBJ += $(GEN_PINS_SRC:.c=.o) # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" $(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces @@ -486,7 +485,7 @@ $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: $(BOARD_PINS) $(MAKE_PINS) $(AF_FILE) $(PR --iomux $(abspath $(TOP)/$(MCU_DIR)/drivers/fsl_iomuxc.h) \ --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC) -$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c +$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC) $(call compile_c) include $(TOP)/py/mkrules.mk diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 38d0bd7fce72..9e0354194dd6 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -45,7 +45,7 @@ endif -include boards/$(BOARD)/modules/boardmodules.mk # qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h +QSTR_DEFS = qstrdefsport.h $(GEN_PINS_QSTR) # MicroPython feature configurations ifeq ($(DEBUG), 0) @@ -106,6 +106,16 @@ endif NRF_DEFINES += -D$(MCU_SUB_VARIANT_UPPER) NRF_DEFINES += -DCONFIG_GPIO_AS_PINRESET +MAKE_PINS = boards/make-pins.py +BOARD_PINS = boards/$(BOARD)/pins.csv +AF_FILE = $(MCU_VARIANT)_af.csv +PREFIX_FILE = boards/$(MCU_VARIANT)_prefix.c +GEN_PINS_SRC = $(BUILD)/pins_gen.c +GEN_PINS_HDR = $(HEADER_BUILD)/pins.h +GEN_PINS_QSTR = $(BUILD)/pins_qstr.h +GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h +GEN_PINS_AF_PY = $(BUILD)/pins_af.py + CFLAGS_CORTEX_M = -mthumb -mabi=aapcs -fsingle-precision-constant -Wdouble-promotion CFLAGS_MCU_m33 = $(CFLAGS_CORTEX_M) -mcpu=cortex-m33 -march=armv8-m.main+dsp -mcmse -mfpu=fpv5-sp-d16 -mfloat-abi=hard @@ -354,7 +364,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX_HAL:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SYSTEM_C_SRC:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o)) -OBJ += $(BUILD)/pins_gen.o +OBJ += $(GEN_PINS_SRC:.c=.o) $(BUILD)/$(OOFATFS_DIR)/ff.o: COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os @@ -528,19 +538,9 @@ $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qst $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC) -$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c +$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC) $(call compile_c) -MAKE_PINS = boards/make-pins.py -BOARD_PINS = boards/$(BOARD)/pins.csv -AF_FILE = $(MCU_VARIANT)_af.csv -PREFIX_FILE = boards/$(MCU_VARIANT)_prefix.c -GEN_PINS_SRC = $(BUILD)/pins_gen.c -GEN_PINS_HDR = $(HEADER_BUILD)/pins.h -GEN_PINS_QSTR = $(BUILD)/pins_qstr.h -GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h -GEN_PINS_AF_PY = $(BUILD)/pins_af.py - ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 512820088a68..735d25bf27cb 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -106,7 +106,6 @@ SRC_C += \ mphalport.c \ pendsv.c \ pin_af.c \ - $(BUILD)/pins.c \ samd_flash.c \ samd_isr.c \ samd_soc.c \ @@ -170,6 +169,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) +OBJ += $(GEN_PINS_SRC:.c=.o) ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_MODULE_FROZEN_MPY @@ -205,4 +205,7 @@ $(GEN_PINS_SRC) $(GEN_PINS_HDR): $(BOARD_PINS) | $(HEADER_BUILD) $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --pins $(GEN_PINS_SRC) --inc $(GEN_PINS_HDR) +$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC) + $(call compile_c) + include $(TOP)/py/mkrules.mk diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 903730982ea0..403b68b240a1 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -15,7 +15,7 @@ include ../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk # Files that are generated and needed before the QSTR build. -QSTR_GENERATED_HEADERS = $(BUILD)/pins_qstr.h $(BUILD)/modstm_qstr.h +QSTR_GENERATED_HEADERS = $(GEN_PINS_QSTR) $(GEN_STMCONST_QSTR) # qstr definitions (must come before including py.mk) QSTR_DEFS += qstrdefsport.h $(QSTR_GENERATED_HEADERS) @@ -57,6 +57,31 @@ OPENOCD_CONFIG ?= boards/openocd_stm32f4.cfg include stm32.mk +PLLVALUES = boards/pllvalues.py +MAKE_PINS = boards/make-pins.py +BOARD_PINS = $(BOARD_DIR)/pins.csv +PREFIX_FILE = boards/stm32f4xx_prefix.c +GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c +GEN_PINS_HDR = $(HEADER_BUILD)/pins.h +GEN_PINS_QSTR = $(BUILD)/pins_qstr.h +GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h +GEN_PINS_AF_DEFS = $(HEADER_BUILD)/pins_af_defs.h +GEN_PINS_AF_PY = $(BUILD)/pins_af.py + +INSERT_USB_IDS = $(TOP)/tools/insert-usb-ids.py +FILE2H = $(TOP)/tools/file2h.py + +USB_IDS_FILE = mpconfigboard_common.h +CDCINF_TEMPLATE = pybcdc.inf_template +GEN_CDCINF_FILE = $(HEADER_BUILD)/pybcdc.inf +GEN_CDCINF_HEADER = $(HEADER_BUILD)/pybcdc_inf.h + +GEN_PLLFREQTABLE_HDR = $(HEADER_BUILD)/pllfreqtable.h +GEN_STMCONST_HDR = $(HEADER_BUILD)/modstm_const.h +GEN_STMCONST_QSTR = $(BUILD)/modstm_qstr.h +GEN_STMCONST_MPZ = $(HEADER_BUILD)/modstm_mpz.h +CMSIS_MCU_HDR = $(STM32LIB_CMSIS_ABS)/Include/$(CMSIS_MCU_LOWER).h + # Select the cross compile prefix CROSS_COMPILE ?= arm-none-eabi- @@ -537,8 +562,7 @@ OBJ += $(addprefix $(BUILD)/, $(HAL_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(USBDEV_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) -OBJ += $(BUILD)/pins_$(BOARD).o +OBJ += $(GEN_PINS_SRC:.c=.o) # This file contains performance critical functions so turn up the optimisation # level. It doesn't add much to the code size and improves performance a bit. @@ -689,25 +713,6 @@ $(BUILD)/firmware.hex: $(BUILD)/firmware.elf $(BUILD)/firmware.elf: $(OBJ) $(call GENERATE_ELF,$@,$^) -PLLVALUES = boards/pllvalues.py -MAKE_PINS = boards/make-pins.py -BOARD_PINS = $(BOARD_DIR)/pins.csv -PREFIX_FILE = boards/stm32f4xx_prefix.c -GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c -GEN_PINS_HDR = $(HEADER_BUILD)/pins.h -GEN_PINS_QSTR = $(BUILD)/pins_qstr.h -GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h -GEN_PINS_AF_DEFS = $(HEADER_BUILD)/pins_af_defs.h -GEN_PINS_AF_PY = $(BUILD)/pins_af.py - -INSERT_USB_IDS = $(TOP)/tools/insert-usb-ids.py -FILE2H = $(TOP)/tools/file2h.py - -USB_IDS_FILE = mpconfigboard_common.h -CDCINF_TEMPLATE = pybcdc.inf_template -GEN_CDCINF_FILE = $(HEADER_BUILD)/pybcdc.inf -GEN_CDCINF_HEADER = $(HEADER_BUILD)/pybcdc_inf.h - # List of sources for qstr extraction SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SRC_MOD) $(SHARED_SRC_C) $(EXTMOD_SRC_C) # Append any auto-generated sources that are needed by sources listed in @@ -738,15 +743,9 @@ $(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(HEADER_ --af-defs $(GEN_PINS_AF_DEFS) --af-defs-cmp-strings \ --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC) -$(BUILD)/pins_$(BOARD).o: $(BUILD)/pins_$(BOARD).c +$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC) $(call compile_c) -GEN_PLLFREQTABLE_HDR = $(HEADER_BUILD)/pllfreqtable.h -GEN_STMCONST_HDR = $(HEADER_BUILD)/modstm_const.h -GEN_STMCONST_QSTR = $(BUILD)/modstm_qstr.h -GEN_STMCONST_MPZ = $(HEADER_BUILD)/modstm_mpz.h -CMSIS_MCU_HDR = $(STM32LIB_CMSIS_ABS)/Include/$(CMSIS_MCU_LOWER).h - modmachine.c: $(GEN_PLLFREQTABLE_HDR) $(GEN_PLLFREQTABLE_HDR): $(PLLVALUES) | $(HEADER_BUILD) $(ECHO) "GEN $@" diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index 52fc812ad4e7..876ddf1c1da3 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -1,7 +1,7 @@ include ../../py/mkenv.mk # qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h +QSTR_DEFS = qstrdefsport.h $(GEN_PINS_QSTR) # MicroPython feature configurations MICROPY_ROM_TEXT_COMPRESSION ?= 1 @@ -66,6 +66,16 @@ $(info Using toolchain from PATH) CROSS_COMPILE ?= arm-none-eabi- endif +MAKE_PINS = make-pins.py +BOARD_PINS = teensy_pins.csv +AF_FILE = mk20dx256_af.csv +PREFIX_FILE = mk20dx256_prefix.c +GEN_PINS_SRC = $(BUILD)/pins_gen.c +GEN_PINS_HDR = $(HEADER_BUILD)/pins.h +GEN_PINS_QSTR = $(BUILD)/pins_qstr.h +GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h +GEN_PINS_AF_PY = $(BUILD)/pins_af.py + CFLAGS_TEENSY = -DF_CPU=96000000 -DUSB_SERIAL -D__MK20DX256__ CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mcpu=cortex-m4 -msoft-float -mfloat-abi=soft -fsingle-precision-constant -Wdouble-promotion $(CFLAGS_TEENSY) @@ -157,7 +167,7 @@ SRC_TEENSY = $(addprefix core/,\ OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(STM_SRC_C:.c=.o) $(SRC_TEENSY:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) OBJ += $(BUILD)/shared/runtime/gchelper_m3.o -OBJ += $(BUILD)/pins_gen.o +OBJ += $(GEN_PINS_SRC:.c=.o) all: hex hex: $(BUILD)/micropython.hex @@ -195,16 +205,6 @@ $(BUILD)/%.hex: $(BUILD)/%.elf $(ECHO) "HEX $<" $(Q)$(OBJCOPY) -O ihex -R .eeprom "$<" "$@" -MAKE_PINS = make-pins.py -BOARD_PINS = teensy_pins.csv -AF_FILE = mk20dx256_af.csv -PREFIX_FILE = mk20dx256_prefix.c -GEN_PINS_SRC = $(BUILD)/pins_gen.c -GEN_PINS_HDR = $(HEADER_BUILD)/pins.h -GEN_PINS_QSTR = $(BUILD)/pins_qstr.h -GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h -GEN_PINS_AF_PY = $(BUILD)/pins_af.py - # List of sources for qstr extraction SRC_QSTR += $(SRC_C) $(STM_SRC_C) $(SHARED_SRC_C) # Append any auto-generated sources that are needed by sources listed in @@ -224,7 +224,7 @@ $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qst $(ECHO) "Create $@" $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC) -$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c +$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC) $(call compile_c) $(BUILD)/%.pp: $(BUILD)/%.c From 3cc6decfc4d6b459014940ae01f90d4f1fae0da6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 8 Oct 2022 23:28:24 +1100 Subject: [PATCH 1861/4290] py/py.mk: Make user-C-module handling self-contained in py.mk. Removes the need for the port to add anything to OBJS or SRC_QSTR. Also makes it possible for user-C-modules to differentiate between code that should be processed for QSTR vs other files (e.g. helpers and libraries). Signed-off-by: Jim Mussared --- docs/develop/cmodules.rst | 14 +++++++++++--- ports/samd/Makefile | 3 ++- ports/stm32/Makefile | 3 ++- py/py.mk | 34 ++++++++++++++++++++++++++++------ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/docs/develop/cmodules.rst b/docs/develop/cmodules.rst index 143057f7f1e0..1b3ba04da4af 100644 --- a/docs/develop/cmodules.rst +++ b/docs/develop/cmodules.rst @@ -49,9 +49,17 @@ A MicroPython user C module is a directory with the following files: in your ``micropython.mk`` to a local make variable, eg ``EXAMPLE_MOD_DIR := $(USERMOD_DIR)`` - Your ``micropython.mk`` must add your modules source files relative to your - expanded copy of ``$(USERMOD_DIR)`` to ``SRC_USERMOD``, eg - ``SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c`` + Your ``micropython.mk`` must add your modules source files to the + ``SRC_USERMOD_C`` or ``SRC_USERMOD_LIB_C`` variables. The former will be + processed for ``MP_QSTR_`` and ``MP_REGISTER_MODULE`` definitions, the latter + will not (e.g. helpers and library code that isn't MicroPython-specific). + These paths should include your expaned copy of ``$(USERMOD_DIR)``, e.g.:: + + SRC_USERMOD_C += $(EXAMPLE_MOD_DIR)/modexample.c + SRC_USERMOD_LIB_C += $(EXAMPLE_MOD_DIR)/utils/algorithm.c + + Similarly, use ``SRC_USERMOD_CXX`` and ``SRC_USERMOD_LIB_CXX`` for C++ + source files. If you have custom compiler options (like ``-I`` to add directories to search for header files), these should be added to ``CFLAGS_USERMOD`` for C code diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 735d25bf27cb..9386a8dacc5d 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -81,7 +81,8 @@ endif # Flags for optional C++ source code CXXFLAGS += $(filter-out -std=c99,$(CFLAGS)) CXXFLAGS += $(CXXFLAGS_MOD) -ifneq ($(SRC_CXX)$(SRC_MOD_CXX),) +# TODO make this common -- shouldn't be using these "private" vars from py.mk +ifneq ($(SRC_CXX)$(SRC_USERMOD_CXX)$(SRC_USERMOD_LIB_CXX),) LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)" LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 403b68b240a1..4e594d19ff6b 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -157,7 +157,8 @@ endif # Flags for optional C++ source code CXXFLAGS += $(filter-out -Wmissing-prototypes -Wold-style-definition -std=gnu99,$(CFLAGS)) CXXFLAGS += $(CXXFLAGS_MOD) -ifneq ($(SRC_CXX)$(SRC_MOD_CXX),) +# TODO make this common -- shouldn't be using these "private" vars from py.mk +ifneq ($(SRC_CXX)$(SRC_USERMOD_CXX)$(SRC_USERMOD_LIB_CXX),) LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)" LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif diff --git a/py/py.mk b/py/py.mk index 8aac460b478a..ec69ca42d971 100644 --- a/py/py.mk +++ b/py/py.mk @@ -32,22 +32,44 @@ endif ifneq ($(USER_C_MODULES),) # pre-define USERMOD variables as expanded so that variables are immediate # expanded as they're added to them -SRC_USERMOD := + +# C/C++ files that are included in the QSTR/module build +SRC_USERMOD_C := SRC_USERMOD_CXX := +# Other C/C++ files (e.g. libraries or helpers) +SRC_USERMOD_LIB_C := +SRC_USERMOD_LIB_CXX := +# Optionally set flags CFLAGS_USERMOD := CXXFLAGS_USERMOD := LDFLAGS_USERMOD := + +# Backwards compatibility with older user c modules that set SRC_USERMOD +# added to SRC_USERMOD_C below +SRC_USERMOD := + $(foreach module, $(wildcard $(USER_C_MODULES)/*/micropython.mk), \ $(eval USERMOD_DIR = $(patsubst %/,%,$(dir $(module))))\ $(info Including User C Module from $(USERMOD_DIR))\ $(eval include $(module))\ ) -SRC_MOD += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD)) -SRC_MOD_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_CXX)) -CFLAGS_MOD += $(CFLAGS_USERMOD) -CXXFLAGS_MOD += $(CXXFLAGS_USERMOD) -LDFLAGS_MOD += $(LDFLAGS_USERMOD) +SRC_USERMOD_C += $(SRC_USERMOD) + +SRC_USERMOD_PATHFIX_C += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD_C)) +SRC_USERMOD_PATHFIX_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_CXX)) +SRC_USERMOD_PATHFIX_LIB_C += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD_LIB_C)) +SRC_USERMOD_PATHFIX_LIB_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_LIB_CXX)) + +CFLAGS += $(CFLAGS_USERMOD) +CXXFLAGS += $(CXXFLAGS_USERMOD) +LDFLAGS += $(LDFLAGS_USERMOD) + +SRC_QSTR += $(SRC_USERMOD_PATHFIX_C) $(SRC_USERMOD_PATHFIX_CXX) +PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_C:.c=.o)) +PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_CXX:.cpp=.o)) +PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_LIB_C:.c=.o)) +PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_LIB_CXX:.cpp=.o)) endif # py object files From 065af04a4e86aa5bdbdedb89140241e5d0030ffb Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 8 Oct 2022 23:38:18 +1100 Subject: [PATCH 1862/4290] unix/Makefile: Don't use _MOD variable names. This conflicts with the triple-usage of these variables for user-C-modules and extmod source. For CFLAGS_MOD, just use CFLAGS directly. For SRC, use SRC_C directly as the relevant files are all guarded by the preprocessor anyway. Signed-off-by: Jim Mussared --- ports/unix/Makefile | 46 ++++++++++++++++++++++----------------------- ports/unix/modjni.c | 10 +++++----- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 709cc79853d5..e234621346fa 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -110,27 +110,25 @@ ifeq ($(MICROPY_FORCE_32BIT),1) # starting with linux-libc-dev:i386 ifeq ($(MICROPY_PY_FFI),1) ifeq ($(UNAME_S),Linux) -CFLAGS_MOD += -I/usr/include/i686-linux-gnu +CFLAGS += -I/usr/include/i686-linux-gnu endif endif endif ifeq ($(MICROPY_USE_READLINE),1) INC += -I$(TOP)/shared/readline -CFLAGS_MOD += -DMICROPY_USE_READLINE=1 +CFLAGS += -DMICROPY_USE_READLINE=1 SHARED_SRC_C_EXTRA += readline/readline.c endif ifeq ($(MICROPY_PY_TERMIOS),1) -CFLAGS_MOD += -DMICROPY_PY_TERMIOS=1 -SRC_MOD += modtermios.c +CFLAGS += -DMICROPY_PY_TERMIOS=1 endif ifeq ($(MICROPY_PY_SOCKET),1) -CFLAGS_MOD += -DMICROPY_PY_SOCKET=1 -SRC_MOD += modusocket.c +CFLAGS += -DMICROPY_PY_SOCKET=1 endif ifeq ($(MICROPY_PY_THREAD),1) -CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 -LDFLAGS_MOD += $(LIBPTHREAD) +CFLAGS += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 +LDFLAGS += $(LIBPTHREAD) endif ifeq ($(MICROPY_PY_USSL),1) @@ -139,7 +137,7 @@ GIT_SUBMODULES += lib/axtls endif ifeq ($(MICROPY_SSL_MBEDTLS),1) GIT_SUBMODULES += lib/mbedtls -CFLAGS_MOD += -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' +CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' endif endif @@ -163,8 +161,8 @@ MICROPY_BLUETOOTH_BTSTACK ?= 1 endif endif -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH=1 -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 +CFLAGS += -DMICROPY_PY_BLUETOOTH=1 +CFLAGS += -DMICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) @@ -192,7 +190,7 @@ else # NimBLE is enabled. GIT_SUBMODULES += lib/mynewt-nimble -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 +CFLAGS += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 include $(TOP)/extmod/nimble/nimble.mk endif @@ -205,31 +203,29 @@ ifeq ($(MICROPY_STANDALONE),1) # Build libffi from source. GIT_SUBMODULES += lib/libffi DEPLIBS += libffi -LIBFFI_CFLAGS_MOD := -I$(shell ls -1d $(BUILD)/lib/libffi/out/lib/libffi-*/include) +LIBFFI_CFLAGS := -I$(shell ls -1d $(BUILD)/lib/libffi/out/lib/libffi-*/include) ifeq ($(MICROPY_FORCE_32BIT),1) - LIBFFI_LDFLAGS_MOD = $(BUILD)/lib/libffi/out/lib32/libffi.a + LIBFFI_LDFLAGS = $(BUILD)/lib/libffi/out/lib32/libffi.a else - LIBFFI_LDFLAGS_MOD = $(BUILD)/lib/libffi/out/lib/libffi.a + LIBFFI_LDFLAGS = $(BUILD)/lib/libffi/out/lib/libffi.a endif else # Use system version of libffi. -LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi) -LIBFFI_LDFLAGS_MOD := $(shell pkg-config --libs libffi) +LIBFFI_CFLAGS := $(shell pkg-config --cflags libffi) +LIBFFI_LDFLAGS := $(shell pkg-config --libs libffi) endif ifeq ($(UNAME_S),Linux) -LIBFFI_LDFLAGS_MOD += -ldl +LIBFFI_LDFLAGS += -ldl endif -CFLAGS_MOD += $(LIBFFI_CFLAGS_MOD) -DMICROPY_PY_FFI=1 -LDFLAGS_MOD += $(LIBFFI_LDFLAGS_MOD) -SRC_MOD += modffi.c +CFLAGS += $(LIBFFI_CFLAGS) -DMICROPY_PY_FFI=1 +LDFLAGS += $(LIBFFI_LDFLAGS) endif ifeq ($(MICROPY_PY_JNI),1) # Path for 64-bit OpenJDK, should be adjusted for other JDKs -CFLAGS_MOD += -I/usr/lib/jvm/java-7-openjdk-amd64/include -DMICROPY_PY_JNI=1 -SRC_MOD += modjni.c +CFLAGS += -I/usr/lib/jvm/java-7-openjdk-amd64/include -DMICROPY_PY_JNI=1 endif # source files @@ -250,6 +246,10 @@ SRC_C += \ mpbtstackport_usb.c \ mpnimbleport.c \ $(SRC_MOD) \ + modtermios.c \ + modusocket.c \ + modffi.c \ + modjni.c \ $(wildcard $(VARIANT_DIR)/*.c) SHARED_SRC_C += $(addprefix shared/,\ diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 5988876f888a..10622f588f8a 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -24,19 +24,19 @@ * THE SOFTWARE. */ +#include "py/runtime.h" +#include "py/binary.h" + +#if MICROPY_PY_JNI + #include #include #include #include #include -#include "py/runtime.h" -#include "py/binary.h" - #include -#if MICROPY_PY_JNI - #define JJ(call, ...) (*env)->call(env, __VA_ARGS__) #define JJ1(call) (*env)->call(env) #define MATCH(s, static) (!strncmp(s, static, sizeof(static) - 1)) From 87011f63530f55411843622af8b1bc2dbf98a6f7 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 8 Oct 2022 23:47:57 +1100 Subject: [PATCH 1863/4290] extmod/extmod.mk: Make extmod.mk handle GIT_SUBMODULES. This applies to nimble, btstack, axtls, mbedtls, lwip. Rather than having the ports individually manage GIT_SUBMODULES for these components, make extmod.mk append them when the relevant feature is enabled. Signed-off-by: Jim Mussared --- extmod/btstack/btstack.mk | 1 + extmod/extmod.mk | 4 +++- extmod/nimble/nimble.mk | 2 ++ ports/mimxrt/Makefile | 2 +- ports/stm32/Makefile | 4 +--- ports/unix/Makefile | 5 +---- tools/ci.sh | 6 ++++-- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/extmod/btstack/btstack.mk b/extmod/btstack/btstack.mk index 7ecc23000317..14b8d08bf1d3 100644 --- a/extmod/btstack/btstack.mk +++ b/extmod/btstack/btstack.mk @@ -2,6 +2,7 @@ ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) +GIT_SUBMODULES += lib/btstack MICROPY_BLUETOOTH_BTSTACK_USB ?= 0 BTSTACK_EXTMOD_DIR = extmod/btstack diff --git a/extmod/extmod.mk b/extmod/extmod.mk index ae3e45bd55cb..bd897199178a 100644 --- a/extmod/extmod.mk +++ b/extmod/extmod.mk @@ -100,6 +100,7 @@ CFLAGS_MOD += -DMICROPY_PY_USSL=1 ifeq ($(MICROPY_SSL_AXTLS),1) CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include AXTLS_DIR = lib/axtls +GIT_SUBMODULES += $(AXTLS_DIR) $(BUILD)/$(AXTLS_DIR)/%.o: CFLAGS += -Wno-all -Wno-unused-parameter -Wno-uninitialized -Wno-sign-compare -Wno-old-style-definition -Dmp_stream_errno=errno $(AXTLS_DEFS_EXTRA) SRC_MOD += $(addprefix $(AXTLS_DIR)/,\ ssl/asn1.c \ @@ -118,7 +119,7 @@ SRC_MOD += $(addprefix $(AXTLS_DIR)/,\ ) else ifeq ($(MICROPY_SSL_MBEDTLS),1) MBEDTLS_DIR = lib/mbedtls -CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include +GIT_SUBMODULES += $(MBEDTLS_DIR) SRC_MOD += lib/mbedtls_errors/mp_mbedtls_errors.c SRC_MOD += $(addprefix $(MBEDTLS_DIR)/library/,\ aes.c \ @@ -199,6 +200,7 @@ endif # lwip ifeq ($(MICROPY_PY_LWIP),1) +GIT_SUBMODULES += lib/lwip # A port should add an include path where lwipopts.h can be found (eg extmod/lwip-include) LWIP_DIR = lib/lwip/src INC += -I$(TOP)/$(LWIP_DIR)/include diff --git a/extmod/nimble/nimble.mk b/extmod/nimble/nimble.mk index 806630074eb8..e825261eeadc 100644 --- a/extmod/nimble/nimble.mk +++ b/extmod/nimble/nimble.mk @@ -17,6 +17,8 @@ CFLAGS_MOD += -DMICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY=$(MICROPY_BLUETOOTH_NIMBL ifeq ($(MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY),0) +GIT_SUBMODULES += lib/mynewt-nimble + # On all ports where we provide the full implementation (i.e. not just # bindings like on ESP32), then we don't need to use the ringbuffer. In this # case, all NimBLE events are run by the MicroPython scheduler. On Unix, the diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 6095f5fd2335..b8b08cb011f3 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -7,7 +7,7 @@ BOARD_DIR ?= boards/$(BOARD) BUILD ?= build-$(BOARD) PORT ?= /dev/ttyACM0 CROSS_COMPILE ?= arm-none-eabi- -GIT_SUBMODULES += lib/tinyusb lib/nxp_driver lib/lwip lib/mbedtls +GIT_SUBMODULES += lib/tinyusb lib/nxp_driver # MicroPython feature configurations FROZEN_MANIFEST ?= boards/manifest.py diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 4e594d19ff6b..8b503112aef7 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -35,7 +35,7 @@ MBOOT_TEXT0_ADDR ?= 0x08000000 include $(TOP)/py/py.mk include $(TOP)/extmod/extmod.mk -GIT_SUBMODULES += lib/libhydrogen lib/lwip lib/mbedtls lib/stm32lib +GIT_SUBMODULES += lib/libhydrogen lib/stm32lib query-variants: $(ECHO) "VARIANTS:" $(BOARD_VARIANTS) @@ -531,14 +531,12 @@ endif endif ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) -GIT_SUBMODULES += lib/mynewt-nimble CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 include $(TOP)/extmod/nimble/nimble.mk SRC_C += mpnimbleport.c endif ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) -GIT_SUBMODULES += lib/btstack MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 include $(TOP)/extmod/btstack/btstack.mk SRC_C += mpbtstackport.c diff --git a/ports/unix/Makefile b/ports/unix/Makefile index e234621346fa..facdab2e045d 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -133,10 +133,9 @@ endif ifeq ($(MICROPY_PY_USSL),1) ifeq ($(MICROPY_SSL_AXTLS),1) -GIT_SUBMODULES += lib/axtls + endif ifeq ($(MICROPY_SSL_MBEDTLS),1) -GIT_SUBMODULES += lib/mbedtls CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' endif endif @@ -182,14 +181,12 @@ endif endif # BTstack is enabled. -GIT_SUBMODULES += lib/btstack include $(TOP)/extmod/btstack/btstack.mk SRC_BTSTACK += lib/btstack/platform/embedded/btstack_run_loop_embedded.c else # NimBLE is enabled. -GIT_SUBMODULES += lib/mynewt-nimble CFLAGS += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 include $(TOP)/extmod/nimble/nimble.mk diff --git a/tools/ci.sh b/tools/ci.sh index 9963f7796cc0..86fd44fdfbae 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -198,8 +198,9 @@ function ci_mimxrt_setup { function ci_mimxrt_build { make ${MAKEOPTS} -C mpy-cross - make ${MAKEOPTS} -C ports/mimxrt submodules + make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1020_EVK submodules make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1020_EVK + make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 submodules make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 } @@ -310,6 +311,7 @@ function ci_stm32_setup { function ci_stm32_pyb_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/stm32 MICROPY_PY_NETWORK_WIZNET5K=5200 submodules + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2 submodules git submodule update --init lib/btstack git submodule update --init lib/mynewt-nimble make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 USER_C_MODULES=../../examples/usercmodule @@ -326,7 +328,7 @@ function ci_stm32_pyb_build { function ci_stm32_nucleo_build { make ${MAKEOPTS} -C mpy-cross - make ${MAKEOPTS} -C ports/stm32 submodules + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI submodules git submodule update --init lib/mynewt-nimble # Test building various MCU families, some with additional options. From d6d87225585a9494093d791c807bce652e4c82d8 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 8 Oct 2022 23:59:08 +1100 Subject: [PATCH 1864/4290] extmod: Make extmod.mk self-contained. This makes it so that all a port needs to do is set the relevant variables and "include extmod.mk" and doesn't need to worry about adding anything to OBJ, CFLAGS, SRC_QSTR, etc. Make all extmod variables (src, flags, etc) private to extmod.mk. Also move common/shared, extmod-related fragments (e.g. wiznet, cyw43, bluetooth) into extmod.mk. Now that SRC_MOD, CFLAGS_MOD, CXXFLAGS_MOD are unused by both extmod.mk (and user-C-modules in a previous commit), remove all uses of them from port makefiles. Signed-off-by: Jim Mussared --- extmod/btstack/btstack.mk | 38 +++-- extmod/extmod.mk | 208 ++++++++++++++++++--------- extmod/network_wiznet5k.c | 5 +- extmod/nimble/nimble.mk | 14 +- mpy-cross/Makefile | 2 +- ports/cc3200/Makefile | 1 - ports/esp8266/Makefile | 13 +- ports/mimxrt/Makefile | 17 +-- ports/minimal/Makefile | 13 +- ports/nrf/Makefile | 11 +- ports/renesas-ra/Makefile | 18 +-- ports/samd/Makefile | 23 ++- ports/samd/mcu/samd51/mpconfigmcu.mk | 2 +- ports/stm32/Makefile | 67 +-------- ports/stm32/mboot/Makefile | 2 +- ports/stm32/mpconfigport.h | 8 ++ ports/teensy/Makefile | 5 +- ports/unix/Makefile | 48 +------ ports/unix/mpconfigport.h | 8 ++ ports/windows/Makefile | 13 +- py/py.mk | 2 +- 21 files changed, 235 insertions(+), 283 deletions(-) diff --git a/extmod/btstack/btstack.mk b/extmod/btstack/btstack.mk index 14b8d08bf1d3..ca95931562cd 100644 --- a/extmod/btstack/btstack.mk +++ b/extmod/btstack/btstack.mk @@ -3,17 +3,19 @@ ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) GIT_SUBMODULES += lib/btstack + MICROPY_BLUETOOTH_BTSTACK_USB ?= 0 +MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 BTSTACK_EXTMOD_DIR = extmod/btstack -EXTMOD_SRC_C += extmod/btstack/modbluetooth_btstack.c +SRC_EXTMOD_C += $(BTSTACK_EXTMOD_DIR)/modbluetooth_btstack.c INC += -I$(TOP)/$(BTSTACK_EXTMOD_DIR) -CFLAGS_MOD += -DMICROPY_BLUETOOTH_BTSTACK=1 -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1 -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1 +CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_BTSTACK=1 +CFLAGS_EXTMOD += -DMICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1 +CFLAGS_EXTMOD += -DMICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1 BTSTACK_DIR = $(TOP)/lib/btstack @@ -28,44 +30,50 @@ INC += -I$(BTSTACK_DIR)/3rd-party/bluedroid/encoder/include INC += -I$(BTSTACK_DIR)/3rd-party/md5 INC += -I$(BTSTACK_DIR)/3rd-party/yxml -SRC_BTSTACK = \ +SRC_BTSTACK_C = \ $(addprefix lib/btstack/src/, $(SRC_FILES)) \ $(addprefix lib/btstack/src/ble/, $(filter-out %_tlv.c, $(SRC_BLE_FILES))) \ ifeq ($(MICROPY_BLUETOOTH_BTSTACK_USB),1) ifeq ($(MICROPY_BLUETOOTH_BTSTACK_H4),1) - $(error Cannot specifiy both MICROPY_BLUETOOTH_BTSTACK_USB and MICROPY_BLUETOOTH_BTSTACK_H4) + $(error Cannot enable both MICROPY_BLUETOOTH_BTSTACK_USB and MICROPY_BLUETOOTH_BTSTACK_H4) +endif +endif + +ifneq ($(MICROPY_BLUETOOTH_BTSTACK_USB),1) +ifneq ($(MICROPY_BLUETOOTH_BTSTACK_H4),1) + $(error Must enable one of MICROPY_BLUETOOTH_BTSTACK_USB or MICROPY_BLUETOOTH_BTSTACK_H4) endif endif ifeq ($(MICROPY_BLUETOOTH_BTSTACK_USB),1) -SRC_BTSTACK += \ +SRC_BTSTACK_C += \ lib/btstack/platform/libusb/hci_transport_h2_libusb.c -CFLAGS_MOD += -DMICROPY_BLUETOOTH_BTSTACK_USB=1 +CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_BTSTACK_USB=1 -CFLAGS += $(shell pkg-config libusb-1.0 --cflags) -LDFLAGS += $(shell pkg-config libusb-1.0 --libs) +CFLAGS_THIRDPARTY += $(shell pkg-config libusb-1.0 --cflags) +LDFLAGS_THIRDPARTY += $(shell pkg-config libusb-1.0 --libs) endif ifeq ($(MICROPY_BLUETOOTH_BTSTACK_H4),1) -SRC_BTSTACK += \ +SRC_BTSTACK_C += \ lib/btstack/src/hci_transport_h4.c \ lib/btstack/chipset/zephyr/btstack_chipset_zephyr.c -EXTMOD_SRC_C += \ +SRC_BTSTACK_C += \ extmod/btstack/btstack_hci_uart.c \ -CFLAGS_MOD += -DMICROPY_BLUETOOTH_BTSTACK_H4=1 +CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_BTSTACK_H4=1 endif ifeq ($(MICROPY_BLUETOOTH_BTSTACK_ENABLE_CLASSIC),1) include $(BTSTACK_DIR)/src/classic/Makefile.inc -SRC_BTSTACK += \ +SRC_BTSTACK_C += \ $(addprefix lib/btstack/src/classic/, $(SRC_CLASSIC_FILES)) endif -LIB_SRC_C += $(SRC_BTSTACK) +SRC_THIRDPARTY_C += $(SRC_BTSTACK_C) # Suppress some warnings. BTSTACK_WARNING_CFLAGS = -Wno-old-style-definition -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-fallthrough diff --git a/extmod/extmod.mk b/extmod/extmod.mk index bd897199178a..3b10fc857c80 100644 --- a/extmod/extmod.mk +++ b/extmod/extmod.mk @@ -1,55 +1,66 @@ # This makefile fragment adds the source code files for the core extmod modules # and provides rules to build 3rd-party components for extmod modules. -PY_EXTMOD_O_BASENAME = \ - extmod/moduasyncio.o \ - extmod/moductypes.o \ - extmod/modujson.o \ - extmod/moduos.o \ - extmod/modure.o \ - extmod/moduzlib.o \ - extmod/moduheapq.o \ - extmod/modutimeq.o \ - extmod/moduhashlib.o \ - extmod/moducryptolib.o \ - extmod/modubinascii.o \ - extmod/virtpin.o \ - extmod/machine_bitstream.o \ - extmod/machine_mem.o \ - extmod/machine_pinbase.o \ - extmod/machine_signal.o \ - extmod/machine_pulse.o \ - extmod/machine_pwm.o \ - extmod/machine_i2c.o \ - extmod/machine_spi.o \ - extmod/modbluetooth.o \ - extmod/modlwip.o \ - extmod/modussl_axtls.o \ - extmod/modussl_mbedtls.o \ - extmod/moduplatform.o\ - extmod/modurandom.o \ - extmod/moduselect.o \ - extmod/moduwebsocket.o \ - extmod/modwebrepl.o \ - extmod/modframebuf.o \ - extmod/vfs.o \ - extmod/vfs_blockdev.o \ - extmod/vfs_reader.o \ - extmod/vfs_posix.o \ - extmod/vfs_posix_file.o \ - extmod/vfs_fat.o \ - extmod/vfs_fat_diskio.o \ - extmod/vfs_fat_file.o \ - extmod/vfs_lfs.o \ - extmod/utime_mphal.o \ - extmod/uos_dupterm.o \ - shared/libc/abort_.o \ - shared/libc/printf.o \ +SRC_EXTMOD_C += \ + extmod/machine_bitstream.c \ + extmod/machine_i2c.c \ + extmod/machine_mem.c \ + extmod/machine_pinbase.c \ + extmod/machine_pulse.c \ + extmod/machine_pwm.c \ + extmod/machine_signal.c \ + extmod/machine_spi.c \ + extmod/modbluetooth.c \ + extmod/modbtree.c \ + extmod/modframebuf.c \ + extmod/modlwip.c \ + extmod/modnetwork.c \ + extmod/modonewire.c \ + extmod/moduasyncio.c \ + extmod/modubinascii.c \ + extmod/moducryptolib.c \ + extmod/moductypes.c \ + extmod/moduhashlib.c \ + extmod/moduheapq.c \ + extmod/modujson.c \ + extmod/moduos.c \ + extmod/moduplatform.c\ + extmod/modurandom.c \ + extmod/modure.c \ + extmod/moduselect.c \ + extmod/modusocket.c \ + extmod/modussl_axtls.c \ + extmod/modussl_mbedtls.c \ + extmod/modutimeq.c \ + extmod/moduwebsocket.c \ + extmod/moduzlib.c \ + extmod/modwebrepl.c \ + extmod/network_cyw43.c \ + extmod/network_ninaw10.c \ + extmod/network_wiznet5k.c \ + extmod/uos_dupterm.c \ + extmod/utime_mphal.c \ + extmod/vfs.c \ + extmod/vfs_blockdev.c \ + extmod/vfs_fat.c \ + extmod/vfs_fat_diskio.c \ + extmod/vfs_fat_file.c \ + extmod/vfs_lfs.c \ + extmod/vfs_posix.c \ + extmod/vfs_posix_file.c \ + extmod/vfs_reader.c \ + extmod/virtpin.c \ + shared/libc/abort_.c \ + shared/libc/printf.c \ -PY_EXTMOD_O = $(addprefix $(BUILD)/, $(PY_EXTMOD_O_BASENAME)) +SRC_THIRDPARTY_C += \ -PY_O += $(PY_EXTMOD_O) -SRC_QSTR += $(PY_EXTMOD_O_BASENAME:.o=.c) +PY_O += $(addprefix $(BUILD)/, $(SRC_EXTMOD_C:.c=.o)) +PY_O += $(addprefix $(BUILD)/, $(SRC_THIRDPARTY_C:.c=.o)) +SRC_QSTR += $(SRC_EXTMOD_C) + +CFLAGS += $(CFLAGS_EXTMOD) $(CFLAGS_THIRDPARTY) +LDFLAGS += $(LDFLAGS_EXTMOD) $(LDFLAGS_THIRDPARTY) ################################################################################ # VFS FAT FS @@ -57,11 +68,11 @@ SRC_QSTR += $(PY_EXTMOD_O_BASENAME:.o=.c) OOFATFS_DIR = lib/oofatfs # this sets the config file for FatFs -CFLAGS_MOD += -DFFCONF_H=\"$(OOFATFS_DIR)/ffconf.h\" +CFLAGS_THIRDPARTY += -DFFCONF_H=\"$(OOFATFS_DIR)/ffconf.h\" ifeq ($(MICROPY_VFS_FAT),1) -CFLAGS_MOD += -DMICROPY_VFS_FAT=1 -SRC_MOD += $(addprefix $(OOFATFS_DIR)/,\ +CFLAGS_EXTMOD += -DMICROPY_VFS_FAT=1 +SRC_THIRDPARTY_C += $(addprefix $(OOFATFS_DIR)/,\ ff.c \ ffunicode.c \ ) @@ -73,18 +84,18 @@ endif LITTLEFS_DIR = lib/littlefs ifeq ($(MICROPY_VFS_LFS1),1) -CFLAGS_MOD += -DMICROPY_VFS_LFS1=1 -CFLAGS_MOD += -DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT -SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\ +CFLAGS_EXTMOD += -DMICROPY_VFS_LFS1=1 +CFLAGS_THIRDPARTY += -DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT +SRC_THIRDPARTY_C += $(addprefix $(LITTLEFS_DIR)/,\ lfs1.c \ lfs1_util.c \ ) endif ifeq ($(MICROPY_VFS_LFS2),1) -CFLAGS_MOD += -DMICROPY_VFS_LFS2=1 -CFLAGS_MOD += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT -SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\ +CFLAGS_EXTMOD += -DMICROPY_VFS_LFS2=1 +CFLAGS_THIRDPARTY += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT +SRC_THIRDPARTY_C += $(addprefix $(LITTLEFS_DIR)/,\ lfs2.c \ lfs2_util.c \ ) @@ -96,13 +107,13 @@ endif # ussl ifeq ($(MICROPY_PY_USSL),1) -CFLAGS_MOD += -DMICROPY_PY_USSL=1 +CFLAGS_EXTMOD += -DMICROPY_PY_USSL=1 ifeq ($(MICROPY_SSL_AXTLS),1) -CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include AXTLS_DIR = lib/axtls GIT_SUBMODULES += $(AXTLS_DIR) +CFLAGS_EXTMOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include $(BUILD)/$(AXTLS_DIR)/%.o: CFLAGS += -Wno-all -Wno-unused-parameter -Wno-uninitialized -Wno-sign-compare -Wno-old-style-definition -Dmp_stream_errno=errno $(AXTLS_DEFS_EXTRA) -SRC_MOD += $(addprefix $(AXTLS_DIR)/,\ +SRC_THIRDPARTY_C += $(addprefix $(AXTLS_DIR)/,\ ssl/asn1.c \ ssl/loader.c \ ssl/tls1.c \ @@ -120,8 +131,9 @@ SRC_MOD += $(addprefix $(AXTLS_DIR)/,\ else ifeq ($(MICROPY_SSL_MBEDTLS),1) MBEDTLS_DIR = lib/mbedtls GIT_SUBMODULES += $(MBEDTLS_DIR) -SRC_MOD += lib/mbedtls_errors/mp_mbedtls_errors.c -SRC_MOD += $(addprefix $(MBEDTLS_DIR)/library/,\ +CFLAGS_EXTMOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include +SRC_THIRDPARTY_C += lib/mbedtls_errors/mp_mbedtls_errors.c +SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\ aes.c \ aesni.c \ arc4.c \ @@ -204,10 +216,10 @@ GIT_SUBMODULES += lib/lwip # A port should add an include path where lwipopts.h can be found (eg extmod/lwip-include) LWIP_DIR = lib/lwip/src INC += -I$(TOP)/$(LWIP_DIR)/include -CFLAGS_MOD += -DMICROPY_PY_LWIP=1 -$(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS_MOD += -Wno-address -SRC_MOD += shared/netutils/netutils.c -SRC_MOD += $(addprefix $(LWIP_DIR)/,\ +CFLAGS_EXTMOD += -DMICROPY_PY_LWIP=1 +$(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS += -Wno-address +SRC_THIRDPARTY_C += shared/netutils/netutils.c +SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\ apps/mdns/mdns.c \ core/def.c \ core/dns.c \ @@ -246,8 +258,8 @@ SRC_MOD += $(addprefix $(LWIP_DIR)/,\ netif/ethernet.c \ ) ifeq ($(MICROPY_PY_LWIP_SLIP),1) -CFLAGS_MOD += -DMICROPY_PY_LWIP_SLIP=1 -SRC_MOD += $(LWIP_DIR)/netif/slipif.c +CFLAGS_EXTMOD += -DMICROPY_PY_LWIP_SLIP=1 +SRC_THIRDPARTY_C += $(LWIP_DIR)/netif/slipif.c endif endif @@ -258,8 +270,7 @@ ifeq ($(MICROPY_PY_BTREE),1) BTREE_DIR = lib/berkeley-db-1.xx BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error=printf -Dabort=abort_ "-Dvirt_fd_t=void*" $(BTREE_DEFS_EXTRA) INC += -I$(TOP)/$(BTREE_DIR)/PORT/include -SRC_MOD += extmod/modbtree.c -SRC_MOD += $(addprefix $(BTREE_DIR)/,\ +SRC_THIRDPARTY_C += $(addprefix $(BTREE_DIR)/,\ btree/bt_close.c \ btree/bt_conv.c \ btree/bt_debug.c \ @@ -275,10 +286,67 @@ SRC_MOD += $(addprefix $(BTREE_DIR)/,\ btree/bt_utils.c \ mpool/mpool.c \ ) -CFLAGS_MOD += -DMICROPY_PY_BTREE=1 +CFLAGS_EXTMOD += -DMICROPY_PY_BTREE=1 # we need to suppress certain warnings to get berkeley-db to compile cleanly # and we have separate BTREE_DEFS so the definitions don't interfere with other source code $(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS) $(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS) endif +################################################################################ +# networking + +ifeq ($(MICROPY_PY_NETWORK_CYW43),1) +CFLAGS_EXTMOD += -DMICROPY_PY_NETWORK_CYW43=1 +DRIVERS_SRC_C += drivers/cyw43/cyw43_ctrl.c drivers/cyw43/cyw43_lwip.c +LIBS += $(TOP)/drivers/cyw43/libcyw43.a +endif + +ifneq ($(MICROPY_PY_NETWORK_WIZNET5K),) +ifneq ($(MICROPY_PY_NETWORK_WIZNET5K),0) +WIZNET5K_DIR=lib/wiznet5k +GIT_SUBMODULES += lib/wiznet5k +INC += -I$(TOP)/$(WIZNET5K_DIR) -I$(TOP)/$(WIZNET5K_DIR)/Ethernet +CFLAGS += -DMICROPY_PY_NETWORK_WIZNET5K=$(MICROPY_PY_NETWORK_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_NETWORK_WIZNET5K) +CFLAGS_THIRDPARTY += -DWIZCHIP_PREFIXED_EXPORTS=1 +ifeq ($(MICROPY_PY_LWIP),1) +# When using MACRAW mode (with lwIP), maximum buffer space must be used for the raw socket +CFLAGS_THIRDPARTY += -DWIZCHIP_USE_MAX_BUFFER +endif +SRC_THIRDPARTY_C += $(addprefix $(WIZNET5K_DIR)/,\ + Ethernet/W$(MICROPY_PY_NETWORK_WIZNET5K)/w$(MICROPY_PY_NETWORK_WIZNET5K).c \ + Ethernet/wizchip_conf.c \ + Ethernet/socket.c \ + Internet/DNS/dns.c \ + Internet/DHCP/dhcp.c \ + ) +endif +endif + +################################################################################ +# bluetooth + +ifeq ($(MICROPY_PY_BLUETOOTH),1) +CFLAGS_EXTMOD += -DMICROPY_PY_BLUETOOTH=1 + +ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) +ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) +$(error Cannot enable both NimBLE and BTstack at the same time) +endif +endif + +ifneq ($(MICROPY_BLUETOOTH_NIMBLE),1) +ifneq ($(MICROPY_BLUETOOTH_BTSTACK),1) +$(error Must enable one of MICROPY_BLUETOOTH_NIMBLE or MICROPY_BLUETOOTH_BTSTACK) +endif +endif + +ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) +include $(TOP)/extmod/nimble/nimble.mk +endif + +ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) +include $(TOP)/extmod/btstack/btstack.mk +endif + +endif diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index af2014508127..78cbff4ce2df 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -33,6 +33,9 @@ #include "py/stream.h" #include "py/mperrno.h" #include "py/mphal.h" + +#if MICROPY_PY_NETWORK_WIZNET5K + #include "shared/netutils/netutils.h" #include "extmod/modnetwork.h" #include "extmod/machine_spi.h" @@ -40,8 +43,6 @@ #include "modmachine.h" #include "drivers/bus/spi.h" -#if MICROPY_PY_NETWORK_WIZNET5K - #include "lib/wiznet5k/Ethernet/wizchip_conf.h" // The WIZNET5K module supports two usage modes: diff --git a/extmod/nimble/nimble.mk b/extmod/nimble/nimble.mk index e825261eeadc..fc1709f0e50a 100644 --- a/extmod/nimble/nimble.mk +++ b/extmod/nimble/nimble.mk @@ -5,15 +5,15 @@ ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) EXTMOD_DIR = extmod NIMBLE_EXTMOD_DIR = $(EXTMOD_DIR)/nimble -EXTMOD_SRC_C += $(NIMBLE_EXTMOD_DIR)/modbluetooth_nimble.c +SRC_EXTMOD_C += $(NIMBLE_EXTMOD_DIR)/modbluetooth_nimble.c -CFLAGS_MOD += -DMICROPY_BLUETOOTH_NIMBLE=1 +CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_NIMBLE=1 # Use NimBLE from the submodule in lib/mynewt-nimble by default, # allowing a port to use their own system version (e.g. ESP32). MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY ?= 0 -CFLAGS_MOD += -DMICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY=$(MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY) +CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY=$(MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY) ifeq ($(MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY),0) @@ -24,16 +24,16 @@ GIT_SUBMODULES += lib/mynewt-nimble # case, all NimBLE events are run by the MicroPython scheduler. On Unix, the # scheduler is also responsible for polling the UART, whereas on STM32 the # UART is also polled by the RX IRQ. -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1 +CFLAGS_EXTMOD += -DMICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1 # Without the ringbuffer, and with the full implementation, we can also # enable pairing and bonding. This requires both synchronous events and # some customisation of the key store. -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1 +CFLAGS_EXTMOD += -DMICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1 NIMBLE_LIB_DIR = lib/mynewt-nimble -LIB_SRC_C += $(addprefix $(NIMBLE_LIB_DIR)/, \ +SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \ $(addprefix ext/tinycrypt/src/, \ aes_encrypt.c \ cmac_mode.c \ @@ -98,7 +98,7 @@ LIB_SRC_C += $(addprefix $(NIMBLE_LIB_DIR)/, \ ) # nimble/host/store/ram/src/ble_store_ram.c \ -EXTMOD_SRC_C += $(addprefix $(NIMBLE_EXTMOD_DIR)/, \ +SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_EXTMOD_DIR)/, \ nimble/nimble_npl_os.c \ hal/hal_uart.c \ ) diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile index 4b6e03df8e84..7a71577e2bb1 100644 --- a/mpy-cross/Makefile +++ b/mpy-cross/Makefile @@ -19,7 +19,7 @@ INC += -I$(TOP) # compiler settings CWARN = -Wall -Werror CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith -CFLAGS += $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) +CFLAGS += $(INC) $(CWARN) -std=gnu99 $(COPT) $(CFLAGS_EXTRA) CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables # Debugging/Optimization diff --git a/ports/cc3200/Makefile b/ports/cc3200/Makefile index 6c034c58637e..61af0bfd9844 100644 --- a/ports/cc3200/Makefile +++ b/ports/cc3200/Makefile @@ -23,7 +23,6 @@ CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=co CFLAGS += -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access CFLAGS += -Iboards/$(BOARD) -CFLAGS += $(CFLAGS_MOD) # Workaround gcc 12.1 bug. CFLAGS += -Wno-array-bounds diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 6002dc5e5ab5..168d1d9f6ab6 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -58,11 +58,11 @@ CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \ -DLWIP_OPEN_SRC CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ - $(CFLAGS_XTENSA) $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) -I$(BOARD_DIR) + $(CFLAGS_XTENSA) $(COPT) $(CFLAGS_EXTRA) -I$(BOARD_DIR) LD_FILES ?= boards/esp8266_2m.ld LDFLAGS += -nostdlib -T $(LD_FILES) -Map=$(@:.elf=.map) --cref -LIBS += -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 $(LDFLAGS_MOD) +LIBS += -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LIBS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc @@ -107,11 +107,6 @@ SRC_C = \ posix_helpers.c \ hspi.c \ $(wildcard $(BOARD_DIR)/*.c) \ - $(SRC_MOD) - -EXTMOD_SRC_C = $(addprefix extmod/,\ - modonewire.c \ - ) LIB_SRC_C = $(addprefix lib/,\ libm/math.c \ @@ -163,17 +158,15 @@ DRIVERS_SRC_C = $(addprefix drivers/,\ SRC_S = \ gchelper.s \ -OBJ = OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) -OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(EXTMOD_SRC_C) $(SHARED_SRC_C) $(DRIVERS_SRC_C) +SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) # Append any auto-generated sources that are needed by sources listed in SRC_QSTR SRC_QSTR_AUTO_DEPS += diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index b8b08cb011f3..640864e58295 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -150,10 +150,6 @@ SRC_C += \ drivers/bus/softspi.c \ drivers/dht/dht.c \ eth.c \ - extmod/modnetwork.c \ - extmod/modonewire.c \ - extmod/modusocket.c \ - extmod/uos_dupterm.c \ fatfs_port.c \ hal/pwm_backport.c \ led.c \ @@ -257,16 +253,6 @@ SRC_S += shared/runtime/gchelper_m3.s \ # QSTR Sources # ============================================================================= -# All settings for Ethernet support are controller by the value of MICROPY_PY_LWIP -ifeq ($(MICROPY_PY_LWIP),1) -SRC_QSTR += \ - extmod/modlwip.c \ - extmod/modnetwork.c \ - extmod/modusocket.c \ - extmod/moduwebsocket.c \ - network_lan.c -endif - # List of sources for qstr extraction SRC_QSTR += \ extmod/modonewire.c \ @@ -386,7 +372,7 @@ CFLAGS += \ -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' endif -CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(CFLAGS_EXTRA) # ============================================================================= # Linker Flags @@ -433,7 +419,6 @@ OBJ += $(LIBM_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) OBJ += $(GEN_PINS_SRC:.c=.o) # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" diff --git a/ports/minimal/Makefile b/ports/minimal/Makefile index 2e85bd912e41..1a20412e0da5 100644 --- a/ports/minimal/Makefile +++ b/ports/minimal/Makefile @@ -44,11 +44,6 @@ endif # Flags for optional C++ source code CXXFLAGS += $(filter-out -std=c99,$(CFLAGS)) -CXXFLAGS += $(CXXFLAGS_MOD) - -# Flags for user C modules -CFLAGS += $(CFLAGS_MOD) -LDFLAGS += $(LDFLAGS_MOD) LIBS = @@ -65,14 +60,10 @@ ifeq ($(CROSS), 1) SRC_C += shared/libc/string0.c endif -SRC_C += $(SRC_MOD) - -SRC_CXX += $(SRC_MOD_CXX) - SRC_QSTR += shared/readline/readline.c shared/runtime/pyexec.c -SRC_QSTR += $(SRC_MOD) $(SRC_MOD_CXX) -OBJ += $(PY_CORE_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(PY_CORE_O) +OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) ifeq ($(CROSS), 1) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 9e0354194dd6..4128404da4a8 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -132,9 +132,8 @@ CFLAGS += -ffunction-sections -fdata-sections LDFLAGS += -Wl,--gc-sections endif - CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) -CFLAGS += $(INC) -Wall -Werror -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Werror -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_EXTRA) CFLAGS += -fno-strict-aliasing CFLAGS += -Iboards/$(BOARD) CFLAGS += -DNRF5_HAL_H='<$(MCU_VARIANT)_hal.h>' @@ -357,8 +356,8 @@ SRC_C += \ LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc -OBJ += $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) +OBJ += $(PY_O) +OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX_HAL:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) @@ -515,11 +514,11 @@ flash: deploy $(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ) $(ECHO) "LINK $@" - $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LDFLAGS_MOD) $(LIBS) + $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(Q)$(SIZE) $@ # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_LIB) $(DRIVERS_SRC_C) $(SRC_BOARD_MODULES) $(SRC_MOD) +SRC_QSTR += $(SRC_C) $(SRC_LIB) $(DRIVERS_SRC_C) $(SRC_BOARD_MODULES) # Append any auto-generated sources that are needed by sources listed in # SRC_QSTR diff --git a/ports/renesas-ra/Makefile b/ports/renesas-ra/Makefile index 6c37aeb1e198..2b0358b27076 100644 --- a/ports/renesas-ra/Makefile +++ b/ports/renesas-ra/Makefile @@ -121,7 +121,7 @@ CFLAGS_MCU_RA4W1 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 CFLAGS_MCU_RA6M1 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 CFLAGS_MCU_RA6M2 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_EXTRA) #CFLAGS += -D$(CMSIS_MCU) CFLAGS += $(CFLAGS_MCU_$(CMSIS_MCU)) CFLAGS += $(COPT) @@ -161,8 +161,9 @@ endif # Flags for optional C++ source code CXXFLAGS += $(filter-out -Wmissing-prototypes -Wold-style-definition -std=gnu99,$(CFLAGS)) -CXXFLAGS += $(CXXFLAGS_MOD) -ifneq ($(SRC_CXX)$(SRC_MOD_CXX),) + +# TODO make this common -- shouldn't be using these "private" vars from py.mk +ifneq ($(SRC_CXX)$(SRC_USERMOD_CXX)$(SRC_USERMOD_LIB_CXX),) LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)" LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))" endif @@ -279,10 +280,6 @@ ifeq ($(MICROPY_FLOAT_IMPL),double) $(LIBM_O): CFLAGS := $(filter-out -Wdouble-promotion -Wfloat-conversion, $(CFLAGS)) endif -EXTMOD_SRC_C += $(addprefix extmod/,\ - modonewire.c \ - ) - DRIVERS_SRC_C += $(addprefix drivers/,\ bus/softspi.c \ bus/softqspi.c \ @@ -334,9 +331,6 @@ SRC_C += $(addprefix $(BOARD_DIR)/ra_gen/,\ vector_data.c \ ) -SRC_CXX += \ - $(SRC_MOD_CXX) - SRC_O += \ $(STARTUP_FILE) \ $(SYSTEM_FILE) @@ -408,13 +402,11 @@ OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ += $(LIBM_O) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(HAL_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_O)) -OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) OBJ += $(BUILD)/pins_$(BOARD).o # This file contains performance critical functions so turn up the optimisation @@ -514,7 +506,7 @@ GEN_PINS_AF_PY = $(BUILD)/pins_af.py FILE2H = $(TOP)/tools/file2h.py # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SRC_MOD) $(SHARED_SRC_C) $(EXTMOD_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) # Making OBJ use an order-only depenedency on the generated pins.h file # has the side effect of making the pins.h file before we actually compile diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 9386a8dacc5d..2c5f6a1ab221 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -60,11 +60,10 @@ CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS += $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ -CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(CFLAGS_EXTRA) CFLAGS += -DMPCONFIG_MCU_H='' LDFLAGS += -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref -LDFLAGS += $(LDFLAGS_MOD) LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) @@ -80,7 +79,7 @@ endif # Flags for optional C++ source code CXXFLAGS += $(filter-out -std=c99,$(CFLAGS)) -CXXFLAGS += $(CXXFLAGS_MOD) + # TODO make this common -- shouldn't be using these "private" vars from py.mk ifneq ($(SRC_CXX)$(SRC_USERMOD_CXX)$(SRC_USERMOD_LIB_CXX),) LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)" @@ -114,10 +113,6 @@ SRC_C += \ lib/asf4/$(MCU_SERIES_LOWER)/hal/src/hal_atomic.c \ lib/asf4/$(MCU_SERIES_LOWER)/hal/src/hal_flash.c \ lib/asf4/$(MCU_SERIES_LOWER)/hpl/nvmctrl/hpl_nvmctrl.c \ - lib/libm/ef_sqrt.c \ - lib/libm/fmodf.c \ - lib/libm/math.c \ - lib/libm/nearbyintf.c \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/common/tusb_fifo.c \ lib/tinyusb/src/device/usbd.c \ @@ -125,7 +120,6 @@ SRC_C += \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ lib/tinyusb/src/tusb.c \ drivers/bus/softspi.c \ - extmod/uos_dupterm.c \ shared/runtime/mpirq.c \ shared/libc/printf.c \ shared/libc/string0.c \ @@ -138,9 +132,11 @@ SRC_C += \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ -SRC_C += $(SRC_MOD) - -SRC_CXX += $(SRC_MOD_CXX) +LIBM_SRC_C += \ + lib/libm/ef_sqrt.c \ + lib/libm/fmodf.c \ + lib/libm/math.c \ + lib/libm/nearbyintf.c \ # List of sources for qstr extraction SRC_QSTR += \ @@ -159,17 +155,16 @@ SRC_QSTR += \ modsamd.c \ samd_flash.c \ shared/readline/readline.c \ - extmod/uos_dupterm.c \ shared/runtime/mpirq.c \ shared/runtime/sys_stdio_mphal.c \ -SRC_QSTR += $(SRC_MOD) $(SRC_CXX) +SRC_QSTR += $(SRC_CXX) OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(LIBM_SRC_C:.c=.o)) OBJ += $(GEN_PINS_SRC:.c=.o) ifneq ($(FROZEN_MANIFEST),) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk index e83e8911ddbf..f8ed02f841d9 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.mk +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -2,7 +2,7 @@ MICROPY_VFS_LFS2 ?= 1 SRC_S += shared/runtime/gchelper_m3.s -SRC_MOD += $(addprefix lib/libm/,\ +LIBM_SRC_C += $(addprefix lib/libm/,\ acoshf.c \ asinfacosf.c \ asinhf.c \ diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 8b503112aef7..79bf8b54bf2c 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -95,7 +95,7 @@ INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc #INC += -I$(USBHOST_DIR) INC += -Ilwip_inc -CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_EXTRA) CFLAGS += -D$(CMSIS_MCU) -DUSE_FULL_LL_DRIVER CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) CFLAGS += $(COPT) @@ -156,7 +156,7 @@ endif # Flags for optional C++ source code CXXFLAGS += $(filter-out -Wmissing-prototypes -Wold-style-definition -std=gnu99,$(CFLAGS)) -CXXFLAGS += $(CXXFLAGS_MOD) + # TODO make this common -- shouldn't be using these "private" vars from py.mk ifneq ($(SRC_CXX)$(SRC_USERMOD_CXX)$(SRC_USERMOD_LIB_CXX),) LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)" @@ -275,12 +275,6 @@ ifeq ($(MICROPY_FLOAT_IMPL),double) $(LIBM_O): CFLAGS := $(filter-out -Wdouble-promotion -Wfloat-conversion, $(CFLAGS)) endif -EXTMOD_SRC_C += $(addprefix extmod/,\ - modonewire.c \ - modnetwork.c \ - modusocket.c \ - ) - DRIVERS_SRC_C += $(addprefix drivers/,\ bus/softspi.c \ bus/softqspi.c \ @@ -358,11 +352,9 @@ SRC_C += \ servo.c \ dac.c \ adc.c \ + sdio.c \ $(wildcard $(BOARD_DIR)/*.c) -SRC_CXX += \ - $(SRC_MOD_CXX) - SRC_O += \ $(STARTUP_FILE) \ $(SYSTEM_FILE) @@ -482,70 +474,26 @@ USBDEV_SRC_C += $(addprefix $(USBDEV_DIR)/,\ class/src/usbd_msc_scsi.c \ ) -ifeq ($(MICROPY_PY_BLUETOOTH),1) -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH=1 -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 -endif - -ifeq ($(MICROPY_PY_NETWORK_CYW43),1) -CFLAGS_MOD += -DMICROPY_PY_NETWORK_CYW43=1 -SRC_C += sdio.c -EXTMOD_SRC_C += extmod/network_cyw43.c -DRIVERS_SRC_C += drivers/cyw43/cyw43_ctrl.c drivers/cyw43/cyw43_lwip.c -LIBS += $(TOP)/drivers/cyw43/libcyw43.a -endif - -ifneq ($(MICROPY_PY_NETWORK_WIZNET5K),0) -WIZNET5K_DIR=lib/wiznet5k -GIT_SUBMODULES += lib/wiznet5k -INC += -I$(TOP)/$(WIZNET5K_DIR) -I$(TOP)/$(WIZNET5K_DIR)/Ethernet -CFLAGS_MOD += -DMICROPY_PY_NETWORK_WIZNET5K=$(MICROPY_PY_NETWORK_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_NETWORK_WIZNET5K) -CFLAGS_MOD += -DWIZCHIP_PREFIXED_EXPORTS=1 -ifeq ($(MICROPY_PY_LWIP),1) -# When using MACRAW mode (with lwIP), maximum buffer space must be used for the raw socket -CFLAGS_MOD += -DWIZCHIP_USE_MAX_BUFFER -endif -SRC_MOD += extmod/network_wiznet5k.c -SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ - Ethernet/W$(MICROPY_PY_NETWORK_WIZNET5K)/w$(MICROPY_PY_NETWORK_WIZNET5K).c \ - Ethernet/wizchip_conf.c \ - Ethernet/socket.c \ - Internet/DNS/dns.c \ - Internet/DHCP/dhcp.c \ - ) -endif - ifeq ($(MICROPY_SSL_MBEDTLS),1) -CFLAGS_MOD += -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' -SRC_MOD += mbedtls/mbedtls_port.c +CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' +LIB_SRC_C += mbedtls/mbedtls_port.c endif ifeq ($(MICROPY_PY_BLUETOOTH),1) - SRC_C += mpbthciport.c ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) -ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) -$(error Cannot enable both NimBLE and BTstack at the same time) -endif -endif - -ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) -CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 -include $(TOP)/extmod/nimble/nimble.mk SRC_C += mpnimbleport.c endif ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) -MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 -include $(TOP)/extmod/btstack/btstack.mk SRC_C += mpbtstackport.c +MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 endif ifeq ($(MICROPY_PY_NETWORK_CYW43),1) DRIVERS_SRC_C += drivers/cyw43/cywbt.c endif - endif # SRC_O should be placed first to work around this LTO bug with binutils <2.35: @@ -555,7 +503,6 @@ OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ += $(LIBM_O) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(HAL_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(USBDEV_SRC_C:.c=.o)) @@ -713,7 +660,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(call GENERATE_ELF,$@,$^) # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SRC_MOD) $(SHARED_SRC_C) $(EXTMOD_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) # Append any auto-generated sources that are needed by sources listed in # SRC_QSTR SRC_QSTR_AUTO_DEPS += $(GEN_CDCINF_HEADER) diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index 176092f8c0a5..12ffdbc7e468 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -58,7 +58,7 @@ INC += -I../$(USBDEV_DIR)/core/inc -I../$(USBDEV_DIR)/class/inc # the compiler does not optimise these functions in terms of themselves. CFLAGS_BUILTIN ?= -ffreestanding -fno-builtin -fno-lto -CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Werror -std=gnu99 -nostdlib $(CFLAGS_EXTRA) CFLAGS += -D$(CMSIS_MCU) CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) CFLAGS += $(COPT) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 69b29e8ec393..34b3a6abad7b 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -309,6 +309,14 @@ static inline mp_uint_t disable_irq(void) { #define MICROPY_PY_BLUETOOTH_HCI_READ_MODE MICROPY_PY_BLUETOOTH_HCI_READ_MODE_BYTE #endif +#ifndef MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE +#define MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE (1) +#endif + +#ifndef MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS +#define MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS (MICROPY_BLUETOOTH_NIMBLE) +#endif + // We need an implementation of the log2 function which is not a macro #define MP_NEED_LOG2 (1) diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index 876ddf1c1da3..89e5cbce9dcc 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -164,7 +164,10 @@ SRC_TEENSY = $(addprefix core/,\ yield.c \ ) -OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(STM_SRC_C:.c=.o) $(SRC_TEENSY:.c=.o)) +OBJ += $(PY_O) +OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_TEENSY:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) OBJ += $(BUILD)/shared/runtime/gchelper_m3.o OBJ += $(GEN_PINS_SRC:.c=.o) diff --git a/ports/unix/Makefile b/ports/unix/Makefile index facdab2e045d..360cdd6f8ce9 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -39,7 +39,7 @@ INC += -I$(BUILD) # compiler settings CWARN = -Wall -Werror CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) -I$(VARIANT_DIR) $(CFLAGS_EXTRA) +CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(COPT) -I$(VARIANT_DIR) $(CFLAGS_EXTRA) # Debugging/Optimization ifdef DEBUG @@ -142,35 +142,10 @@ endif # If the variant enables it, enable modbluetooth. ifeq ($(MICROPY_PY_BLUETOOTH),1) - -HAVE_LIBUSB := $(shell (which pkg-config > /dev/null && pkg-config --exists libusb-1.0) 2>/dev/null && echo '1') - -# Only one stack can be enabled. -ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) -ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) -$(error Cannot enable both NimBLE and BTstack at the same time) -endif -endif - -# Default to btstack, but a variant (or make command line) can set NimBLE -# explicitly (which is always via H4 UART). -ifneq ($(MICROPY_BLUETOOTH_NIMBLE),1) -ifneq ($(MICROPY_BLUETOOTH_BTSTACK),1) -MICROPY_BLUETOOTH_BTSTACK ?= 1 -endif -endif - -CFLAGS += -DMICROPY_PY_BLUETOOTH=1 -CFLAGS += -DMICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 - ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) +HAVE_LIBUSB := $(shell (which pkg-config > /dev/null && pkg-config --exists libusb-1.0) 2>/dev/null && echo '1') # Figure out which BTstack transport to use. -ifeq ($(MICROPY_BLUETOOTH_BTSTACK_H4),1) -ifeq ($(MICROPY_BLUETOOTH_BTSTACK_USB),1) -$(error Cannot enable BTstack support for USB and H4 UART at the same time) -endif -else ifeq ($(HAVE_LIBUSB),1) # Default to btstack-over-usb. MICROPY_BLUETOOTH_BTSTACK_USB ?= 1 @@ -178,20 +153,9 @@ else # Fallback to HCI controller via a H4 UART (e.g. Zephyr on nRF) over a /dev/tty serial port. MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 endif -endif - -# BTstack is enabled. -include $(TOP)/extmod/btstack/btstack.mk -SRC_BTSTACK += lib/btstack/platform/embedded/btstack_run_loop_embedded.c - -else - -# NimBLE is enabled. -CFLAGS += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 -include $(TOP)/extmod/nimble/nimble.mk +SRC_BTSTACK_C += lib/btstack/platform/embedded/btstack_run_loop_embedded.c endif - endif ifeq ($(MICROPY_PY_FFI),1) @@ -242,7 +206,6 @@ SRC_C += \ mpbtstackport_h4.c \ mpbtstackport_usb.c \ mpnimbleport.c \ - $(SRC_MOD) \ modtermios.c \ modusocket.c \ modffi.c \ @@ -256,17 +219,14 @@ SHARED_SRC_C += $(addprefix shared/,\ ) SRC_CXX += \ - $(SRC_MOD_CXX) OBJ = $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) $(EXTMOD_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) # Append any auto-generated sources that are needed by sources listed in # SRC_QSTR SRC_QSTR_AUTO_DEPS += diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index a67d11b9e7e4..a0b9192bfcf2 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -240,3 +240,11 @@ static inline unsigned long mp_urandom_seed_init(void) { // Configure the implementation of machine.idle(). #include #define MICROPY_UNIX_MACHINE_IDLE sched_yield(); + +#ifndef MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE +#define MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE (1) +#endif + +#ifndef MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS +#define MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS (MICROPY_BLUETOOTH_NIMBLE) +#endif diff --git a/ports/windows/Makefile b/ports/windows/Makefile index 64334bc18b27..e7f0f2ff618b 100644 --- a/ports/windows/Makefile +++ b/ports/windows/Makefile @@ -32,7 +32,7 @@ INC += -I$(BUILD) INC += -I$(VARIANT_DIR) # compiler settings -CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) +CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(COPT) $(CFLAGS_EXTRA) LDFLAGS += -lm -lbcrypt $(LDFLAGS_EXTRA) # Debugging/Optimization @@ -56,31 +56,26 @@ SRC_C = \ realpath.c \ init.c \ fmode.c \ - $(SRC_MOD) \ $(wildcard $(VARIANT_DIR)/*.c) SHARED_SRC_C += $(addprefix shared/,\ $(SHARED_SRC_C_EXTRA) \ ) -SRC_CXX += \ - $(SRC_MOD_CXX) - OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) ifeq ($(MICROPY_USE_READLINE),1) -CFLAGS_MOD += -DMICROPY_USE_READLINE=1 +CFLAGS += -DMICROPY_USE_READLINE=1 SRC_C += shared/readline/readline.c endif LIB += -lws2_32 # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) $(EXTMOD_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) # Append any auto-generated sources that are needed by sources listed in # SRC_QSTR SRC_QSTR_AUTO_DEPS += @@ -89,7 +84,7 @@ ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -DMICROPY_MODULE_FROZEN_MPY=1 -DMPZ_DIG_SIZE=16 endif -CXXFLAGS += $(filter-out -std=gnu99,$(CFLAGS) $(CXXFLAGS_MOD)) +CXXFLAGS += $(filter-out -std=gnu99,$(CFLAGS)) include $(TOP)/py/mkrules.mk diff --git a/py/py.mk b/py/py.mk index ec69ca42d971..fde612d80465 100644 --- a/py/py.mk +++ b/py/py.mk @@ -207,7 +207,7 @@ endif # Sources that may contain qstrings SRC_QSTR_IGNORE = py/nlr% -SRC_QSTR += $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) +SRC_QSTR += $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) # Anything that depends on FORCE will be considered out-of-date FORCE: From 43bcfb148b21d0f6dfa18d6d565f2c686dec80af Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sun, 9 Oct 2022 00:05:11 +1100 Subject: [PATCH 1865/4290] mimxrt/Makefile: Split up SRC_C variables. This improves clarity a bit, but also ensures that only the required files are added to SRC_QSTR. Signed-off-by: Jim Mussared --- ports/mimxrt/Makefile | 47 +++++++++++++------------------------------ 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 640864e58295..2119e027ef59 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -178,6 +178,11 @@ SRC_C += \ pendsv.c \ pin.c \ sdcard.c \ + systick.c \ + ticks.c \ + tusb_port.c \ + +SHARED_SRC_C += \ shared/libc/printf.c \ shared/libc/string0.c \ shared/netutils/dhcpserver.c \ @@ -191,23 +196,17 @@ SRC_C += \ shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ - systick.c \ - ticks.c \ - tusb_port.c \ - $(SRC_TINYUSB_C) \ - $(SRC_HAL_IMX_C) \ - $(SRC_ETH_C) # Add sources for respective board flash type ifeq ($(MICROPY_HW_FLASH_TYPE),$(filter $(MICROPY_HW_FLASH_TYPE),qspi_nor_flash qspi_hyper_flash)) # Add hal/flexspi_nor_flash.c or hal/flashspi_hyper_flash.c respectively - SRC_C += hal/flexspi_$(subst qspi_,,$(MICROPY_HW_FLASH_TYPE)).c + SRC_HAL_C += hal/flexspi_$(subst qspi_,,$(MICROPY_HW_FLASH_TYPE)).c # # Add custom (board specific) or default configuration ifeq ($(MICROPY_HW_BOARD_FLASH_FILES),1) - SRC_C += $(BOARD_DIR)/$(MICROPY_HW_FLASH_TYPE)_config.c + SRC_HAL_C += $(BOARD_DIR)/$(MICROPY_HW_FLASH_TYPE)_config.c else - SRC_C += hal/$(MICROPY_HW_FLASH_TYPE)_config.c + SRC_HAL_C += hal/$(MICROPY_HW_FLASH_TYPE)_config.c endif else $(error Error: Unknown board flash type $(MICROPY_HW_FLASH_TYPE)) @@ -254,29 +253,7 @@ SRC_S += shared/runtime/gchelper_m3.s \ # ============================================================================= # List of sources for qstr extraction -SRC_QSTR += \ - extmod/modonewire.c \ - extmod/uos_dupterm.c \ - machine_adc.c \ - machine_i2s.c \ - machine_led.c \ - machine_pin.c \ - machine_pwm.c \ - machine_rtc.c \ - machine_sdcard.c \ - machine_spi.c \ - machine_timer.c \ - machine_uart.c \ - machine_wdt.c \ - mimxrt_flash.c \ - modmachine.c \ - modmimxrt.c \ - modutime.c \ - pin.c \ - shared/readline/readline.c \ - shared/runtime/mpirq.c \ - shared/runtime/sys_stdio_mphal.c \ - $(GEN_PINS_SRC) +SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(GEN_PINS_SRC) # ============================================================================= # Compiler Flags @@ -413,12 +390,16 @@ ifeq ($(MICROPY_FLOAT_IMPL),double) $(LIBM_O): CFLAGS := $(filter-out -Wdouble-promotion -Wfloat-conversion, $(CFLAGS)) endif - OBJ += $(PY_O) OBJ += $(LIBM_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_TINYUSB_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_HAL_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_HAL_IMX_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_ETH_C:.c=.o)) OBJ += $(GEN_PINS_SRC:.c=.o) # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" From a2aceb50074f625c0d9b08ab8902bef1557c1ec6 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sun, 9 Oct 2022 00:05:17 +1100 Subject: [PATCH 1866/4290] nrf/Makefile: Split up SRC_C variables. This improves clarity a bit, but also ensures that only the required files are added to SRC_QSTR. Signed-off-by: Jim Mussared --- ports/nrf/Makefile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 4128404da4a8..a80a37e1fb46 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -163,7 +163,7 @@ LIBS = \ ifeq ($(MCU_VARIANT), nrf52) -SRC_LIB += $(addprefix lib/,\ +SRC_LIB_C += $(addprefix lib/,\ libm/math.c \ libm/fmodf.c \ libm/nearbyintf.c \ @@ -197,7 +197,7 @@ endif ifeq ($(MCU_VARIANT), nrf91) -SRC_LIB += $(addprefix lib/,\ +SRC_LIB_C += $(addprefix lib/,\ libm/math.c \ libm/fmodf.c \ libm/nearbyintf.c \ @@ -236,7 +236,7 @@ include drivers/secureboot/secureboot.mk endif -SRC_LIB += $(addprefix shared/,\ +SRC_SHARED_C += $(addprefix shared/,\ libc/string0.c \ readline/readline.c \ runtime/pyexec.c \ @@ -247,7 +247,7 @@ SRC_LIB += $(addprefix shared/,\ ) ifeq ($(MICROPY_FATFS), 1) -SRC_LIB += $(addprefix lib/,\ +SRC_LIB_C += $(addprefix lib/,\ oofatfs/ff.c \ oofatfs/ffunicode.c \ ) @@ -362,7 +362,8 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX_HAL:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SYSTEM_C_SRC:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIB_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_C:.c=.o)) OBJ += $(GEN_PINS_SRC:.c=.o) $(BUILD)/$(OOFATFS_DIR)/ff.o: COPT += -Os @@ -518,7 +519,7 @@ $(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ) $(Q)$(SIZE) $@ # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_LIB) $(DRIVERS_SRC_C) $(SRC_BOARD_MODULES) +SRC_QSTR += $(SRC_C) $(SRC_SHARED_C) $(DRIVERS_SRC_C) $(SRC_BOARD_MODULES) # Append any auto-generated sources that are needed by sources listed in # SRC_QSTR From b25087fc6ff6460bf464dbd402febc86799068a9 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sun, 9 Oct 2022 00:05:26 +1100 Subject: [PATCH 1867/4290] samd/Makefile: Split up SRC_C variables. This improves clarity a bit, but also ensures that only the required files are added to SRC_QSTR. Signed-off-by: Jim Mussared --- ports/samd/Makefile | 66 +++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 2c5f6a1ab221..2f97b1993e99 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -110,16 +110,8 @@ SRC_C += \ samd_isr.c \ samd_soc.c \ tusb_port.c \ - lib/asf4/$(MCU_SERIES_LOWER)/hal/src/hal_atomic.c \ - lib/asf4/$(MCU_SERIES_LOWER)/hal/src/hal_flash.c \ - lib/asf4/$(MCU_SERIES_LOWER)/hpl/nvmctrl/hpl_nvmctrl.c \ - lib/tinyusb/src/class/cdc/cdc_device.c \ - lib/tinyusb/src/common/tusb_fifo.c \ - lib/tinyusb/src/device/usbd.c \ - lib/tinyusb/src/device/usbd_control.c \ - lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ - lib/tinyusb/src/tusb.c \ - drivers/bus/softspi.c \ + +SHARED_SRC_C += \ shared/runtime/mpirq.c \ shared/libc/printf.c \ shared/libc/string0.c \ @@ -132,39 +124,43 @@ SRC_C += \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ -LIBM_SRC_C += \ - lib/libm/ef_sqrt.c \ - lib/libm/fmodf.c \ - lib/libm/math.c \ - lib/libm/nearbyintf.c \ +ASF4_SRC_C += $(addprefix lib/asf4/$(MCU_SERIES_LOWER)/,\ + hal/src/hal_atomic.c \ + hal/src/hal_flash.c \ + hpl/nvmctrl/hpl_nvmctrl.c \ + ) + +LIBM_SRC_C += $(addprefix lib/libm/,\ + ef_sqrt.c \ + fmodf.c \ + math.c \ + nearbyintf.c \ + ) + +TINYUSB_SRC_C += $(addprefix lib/tinyusb/src/,\ + class/cdc/cdc_device.c \ + common/tusb_fifo.c \ + device/usbd.c \ + device/usbd_control.c \ + portable/microchip/samd/dcd_samd.c \ + tusb.c \ + ) + +DRIVERS_SRC_C += \ + drivers/bus/softspi.c \ # List of sources for qstr extraction -SRC_QSTR += \ - machine_adc.c \ - machine_dac.c \ - machine_i2c.c \ - machine_led.c \ - machine_pin.c \ - machine_pwm.c \ - machine_spi.c \ - machine_timer.c \ - machine_uart.c \ - machine_wdt.c \ - modutime.c \ - modmachine.c \ - modsamd.c \ - samd_flash.c \ - shared/readline/readline.c \ - shared/runtime/mpirq.c \ - shared/runtime/sys_stdio_mphal.c \ - -SRC_QSTR += $(SRC_CXX) +SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(SRC_CXX) $(GEN_PINS_SRC) OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(ASF4_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(LIBM_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o)) OBJ += $(GEN_PINS_SRC:.c=.o) ifneq ($(FROZEN_MANIFEST),) From 92d911803812100fac109b6108ab005e7bbd4c82 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 7 Oct 2022 21:08:08 +0200 Subject: [PATCH 1868/4290] rp2/fatfs_port: Fix the modification date of files. It was off by 2000 % 128 == 80 years. Addresses issue #9535. --- ports/rp2/fatfs_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/rp2/fatfs_port.c b/ports/rp2/fatfs_port.c index 3821d6586c13..9706b6fe7dc7 100644 --- a/ports/rp2/fatfs_port.c +++ b/ports/rp2/fatfs_port.c @@ -30,5 +30,5 @@ MP_WEAK DWORD get_fattime(void) { datetime_t t; rtc_get_datetime(&t); - return ((2000 + t.year - 1980) << 25) | ((t.month) << 21) | ((t.day) << 16) | ((t.hour) << 11) | ((t.min) << 5) | (t.sec / 2); + return ((t.year - 1980) << 25) | ((t.month) << 21) | ((t.day) << 16) | ((t.hour) << 11) | ((t.min) << 5) | (t.sec / 2); } From ab317a0d66005ea88f162994130f61d0d488db93 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 8 Oct 2022 17:32:22 -0500 Subject: [PATCH 1869/4290] py/misc: Remove use of bitfield from vstr_t. Since there is only one flag, we don't need to use a bitfield in vstr_t. Compilers emit extra instructions to access a bitfield, so this should reduce the binary size a small amount. Signed-off-by: David Lechner --- py/misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/misc.h b/py/misc.h index 7350d2f9b0c0..32061a009ed3 100644 --- a/py/misc.h +++ b/py/misc.h @@ -179,7 +179,7 @@ typedef struct _vstr_t { size_t alloc; size_t len; char *buf; - bool fixed_buf : 1; + bool fixed_buf; } vstr_t; // convenience macro to declare a vstr with a fixed size buffer on the stack From 89b320737652829edbab921e86d7ad3962d86d9e Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Oct 2022 14:36:17 +1100 Subject: [PATCH 1870/4290] unix/modffi: Move header includes inside MICROPY_PY_FFI guard. So ffi.h is not needed if this module is disabled. Signed-off-by: Damien George --- ports/unix/modffi.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 3df748b80d95..bc585f8647bc 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -25,13 +25,6 @@ * THE SOFTWARE. */ -#include -#include -#include -#include -#include -#include - #include "py/runtime.h" #include "py/binary.h" #include "py/mperrno.h" @@ -40,6 +33,12 @@ #if MICROPY_PY_FFI +#include +#include +#include +#include +#include + /* * modffi uses character codes to encode a value type, based on "struct" * module type codes, with some extensions and overridings. From 815920c87f9bda6b3fb7ec24686154210c9e8774 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Oct 2022 15:49:52 +1100 Subject: [PATCH 1871/4290] extmod/utime_mphal: Make ticks_add check for overflow of delta. Work done in collaboration with @jimmo. Signed-off-by: Damien George --- extmod/utime_mphal.c | 13 +++++++++++ tests/extmod/ticks_add.py | 42 +++++++++++++++++++++++++++++++++++ tests/extmod/ticks_add.py.exp | 36 ++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 tests/extmod/ticks_add.py create mode 100644 tests/extmod/ticks_add.py.exp diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c index 3d1cdfd82062..cd91c95530cb 100644 --- a/extmod/utime_mphal.c +++ b/extmod/utime_mphal.c @@ -95,6 +95,19 @@ STATIC mp_obj_t time_ticks_add(mp_obj_t ticks_in, mp_obj_t delta_in) { // we assume that first argument come from ticks_xx so is small int mp_uint_t ticks = MP_OBJ_SMALL_INT_VALUE(ticks_in); mp_uint_t delta = mp_obj_get_int(delta_in); + + // Check that delta does not overflow the range that ticks_diff can handle. + // This ensures the following: + // - ticks_diff(ticks_add(T, delta), T) == delta + // - ticks_diff(T, ticks_add(T, delta)) == -delta + // The latter requires excluding delta=-TICKS_PERIOD/2. + // + // This unsigned comparison is equivalent to a signed comparison of: + // delta <= TICKS_PERIOD/2 || delta >= TICKS_PERIOD/2 + if (delta + MICROPY_PY_UTIME_TICKS_PERIOD / 2 - 1 >= MICROPY_PY_UTIME_TICKS_PERIOD - 1) { + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ticks interval overflow")); + } + return MP_OBJ_NEW_SMALL_INT((ticks + delta) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)); } MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj, time_ticks_add); diff --git a/tests/extmod/ticks_add.py b/tests/extmod/ticks_add.py new file mode 100644 index 000000000000..2f1ba6c8109d --- /dev/null +++ b/tests/extmod/ticks_add.py @@ -0,0 +1,42 @@ +try: + from utime import ticks_diff, ticks_add +except ImportError: + print("SKIP") + raise SystemExit + +# Maximum value returned from ticks_add, ticks_ms, etc. +TICKS_MAX = ticks_add(0, -1) +# Maximum value returned from ticks_diff. +TICKS_INTERVAL_MAX = TICKS_MAX // 2 + +# Invariants: +# - ticks_diff(ticks_add(T, delta), T) == delta +# - ticks_diff(T, ticks_add(T, delta)) == -delta + +# Check actual values of ticks_add. +print(ticks_add(20, 12)) +print(ticks_add(20, -12)) + +# Check invariant. +print(ticks_diff(ticks_add(100, 123), 100)) +print(ticks_diff(ticks_add(100, -123), 100)) +print(ticks_diff(100, ticks_add(100, 123))) +print(ticks_diff(100, ticks_add(100, -123))) + +# Check limits. +for T in (0, 10, TICKS_MAX): + for delta in ( + -TICKS_INTERVAL_MAX - 1, + -TICKS_INTERVAL_MAX, + 0, + TICKS_INTERVAL_MAX, + TICKS_INTERVAL_MAX + 1, + ): + try: + print(ticks_diff(ticks_add(T, delta), T) == delta) + except OverflowError: + print("OverflowError") + try: + print(ticks_diff(T, ticks_add(T, delta)) == -delta) + except OverflowError: + print("OverflowError") diff --git a/tests/extmod/ticks_add.py.exp b/tests/extmod/ticks_add.py.exp new file mode 100644 index 000000000000..60dc6f5afda6 --- /dev/null +++ b/tests/extmod/ticks_add.py.exp @@ -0,0 +1,36 @@ +32 +8 +123 +-123 +-123 +123 +OverflowError +OverflowError +True +True +True +True +True +True +OverflowError +OverflowError +OverflowError +OverflowError +True +True +True +True +True +True +OverflowError +OverflowError +OverflowError +OverflowError +True +True +True +True +True +True +OverflowError +OverflowError From 965a87b53cd9da32a546b03cdd01042058080498 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Oct 2022 16:10:38 +1100 Subject: [PATCH 1872/4290] tests/extmod: Add test for sleep_ms value that overflows ticks. Addresses #9516. Signed-off-by: Damien George --- tests/extmod/uasyncio_micropython.py | 6 ++++++ tests/extmod/uasyncio_micropython.py.exp | 1 + 2 files changed, 7 insertions(+) diff --git a/tests/extmod/uasyncio_micropython.py b/tests/extmod/uasyncio_micropython.py index 69e5fa3224df..a6b65bb2a84c 100644 --- a/tests/extmod/uasyncio_micropython.py +++ b/tests/extmod/uasyncio_micropython.py @@ -22,6 +22,12 @@ async def main(): await uasyncio.sleep_ms(1) print(utime.ticks_diff(utime.ticks_ms(), t0) < 100) + try: + # Sleep 1ms beyond maximum allowed sleep value + await uasyncio.sleep_ms(utime.ticks_add(0, -1) // 2 + 1) + except OverflowError: + print("OverflowError") + # When task finished before the timeout print(await uasyncio.wait_for_ms(task(1, 5), 50)) diff --git a/tests/extmod/uasyncio_micropython.py.exp b/tests/extmod/uasyncio_micropython.py.exp index f5be1dc75a25..4d1c6d681f2f 100644 --- a/tests/extmod/uasyncio_micropython.py.exp +++ b/tests/extmod/uasyncio_micropython.py.exp @@ -1,4 +1,5 @@ True +OverflowError task start 1 task end 1 2 From af4ba6d1b4558e0ce1c81b8acd975f0bcbe83072 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 19:48:07 +0200 Subject: [PATCH 1873/4290] stm32: Rename machine I2C and SPI types consistently across ports. This renames: - machine_hard_i2c_type -> machine_i2c_type - machine_hard_spi_type -> machine_spi_type --- ports/stm32/machine_i2c.c | 18 +++++++++--------- ports/stm32/machine_spi.c | 14 +++++++------- ports/stm32/modmachine.c | 4 ++-- ports/stm32/modmachine.h | 4 +++- ports/stm32/spi.c | 4 ++-- ports/stm32/spi.h | 2 +- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 9a2d338f5498..7718d1bfe038 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -49,16 +49,16 @@ typedef struct _machine_hard_i2c_obj_t { STATIC const machine_hard_i2c_obj_t machine_hard_i2c_obj[MICROPY_HW_MAX_I2C] = { #if defined(MICROPY_HW_I2C1_SCL) - [0] = {{&machine_hard_i2c_type}, I2C1, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA}, + [0] = {{&machine_i2c_type}, I2C1, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA}, #endif #if defined(MICROPY_HW_I2C2_SCL) - [1] = {{&machine_hard_i2c_type}, I2C2, MICROPY_HW_I2C2_SCL, MICROPY_HW_I2C2_SDA}, + [1] = {{&machine_i2c_type}, I2C2, MICROPY_HW_I2C2_SCL, MICROPY_HW_I2C2_SDA}, #endif #if defined(MICROPY_HW_I2C3_SCL) - [2] = {{&machine_hard_i2c_type}, I2C3, MICROPY_HW_I2C3_SCL, MICROPY_HW_I2C3_SDA}, + [2] = {{&machine_i2c_type}, I2C3, MICROPY_HW_I2C3_SCL, MICROPY_HW_I2C3_SDA}, #endif #if defined(MICROPY_HW_I2C4_SCL) - [3] = {{&machine_hard_i2c_type}, I2C4, MICROPY_HW_I2C4_SCL, MICROPY_HW_I2C4_SDA}, + [3] = {{&machine_i2c_type}, I2C4, MICROPY_HW_I2C4_SCL, MICROPY_HW_I2C4_SDA}, #endif }; @@ -140,16 +140,16 @@ typedef mp_machine_soft_i2c_obj_t machine_hard_i2c_obj_t; STATIC machine_hard_i2c_obj_t machine_hard_i2c_obj[MICROPY_HW_MAX_I2C] = { #if defined(MICROPY_HW_I2C1_SCL) - [0] = {{&machine_hard_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA}, + [0] = {{&machine_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA}, #endif #if defined(MICROPY_HW_I2C2_SCL) - [1] = {{&machine_hard_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C2_SCL, MICROPY_HW_I2C2_SDA}, + [1] = {{&machine_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C2_SCL, MICROPY_HW_I2C2_SDA}, #endif #if defined(MICROPY_HW_I2C3_SCL) - [2] = {{&machine_hard_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C3_SCL, MICROPY_HW_I2C3_SDA}, + [2] = {{&machine_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C3_SCL, MICROPY_HW_I2C3_SDA}, #endif #if defined(MICROPY_HW_I2C4_SCL) - [3] = {{&machine_hard_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C4_SCL, MICROPY_HW_I2C4_SDA}, + [3] = {{&machine_i2c_type}, 1, I2C_POLL_DEFAULT_TIMEOUT_US, MICROPY_HW_I2C4_SCL, MICROPY_HW_I2C4_SDA}, #endif }; @@ -237,7 +237,7 @@ STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_i2c_type, + machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, make_new, machine_hard_i2c_make_new, diff --git a/ports/stm32/machine_spi.c b/ports/stm32/machine_spi.c index 718ae1af5e5a..7ccff75f1ccf 100644 --- a/ports/stm32/machine_spi.c +++ b/ports/stm32/machine_spi.c @@ -32,12 +32,12 @@ // Implementation of hard SPI for machine module STATIC const machine_hard_spi_obj_t machine_hard_spi_obj[] = { - {{&machine_hard_spi_type}, &spi_obj[0]}, - {{&machine_hard_spi_type}, &spi_obj[1]}, - {{&machine_hard_spi_type}, &spi_obj[2]}, - {{&machine_hard_spi_type}, &spi_obj[3]}, - {{&machine_hard_spi_type}, &spi_obj[4]}, - {{&machine_hard_spi_type}, &spi_obj[5]}, + {{&machine_spi_type}, &spi_obj[0]}, + {{&machine_spi_type}, &spi_obj[1]}, + {{&machine_spi_type}, &spi_obj[2]}, + {{&machine_spi_type}, &spi_obj[3]}, + {{&machine_spi_type}, &spi_obj[4]}, + {{&machine_spi_type}, &spi_obj[5]}, }; STATIC void machine_hard_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -136,7 +136,7 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_spi_type, + machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, make_new, machine_hard_spi_make_new, diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index e1796d1cf025..06fdd0e2c1bd 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -424,14 +424,14 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, #if MICROPY_PY_MACHINE_I2C #if MICROPY_HW_ENABLE_HW_I2C - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hard_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, #else { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, #endif { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, #endif #if MICROPY_PY_MACHINE_SPI - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hard_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, #endif #if MICROPY_HW_ENABLE_I2S diff --git a/ports/stm32/modmachine.h b/ports/stm32/modmachine.h index 9fa7851582e1..0c776280b416 100644 --- a/ports/stm32/modmachine.h +++ b/ports/stm32/modmachine.h @@ -30,8 +30,10 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_timer_type; -extern const mp_obj_type_t machine_hard_i2c_type; +extern const mp_obj_type_t machine_i2c_type; extern const mp_obj_type_t machine_i2s_type; +extern const mp_obj_type_t machine_spi_type; +extern const mp_obj_type_t machine_timer_type; void machine_init(void); void machine_deinit(void); diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 9c031cad2e28..e21ebcd02b9d 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -678,7 +678,7 @@ const spi_t *spi_from_mp_obj(mp_obj_t o) { if (mp_obj_is_type(o, &pyb_spi_type)) { pyb_spi_obj_t *self = MP_OBJ_TO_PTR(o); return self->spi; - } else if (mp_obj_is_type(o, &machine_hard_spi_type)) { + } else if (mp_obj_is_type(o, &machine_spi_type)) { machine_hard_spi_obj_t *self = MP_OBJ_TO_PTR(o); return self->spi; } else { @@ -687,7 +687,7 @@ const spi_t *spi_from_mp_obj(mp_obj_t o) { } mp_obj_base_t *mp_hal_get_spi_obj(mp_obj_t o) { - if (mp_obj_is_type(o, &machine_hard_spi_type)) { + if (mp_obj_is_type(o, &machine_spi_type)) { return MP_OBJ_TO_PTR(o); } #if MICROPY_PY_MACHINE_SOFTSPI diff --git a/ports/stm32/spi.h b/ports/stm32/spi.h index 17f1bf6c4ab9..ef3d718cddfd 100644 --- a/ports/stm32/spi.h +++ b/ports/stm32/spi.h @@ -65,7 +65,7 @@ extern const spi_t spi_obj[6]; extern const mp_spi_proto_t spi_proto; extern const mp_obj_type_t pyb_spi_type; -extern const mp_obj_type_t machine_hard_spi_type; +extern const mp_obj_type_t machine_spi_type; // A transfer of "len" bytes should take len*8*1000/baudrate milliseconds. // To simplify the calculation we assume the baudrate is never less than 8kHz From 427670c21047585fb9295ddf35cdbdaa8265fbe1 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 20:20:03 +0200 Subject: [PATCH 1874/4290] esp32: Rename machine I2C and SPI types consistently across ports. This renames: - machine_hw_i2c_type -> machine_i2c_type - machine_hw_spi_type -> machine_spi_type --- ports/esp32/machine_hw_spi.c | 4 ++-- ports/esp32/machine_i2c.c | 4 ++-- ports/esp32/modmachine.c | 4 ++-- ports/esp32/modmachine.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index 647874e17f64..35ecc397b339 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -490,7 +490,7 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_ self = &machine_hw_spi_obj[1]; default_pins = &machine_hw_spi_default_pins[1]; } - self->base.type = &machine_hw_spi_type; + self->base.type = &machine_spi_type; int8_t sck, mosi, miso; @@ -540,7 +540,7 @@ STATIC const mp_machine_spi_p_t machine_hw_spi_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hw_spi_type, + machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, make_new, machine_hw_spi_make_new, diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index 9244343dcf61..17e98ffc5bb4 100644 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -161,7 +161,7 @@ mp_obj_t machine_hw_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_ bool first_init = false; if (self->base.type == NULL) { // Created for the first time, set default pins - self->base.type = &machine_hw_i2c_type; + self->base.type = &machine_i2c_type; self->port = i2c_id; if (self->port == I2C_NUM_0) { self->scl = MICROPY_HW_I2C0_SCL; @@ -193,7 +193,7 @@ STATIC const mp_machine_i2c_p_t machine_hw_i2c_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hw_i2c_type, + machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, make_new, machine_hw_i2c_make_new, diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index a70f2fbedb59..e24afd040350 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -315,14 +315,14 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { #if MICROPY_PY_MACHINE_DAC { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) }, #endif - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, #if MICROPY_PY_MACHINE_I2S { MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) }, #endif { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hw_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h index 4d2ab9020d16..138a89e9c33d 100644 --- a/ports/esp32/modmachine.h +++ b/ports/esp32/modmachine.h @@ -16,8 +16,8 @@ extern const mp_obj_type_t machine_touchpad_type; extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_adcblock_type; extern const mp_obj_type_t machine_dac_type; -extern const mp_obj_type_t machine_hw_i2c_type; -extern const mp_obj_type_t machine_hw_spi_type; +extern const mp_obj_type_t machine_i2c_type; +extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_i2s_type; extern const mp_obj_type_t machine_uart_type; extern const mp_obj_type_t machine_rtc_type; From 22ad45fda649b754916883f246139e35ff20e126 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 20:21:51 +0200 Subject: [PATCH 1875/4290] rp2: Rename machine I2C type consistently across ports. This renames: - machine_hw_i2c_type -> machine_i2c_type --- ports/rp2/machine_i2c.c | 6 +++--- ports/rp2/modmachine.c | 2 +- ports/rp2/modmachine.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/rp2/machine_i2c.c b/ports/rp2/machine_i2c.c index 00dc36a4e0cb..85d12c771368 100644 --- a/ports/rp2/machine_i2c.c +++ b/ports/rp2/machine_i2c.c @@ -68,8 +68,8 @@ typedef struct _machine_i2c_obj_t { } machine_i2c_obj_t; STATIC machine_i2c_obj_t machine_i2c_obj[] = { - {{&machine_hw_i2c_type}, i2c0, 0, MICROPY_HW_I2C0_SCL, MICROPY_HW_I2C0_SDA, 0}, - {{&machine_hw_i2c_type}, i2c1, 1, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA, 0}, + {{&machine_i2c_type}, i2c0, 0, MICROPY_HW_I2C0_SCL, MICROPY_HW_I2C0_SDA, 0}, + {{&machine_i2c_type}, i2c1, 1, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA, 0}, }; STATIC void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -177,7 +177,7 @@ STATIC const mp_machine_i2c_p_t machine_i2c_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hw_i2c_type, + machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, make_new, machine_i2c_make_new, diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c index 3c8922c41721..8058189a92b6 100644 --- a/ports/rp2/modmachine.c +++ b/ports/rp2/modmachine.c @@ -239,7 +239,7 @@ 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_ADC), MP_ROM_PTR(&machine_adc_type) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, diff --git a/ports/rp2/modmachine.h b/ports/rp2/modmachine.h index 503c1ca86c8a..6ea4def91d97 100644 --- a/ports/rp2/modmachine.h +++ b/ports/rp2/modmachine.h @@ -4,7 +4,7 @@ #include "py/obj.h" extern const mp_obj_type_t machine_adc_type; -extern const mp_obj_type_t machine_hw_i2c_type; +extern const mp_obj_type_t machine_i2c_type; extern const mp_obj_type_t machine_i2s_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_rtc_type; From e275a58ac12c72d8d8e99f8c558f6e4a1f6637c1 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 20:22:57 +0200 Subject: [PATCH 1876/4290] samd: Rename machine I2C type consistently across ports. This renames: - machine_hw_i2c_type -> machine_i2c_type --- ports/samd/machine_i2c.c | 4 ++-- ports/samd/modmachine.c | 2 +- ports/samd/modmachine.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c index 25dfa99340ff..0a8f5b94db08 100644 --- a/ports/samd/machine_i2c.c +++ b/ports/samd/machine_i2c.c @@ -144,7 +144,7 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n } // Get the peripheral object. - machine_i2c_obj_t *self = mp_obj_malloc(machine_i2c_obj_t, &machine_hw_i2c_type); + machine_i2c_obj_t *self = mp_obj_malloc(machine_i2c_obj_t, &machine_i2c_type); self->id = id; self->instance = sercom_instance[self->id]; @@ -260,7 +260,7 @@ STATIC const mp_machine_i2c_p_t machine_i2c_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hw_i2c_type, + machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, make_new, machine_i2c_make_new, diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index f6cf7f8155c9..b9de026ed425 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -157,7 +157,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 6a745da0675a..e99ca990fbba 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -30,7 +30,7 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_dac_type; -extern const mp_obj_type_t machine_hw_i2c_type; +extern const mp_obj_type_t machine_i2c_type; extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_pwm_type; From bfa6f34404374bb7c7d892ca6cb32175e8dd19f6 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 20:25:34 +0200 Subject: [PATCH 1877/4290] renesas-ra: Rename machine SPI type consistently across ports. This renames: - machine_hard_spi_type -> machine_spi_type --- ports/renesas-ra/machine_spi.c | 6 +++--- ports/renesas-ra/modmachine.c | 2 +- ports/renesas-ra/modmachine.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/renesas-ra/machine_spi.c b/ports/renesas-ra/machine_spi.c index b9f5b1ad1b4e..2c71c83b666c 100644 --- a/ports/renesas-ra/machine_spi.c +++ b/ports/renesas-ra/machine_spi.c @@ -70,7 +70,7 @@ typedef struct _machine_hard_spi_obj_t { STATIC machine_hard_spi_obj_t machine_hard_spi_obj[] = { #if defined(MICROPY_HW_SPI0_RSPCK) { - {&machine_hard_spi_type}, 0, + {&machine_spi_type}, 0, DEFAULT_SPI_POLARITY, DEFAULT_SPI_PHASE, DEFAULT_SPI_BITS, DEFAULT_SPI_FIRSTBIT, DEFAULT_SPI_BAUDRATE, MICROPY_HW_SPI0_RSPCK, MICROPY_HW_SPI0_MOSI, MICROPY_HW_SPI0_MISO, @@ -78,7 +78,7 @@ STATIC machine_hard_spi_obj_t machine_hard_spi_obj[] = { #endif #if defined(MICROPY_HW_SPI1_RSPCK) { - {&machine_hard_spi_type}, 1, + {&machine_spi_type}, 1, DEFAULT_SPI_POLARITY, DEFAULT_SPI_PHASE, DEFAULT_SPI_BITS, DEFAULT_SPI_FIRSTBIT, DEFAULT_SPI_BAUDRATE, MICROPY_HW_SPI1_RSPCK, MICROPY_HW_SPI1_MOSI, MICROPY_HW_SPI1_MISO, @@ -298,7 +298,7 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_spi_type, + machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, make_new, machine_hard_spi_make_new, diff --git a/ports/renesas-ra/modmachine.c b/ports/renesas-ra/modmachine.c index e6f78747fdba..7db36298db4a 100644 --- a/ports/renesas-ra/modmachine.c +++ b/ports/renesas-ra/modmachine.c @@ -286,7 +286,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, #endif #if MICROPY_PY_MACHINE_SPI - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hard_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, #endif { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, diff --git a/ports/renesas-ra/modmachine.h b/ports/renesas-ra/modmachine.h index de421c5db81f..5dbda6bda8ae 100644 --- a/ports/renesas-ra/modmachine.h +++ b/ports/renesas-ra/modmachine.h @@ -37,7 +37,7 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_adcblock_type; extern const mp_obj_type_t machine_dac_type; extern const mp_obj_type_t machine_i2c_type; -extern const mp_obj_type_t machine_hard_spi_type; +extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_i2s_type; extern const mp_obj_type_t machine_uart_type; extern const mp_obj_type_t machine_rtc_type; From 5e90ec233139e90b5dc022932b15b3bc9fd7865c Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 20:28:31 +0200 Subject: [PATCH 1878/4290] zephyr: Rename machine I2C and SPI types consistently across ports. This renames: - machine_hard_i2c_type -> machine_i2c_type - machine_hard_spi_type -> machine_spi_type --- ports/zephyr/machine_i2c.c | 4 ++-- ports/zephyr/machine_spi.c | 4 ++-- ports/zephyr/modmachine.c | 4 ++-- ports/zephyr/modmachine.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c index 8f0f25257ba5..c261ffad0d25 100644 --- a/ports/zephyr/machine_i2c.c +++ b/ports/zephyr/machine_i2c.c @@ -84,7 +84,7 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_raise_NotImplementedError(MP_ERROR_TEXT("explicit choice of timeout is not implemented")); } - machine_hard_i2c_obj_t *self = mp_obj_malloc(machine_hard_i2c_obj_t, &machine_hard_i2c_type); + machine_hard_i2c_obj_t *self = mp_obj_malloc(machine_hard_i2c_obj_t, &machine_i2c_type); self->dev = dev; self->restart = false; @@ -127,7 +127,7 @@ STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_i2c_type, + machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, make_new, machine_hard_i2c_make_new, diff --git a/ports/zephyr/machine_spi.c b/ports/zephyr/machine_spi.c index 19d4ae6dee68..507d839c6644 100644 --- a/ports/zephyr/machine_spi.c +++ b/ports/zephyr/machine_spi.c @@ -106,7 +106,7 @@ mp_obj_t machine_hard_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz .cs = NULL }; - machine_hard_spi_obj_t *self = mp_obj_malloc(machine_hard_spi_obj_t, &machine_hard_spi_type); + machine_hard_spi_obj_t *self = mp_obj_malloc(machine_hard_spi_obj_t, &machine_spi_type); self->dev = dev; self->config = cfg; @@ -198,7 +198,7 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_spi_type, + machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, make_new, machine_hard_spi_make_new, diff --git a/ports/zephyr/modmachine.c b/ports/zephyr/modmachine.c index 63bd3369897d..95a66c51199b 100644 --- a/ports/zephyr/modmachine.c +++ b/ports/zephyr/modmachine.c @@ -69,10 +69,10 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, #if MICROPY_PY_MACHINE_I2C - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hard_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, #endif #if MICROPY_PY_MACHINE_SPI - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hard_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, #endif { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, diff --git a/ports/zephyr/modmachine.h b/ports/zephyr/modmachine.h index a3cdd2b30fe6..a605ada0de76 100644 --- a/ports/zephyr/modmachine.h +++ b/ports/zephyr/modmachine.h @@ -4,8 +4,8 @@ #include "py/obj.h" extern const mp_obj_type_t machine_pin_type; -extern const mp_obj_type_t machine_hard_i2c_type; -extern const mp_obj_type_t machine_hard_spi_type; +extern const mp_obj_type_t machine_i2c_type; +extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_uart_type; MP_DECLARE_CONST_FUN_OBJ_0(machine_info_obj); From 93f3910fe7e43de5661ff0d6f961c6eccb8537e5 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Oct 2022 20:27:09 +0200 Subject: [PATCH 1879/4290] nrf: Rename machine I2C, PWM, SPI, UART types consistently across ports. This renames: - machine_hard_i2c_type -> machine_i2c_type - machine_hard_pwm_type -> machine_pwm_type - machine_hard_spi_type -> machine_spi_type - machine_hard_uart_type -> machine_uart_type --- ports/nrf/main.c | 2 +- ports/nrf/modules/machine/i2c.c | 6 +++--- ports/nrf/modules/machine/i2c.h | 2 +- ports/nrf/modules/machine/modmachine.c | 8 ++++---- ports/nrf/modules/machine/pwm.c | 16 ++++++++-------- ports/nrf/modules/machine/pwm.h | 2 +- ports/nrf/modules/machine/spi.c | 14 +++++++------- ports/nrf/modules/machine/spi.h | 2 +- ports/nrf/modules/machine/uart.c | 4 ++-- ports/nrf/modules/machine/uart.h | 2 +- ports/nrf/modules/uos/moduos.c | 2 +- 11 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ports/nrf/main.c b/ports/nrf/main.c index bcfaafd39c7e..989db58b3fa8 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -170,7 +170,7 @@ int main(int argc, char **argv) { MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_NEW_SMALL_INT(115200), }; - MP_STATE_PORT(board_stdio_uart) = MP_OBJ_TYPE_GET_SLOT(&machine_hard_uart_type, make_new)((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); + MP_STATE_PORT(board_stdio_uart) = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, MP_ARRAY_SIZE(args), 0, args); } #endif diff --git a/ports/nrf/modules/machine/i2c.c b/ports/nrf/modules/machine/i2c.c index c16c3669ec57..ac331b8d7af6 100644 --- a/ports/nrf/modules/machine/i2c.c +++ b/ports/nrf/modules/machine/i2c.c @@ -69,8 +69,8 @@ typedef struct _machine_hard_i2c_obj_t { } machine_hard_i2c_obj_t; STATIC const machine_hard_i2c_obj_t machine_hard_i2c_obj[] = { - {{&machine_hard_i2c_type}, .p_twi = NRFX_TWI_INSTANCE(0)}, - {{&machine_hard_i2c_type}, .p_twi = NRFX_TWI_INSTANCE(1)}, + {{&machine_i2c_type}, .p_twi = NRFX_TWI_INSTANCE(0)}, + {{&machine_i2c_type}, .p_twi = NRFX_TWI_INSTANCE(1)}, }; void i2c_init0(void) { @@ -162,7 +162,7 @@ STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_i2c_type, + machine_i2c_type, MP_QSTR_I2C, MP_TYPE_FLAG_NONE, make_new, machine_hard_i2c_make_new, diff --git a/ports/nrf/modules/machine/i2c.h b/ports/nrf/modules/machine/i2c.h index 1dfb1f077a44..5c5befc28535 100644 --- a/ports/nrf/modules/machine/i2c.h +++ b/ports/nrf/modules/machine/i2c.h @@ -29,7 +29,7 @@ #include "extmod/machine_i2c.h" -extern const mp_obj_type_t machine_hard_i2c_type; +extern const mp_obj_type_t machine_i2c_type; void i2c_init0(void); diff --git a/ports/nrf/modules/machine/modmachine.c b/ports/nrf/modules/machine/modmachine.c index d322e450671f..d315582ae6fd 100644 --- a/ports/nrf/modules/machine/modmachine.c +++ b/ports/nrf/modules/machine/modmachine.c @@ -217,13 +217,13 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, #if MICROPY_PY_MACHINE_UART - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_hard_uart_type) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, #endif #if MICROPY_PY_MACHINE_HW_SPI - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hard_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, #endif #if MICROPY_PY_MACHINE_I2C - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hard_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, #endif #if MICROPY_PY_MACHINE_ADC @@ -236,7 +236,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, #endif #if MICROPY_PY_MACHINE_HW_PWM - { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_hard_pwm_type) }, + { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, #endif #if MICROPY_PY_MACHINE_TEMP { MP_ROM_QSTR(MP_QSTR_Temp), MP_ROM_PTR(&machine_temp_type) }, diff --git a/ports/nrf/modules/machine/pwm.c b/ports/nrf/modules/machine/pwm.c index 862e1907cbf3..7c84a8c885f9 100644 --- a/ports/nrf/modules/machine/pwm.c +++ b/ports/nrf/modules/machine/pwm.c @@ -77,11 +77,11 @@ STATIC machine_pwm_config_t hard_configs[MP_ARRAY_SIZE(machine_hard_pwm_instance STATIC const machine_hard_pwm_obj_t machine_hard_pwm_obj[] = { #if defined(NRF52_SERIES) - {{&machine_hard_pwm_type}, .p_pwm = &machine_hard_pwm_instances[0], .p_config = &hard_configs[0]}, - {{&machine_hard_pwm_type}, .p_pwm = &machine_hard_pwm_instances[1], .p_config = &hard_configs[1]}, - {{&machine_hard_pwm_type}, .p_pwm = &machine_hard_pwm_instances[2], .p_config = &hard_configs[2]}, + {{&machine_pwm_type}, .p_pwm = &machine_hard_pwm_instances[0], .p_config = &hard_configs[0]}, + {{&machine_pwm_type}, .p_pwm = &machine_hard_pwm_instances[1], .p_config = &hard_configs[1]}, + {{&machine_pwm_type}, .p_pwm = &machine_hard_pwm_instances[2], .p_config = &hard_configs[2]}, #if NRF52840 - {{&machine_hard_pwm_type}, .p_pwm = &machine_hard_pwm_instances[3], .p_config = &hard_configs[3]}, + {{&machine_pwm_type}, .p_pwm = &machine_hard_pwm_instances[3], .p_config = &hard_configs[3]}, #endif #endif }; @@ -155,7 +155,7 @@ STATIC mp_obj_t machine_pwm_init(size_t n_args, const mp_obj_t *pos_args, mp_map mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // dispatch to specific implementation - if (mp_obj_get_type(self) == &machine_hard_pwm_type) { + if (mp_obj_get_type(self) == &machine_pwm_type) { machine_hard_pwm_init(self, args); } @@ -165,7 +165,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_pwm_init_obj, 1, machine_pwm_init); STATIC mp_obj_t machine_pwm_deinit(mp_obj_t self) { // dispatch to specific implementation - if (mp_obj_get_type(self) == &machine_hard_pwm_type) { + if (mp_obj_get_type(self) == &machine_pwm_type) { machine_hard_pwm_deinit(self); } return mp_const_none; @@ -182,7 +182,7 @@ STATIC mp_obj_t machine_pwm_freq(size_t n_args, const mp_obj_t *pos_args, mp_map mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (mp_obj_get_type(self) == &machine_hard_pwm_type) { + if (mp_obj_get_type(self) == &machine_pwm_type) { machine_hard_pwm_freq(self, args); } else { // soft pwm @@ -340,7 +340,7 @@ STATIC mp_obj_t machine_hard_pwm_freq(mp_obj_t self_in, mp_arg_val_t *args) { } MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_pwm_type, + machine_pwm_type, MP_QSTR_PWM, MP_TYPE_FLAG_NONE, make_new, machine_pwm_make_new, diff --git a/ports/nrf/modules/machine/pwm.h b/ports/nrf/modules/machine/pwm.h index 7a5b72e0e84f..ab2d927fa4e5 100644 --- a/ports/nrf/modules/machine/pwm.h +++ b/ports/nrf/modules/machine/pwm.h @@ -26,4 +26,4 @@ void pwm_init0(void); -extern const mp_obj_type_t machine_hard_pwm_type; +extern const mp_obj_type_t machine_pwm_type; diff --git a/ports/nrf/modules/machine/spi.c b/ports/nrf/modules/machine/spi.c index fd7f7bb5bcce..0dee20027b2d 100644 --- a/ports/nrf/modules/machine/spi.c +++ b/ports/nrf/modules/machine/spi.c @@ -117,12 +117,12 @@ STATIC const nrfx_spi_t machine_spi_instances[] = { STATIC nrfx_spi_config_t configs[MP_ARRAY_SIZE(machine_spi_instances)]; STATIC const machine_hard_spi_obj_t machine_hard_spi_obj[] = { - {{&machine_hard_spi_type}, .p_spi = &machine_spi_instances[0], .p_config = &configs[0]}, - {{&machine_hard_spi_type}, .p_spi = &machine_spi_instances[1], .p_config = &configs[1]}, + {{&machine_spi_type}, .p_spi = &machine_spi_instances[0], .p_config = &configs[0]}, + {{&machine_spi_type}, .p_spi = &machine_spi_instances[1], .p_config = &configs[1]}, #if defined(NRF52_SERIES) - {{&machine_hard_spi_type}, .p_spi = &machine_spi_instances[2], .p_config = &configs[2]}, + {{&machine_spi_type}, .p_spi = &machine_spi_instances[2], .p_config = &configs[2]}, #if defined(NRF52840_XXAA) && NRFX_SPIM_ENABLED - {{&machine_hard_spi_type}, .p_spi = &machine_spi_instances[3], .p_config = &configs[3]}, + {{&machine_spi_type}, .p_spi = &machine_spi_instances[3], .p_config = &configs[3]}, #endif // NRF52840_XXAA && NRFX_SPIM_ENABLED #endif // NRF52_SERIES }; @@ -235,7 +235,7 @@ STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *pos_args, mp_map mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // dispatch to specific implementation - if (mp_obj_get_type(self) == &machine_hard_spi_type) { + if (mp_obj_get_type(self) == &machine_spi_type) { machine_hard_spi_init(self, args); } @@ -245,7 +245,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_spi_init_obj, 1, machine_spi_init); STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) { // dispatch to specific implementation - if (mp_obj_get_type(self) == &machine_hard_spi_type) { + if (mp_obj_get_type(self) == &machine_spi_type) { machine_hard_spi_deinit(self); } return mp_const_none; @@ -428,7 +428,7 @@ STATIC const mp_machine_spi_p_t machine_hard_spi_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_spi_type, + machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, make_new, machine_spi_make_new, diff --git a/ports/nrf/modules/machine/spi.h b/ports/nrf/modules/machine/spi.h index c6f64a19da2a..e1505781ac38 100644 --- a/ports/nrf/modules/machine/spi.h +++ b/ports/nrf/modules/machine/spi.h @@ -27,7 +27,7 @@ #include "py/obj.h" typedef struct _machine_hard_spi_obj_t machine_hard_spi_obj_t; -extern const mp_obj_type_t machine_hard_spi_type; +extern const mp_obj_type_t machine_spi_type; void spi_init0(void); void spi_transfer(const machine_hard_spi_obj_t * self, diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index 035a30df9c01..eee5b8b79eac 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -106,7 +106,7 @@ static const nrfx_uart_t instance0 = NRFX_UART_INSTANCE(0); STATIC machine_hard_uart_buf_t machine_hard_uart_buf[1]; STATIC const machine_hard_uart_obj_t machine_hard_uart_obj[] = { - {{&machine_hard_uart_type}, .p_uart = &instance0, .buf = &machine_hard_uart_buf[0]}, + {{&machine_uart_type}, .p_uart = &instance0, .buf = &machine_hard_uart_buf[0]}, }; void uart_init0(void) { @@ -371,7 +371,7 @@ STATIC const mp_stream_p_t uart_stream_p = { }; MP_DEFINE_CONST_OBJ_TYPE( - machine_hard_uart_type, + machine_uart_type, MP_QSTR_UART, MP_TYPE_FLAG_ITER_IS_STREAM, make_new, machine_hard_uart_make_new, diff --git a/ports/nrf/modules/machine/uart.h b/ports/nrf/modules/machine/uart.h index 121f83cd39b3..d3e23645b902 100644 --- a/ports/nrf/modules/machine/uart.h +++ b/ports/nrf/modules/machine/uart.h @@ -32,7 +32,7 @@ #include "genhdr/pins.h" typedef struct _machine_hard_uart_obj_t machine_hard_uart_obj_t; -extern const mp_obj_type_t machine_hard_uart_type; +extern const mp_obj_type_t machine_uart_type; void uart_init0(void); void uart_deinit(void); diff --git a/ports/nrf/modules/uos/moduos.c b/ports/nrf/modules/uos/moduos.c index 3fdd8eb19ec1..402096aacd78 100644 --- a/ports/nrf/modules/uos/moduos.c +++ b/ports/nrf/modules/uos/moduos.c @@ -126,7 +126,7 @@ STATIC mp_obj_t os_dupterm(mp_uint_t n_args, const mp_obj_t *args) { } else { if (args[0] == mp_const_none) { MP_STATE_PORT(board_stdio_uart) = NULL; - } else if (mp_obj_get_type(args[0]) == &machine_hard_uart_type) { + } else if (mp_obj_get_type(args[0]) == &machine_uart_type) { MP_STATE_PORT(board_stdio_uart) = args[0]; } else { mp_raise_ValueError(MP_ERROR_TEXT("need a UART object")); From 4f946ba963b452cb79524225e0a88134921f2ebb Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 8 Sep 2022 12:51:10 +1000 Subject: [PATCH 1880/4290] lib/btstack: Update to v1.5.3. Signed-off-by: Damien George --- lib/btstack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/btstack b/lib/btstack index c8b9823f68c6..87087689bb0c 160000 --- a/lib/btstack +++ b/lib/btstack @@ -1 +1 @@ -Subproject commit c8b9823f68c6af0fa52e2c4e009aba4dbf257232 +Subproject commit 87087689bb0c37ff4b9b3e3ba670b7019c306ebd From 67f98ba10c3d894e737f275f0a508b7ccf4f1807 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 8 Sep 2022 12:51:19 +1000 Subject: [PATCH 1881/4290] extmod/btstack: Update BTstack bindings to work with latest BTstack. The following multi-tests pass (eg with PYBD_SF6+LEGO_HUB_NO6): ble_gap_advertise.py ble_gap_connect.py ble_gap_device_name.py ble_gattc_discover_services.py ble_gatt_data_transfer.py perf_gatt_char_write.py perf_gatt_notify.py stress_log_filesystem.py These are the same tests that passed prior to this BTstack update. Also tested on the unix port using H4 transport. Signed-off-by: Damien George --- extmod/btstack/btstack_config.h | 2 +- extmod/btstack/btstack_hci_uart.c | 6 ++++++ extmod/btstack/btstack_hci_uart.h | 2 +- extmod/btstack/modbluetooth_btstack.c | 28 ++++++++++++++++++++++----- ports/stm32/mpbtstackport.c | 11 +++-------- ports/unix/mpbtstackport_common.c | 8 +------- ports/unix/mpbtstackport_h4.c | 14 ++++++++------ ports/unix/mpbtstackport_usb.c | 1 + 8 files changed, 44 insertions(+), 28 deletions(-) diff --git a/extmod/btstack/btstack_config.h b/extmod/btstack/btstack_config.h index e56a84f94a16..7de938cb6f7e 100644 --- a/extmod/btstack/btstack_config.h +++ b/extmod/btstack/btstack_config.h @@ -6,7 +6,7 @@ #define ENABLE_LE_PERIPHERAL #define ENABLE_LE_CENTRAL // #define ENABLE_CLASSIC -#define ENABLE_LE_DATA_CHANNELS +#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE // #define ENABLE_LOG_INFO // #define ENABLE_LOG_DEBUG #define ENABLE_LOG_ERROR diff --git a/extmod/btstack/btstack_hci_uart.c b/extmod/btstack/btstack_hci_uart.c index 83e865b71d2d..f945efc762cb 100644 --- a/extmod/btstack/btstack_hci_uart.c +++ b/extmod/btstack/btstack_hci_uart.c @@ -159,6 +159,12 @@ const btstack_uart_block_t mp_bluetooth_btstack_hci_uart_block = { &btstack_uart_get_supported_sleep_modes, &btstack_uart_set_sleep, &btstack_uart_set_wakeup_handler, + + // The following are needed for H5 mode only. + NULL, // set_frame_received + NULL, // set_frame_sent, + NULL, // receive_frame, + NULL, // send_frame, }; void mp_bluetooth_btstack_hci_uart_process(void) { diff --git a/extmod/btstack/btstack_hci_uart.h b/extmod/btstack/btstack_hci_uart.h index 8011e587dee3..74983808ec28 100644 --- a/extmod/btstack/btstack_hci_uart.h +++ b/extmod/btstack/btstack_hci_uart.h @@ -28,7 +28,7 @@ #ifndef MICROPY_INCLUDED_EXTMOD_BTSTACK_HCI_UART_H #define MICROPY_INCLUDED_EXTMOD_BTSTACK_HCI_UART_H -#include "lib/btstack/src/btstack.h" +#include "lib/btstack/src/btstack_uart_block.h" // --- Used by the port to create the HCI transport --------------------------- extern const btstack_uart_block_t mp_bluetooth_btstack_hci_uart_block; diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index b58be78a9942..e9c0037394b2 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -368,7 +368,7 @@ STATIC void btstack_packet_handler(uint8_t packet_type, uint8_t *packet, uint8_t event_type == SM_EVENT_PAIRING_COMPLETE || // event_type == GAP_EVENT_DEDICATED_BONDING_COMPLETED || // No conn_handle event_type == HCI_EVENT_ENCRYPTION_CHANGE) { - DEBUG_printf(" --> enc/auth/pair/bond change\n", ); + DEBUG_printf(" --> enc/auth/pair/bond change\n"); #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING uint16_t conn_handle; switch (event_type) { @@ -420,6 +420,11 @@ STATIC void btstack_packet_handler(uint8_t packet_type, uint8_t *packet, uint8_t mp_bluetooth_gap_on_scan_result(address_type, address, adv_event_type, rssi, data, length); #endif // MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE #if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT + } else if (event_type == GATT_EVENT_MTU) { + // This is triggered in client mode. + uint16_t conn_handle = gatt_event_mtu_get_handle(packet); + uint16_t mtu = gatt_event_mtu_get_MTU(packet); + mp_bluetooth_gatts_on_mtu_exchanged(conn_handle, mtu); } else if (event_type == GATT_EVENT_QUERY_COMPLETE) { uint16_t conn_handle = gatt_event_query_complete_get_handle(packet); uint16_t status = gatt_event_query_complete_get_att_status(packet); @@ -625,6 +630,19 @@ STATIC void set_random_address(void) { DEBUG_printf("set_random_address: Address loaded by controller\n"); } +STATIC void deinit_stack(void) { + mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_OFF; + + // Deinitialise BTstack components. + sm_deinit(); + l2cap_deinit(); + hci_deinit(); + btstack_memory_deinit(); + btstack_run_loop_deinit(); + + MP_STATE_PORT(bluetooth_btstack_root_pointers) = NULL; +} + int mp_bluetooth_init(void) { DEBUG_printf("mp_bluetooth_init\n"); @@ -702,8 +720,8 @@ int mp_bluetooth_init(void) { // Attempt a shutdown (may not do anything). mp_bluetooth_btstack_port_deinit(); - // Clean up. - MP_STATE_PORT(bluetooth_btstack_root_pointers) = NULL; + // Clean up BTstack. + deinit_stack(); return timeout ? MP_ETIMEDOUT : MP_EINVAL; } @@ -757,8 +775,8 @@ void mp_bluetooth_deinit(void) { } btstack_run_loop_remove_timer(&btstack_init_deinit_timeout); - mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_OFF; - MP_STATE_PORT(bluetooth_btstack_root_pointers) = NULL; + // Clean up BTstack. + deinit_stack(); DEBUG_printf("mp_bluetooth_deinit: complete\n"); } diff --git a/ports/stm32/mpbtstackport.c b/ports/stm32/mpbtstackport.c index 795534042eae..301ac30e2060 100644 --- a/ports/stm32/mpbtstackport.c +++ b/ports/stm32/mpbtstackport.c @@ -31,6 +31,7 @@ #if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_BTSTACK #include "lib/btstack/src/btstack.h" +#include "lib/btstack/src/hci_transport_h4.h" #include "extmod/mpbthci.h" #include "extmod/btstack/btstack_hci_uart.h" #include "extmod/btstack/modbluetooth_btstack.h" @@ -137,16 +138,10 @@ void mp_bluetooth_hci_poll(void) { } void mp_bluetooth_btstack_port_init(void) { - static bool run_loop_init = false; - if (!run_loop_init) { - run_loop_init = true; - btstack_run_loop_init(&mp_btstack_runloop_stm32); - } else { - mp_btstack_runloop_stm32.init(); - } + btstack_run_loop_init(&mp_btstack_runloop_stm32); // hci_dump_open(NULL, HCI_DUMP_STDOUT); - const hci_transport_t *transport = hci_transport_h4_instance(&mp_bluetooth_btstack_hci_uart_block); + const hci_transport_t *transport = hci_transport_h4_instance_for_uart(&mp_bluetooth_btstack_hci_uart_block); hci_init(transport, &hci_transport_config_uart); #ifdef MICROPY_HW_BLE_BTSTACK_CHIPSET_INSTANCE diff --git a/ports/unix/mpbtstackport_common.c b/ports/unix/mpbtstackport_common.c index ec40db65bc3a..66a3a0536aed 100644 --- a/ports/unix/mpbtstackport_common.c +++ b/ports/unix/mpbtstackport_common.c @@ -79,13 +79,7 @@ uint32_t hal_time_ms(void) { } void mp_bluetooth_btstack_port_init(void) { - static bool run_loop_init = false; - if (!run_loop_init) { - run_loop_init = true; - btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); - } else { - btstack_run_loop_embedded_get_instance()->init(); - } + btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); // hci_dump_open(NULL, HCI_DUMP_STDOUT); diff --git a/ports/unix/mpbtstackport_h4.c b/ports/unix/mpbtstackport_h4.c index 4fdc20c22b69..dacfff9a498a 100644 --- a/ports/unix/mpbtstackport_h4.c +++ b/ports/unix/mpbtstackport_h4.c @@ -32,6 +32,7 @@ #if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_BTSTACK && MICROPY_BLUETOOTH_BTSTACK_H4 +#include "lib/btstack/src/hci_transport_h4.h" #include "lib/btstack/chipset/zephyr/btstack_chipset_zephyr.h" #include "extmod/btstack/btstack_hci_uart.h" @@ -42,11 +43,12 @@ #define DEBUG_printf(...) // printf(__VA_ARGS__) STATIC hci_transport_config_uart_t hci_transport_config_uart = { - HCI_TRANSPORT_CONFIG_UART, - 1000000, // initial baudrate - 0, // main baudrate - 1, // flow control - NULL, // device name + .type = HCI_TRANSPORT_CONFIG_UART, + .baudrate_init = 1000000, + .baudrate_main = 0, + .flowcontrol = 1, + .device_name = NULL, + .parity = BTSTACK_UART_PARITY_OFF, }; void mp_bluetooth_hci_poll_h4(void) { @@ -58,7 +60,7 @@ void mp_bluetooth_hci_poll_h4(void) { void mp_bluetooth_btstack_port_init_h4(void) { DEBUG_printf("mp_bluetooth_btstack_port_init_h4\n"); - const hci_transport_t *transport = hci_transport_h4_instance(&mp_bluetooth_btstack_hci_uart_block); + const hci_transport_t *transport = hci_transport_h4_instance_for_uart(&mp_bluetooth_btstack_hci_uart_block); hci_init(transport, &hci_transport_config_uart); hci_set_chipset(btstack_chipset_zephyr_instance()); diff --git a/ports/unix/mpbtstackport_usb.c b/ports/unix/mpbtstackport_usb.c index 28d2c8c543f7..b8c7b758d93e 100644 --- a/ports/unix/mpbtstackport_usb.c +++ b/ports/unix/mpbtstackport_usb.c @@ -34,6 +34,7 @@ #if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_BTSTACK && MICROPY_BLUETOOTH_BTSTACK_USB #include "lib/btstack/src/btstack.h" +#include "lib/btstack/src/hci_transport_usb.h" #include "lib/btstack/platform/embedded/btstack_run_loop_embedded.h" #include "lib/btstack/platform/embedded/hal_cpu.h" #include "lib/btstack/platform/embedded/hal_time_ms.h" From b33767896430a36f163c0f9bb7020e688ccb9c5b Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 5 Oct 2022 10:46:11 +1100 Subject: [PATCH 1882/4290] extmod/mbedtls: Add common configuration file, and use it in all ports. This is a no-op change. Signed-off-by: Damien George --- extmod/mbedtls/mbedtls_config_common.h | 110 +++++++++++++++++++++++++ ports/mimxrt/mbedtls/mbedtls_config.h | 69 +--------------- ports/rp2/mbedtls/mbedtls_config.h | 73 ++-------------- ports/stm32/mbedtls/mbedtls_config.h | 69 +--------------- ports/unix/mbedtls/mbedtls_config.h | 58 +------------ 5 files changed, 125 insertions(+), 254 deletions(-) create mode 100644 extmod/mbedtls/mbedtls_config_common.h diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h new file mode 100644 index 000000000000..6c9385dea5f7 --- /dev/null +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -0,0 +1,110 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018-2022 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H +#define MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H + +// If you want to debug MBEDTLS uncomment the following and +// pass "3" to mbedtls_debug_set_threshold in socket_new. +// #define MBEDTLS_DEBUG_C + +// Set mbedtls configuration. +#define MBEDTLS_DEPRECATED_REMOVED +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_SSL_PROTO_TLS1 +#define MBEDTLS_SSL_PROTO_TLS1_1 +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +// Use a smaller output buffer to reduce size of SSL context. +#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) +#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) +#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) + +// Enable mbedtls modules. +#define MBEDTLS_AES_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_ERROR_C +#define MBEDTLS_MD_C +#define MBEDTLS_MD5_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS5_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_RSA_C +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_USE_C + +// A port may enable this option to select additional bare-metal configuration. +#if MICROPY_MBEDTLS_CONFIG_BARE_METAL + +// Bare-metal mbedtls configuration. +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_ENTROPY_HARDWARE_ALT + +// Bare-metal memory allocation hooks. +#include +#include +void *m_tracked_calloc(size_t nmemb, size_t size); +void m_tracked_free(void *ptr); +#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc +#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +#endif + +// Include mbedtls configuration checker. +#include "mbedtls/check_config.h" + +#endif // MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H diff --git a/ports/mimxrt/mbedtls/mbedtls_config.h b/ports/mimxrt/mbedtls/mbedtls_config.h index 8e054ed51713..cc71aa7ec113 100644 --- a/ports/mimxrt/mbedtls/mbedtls_config.h +++ b/ports/mimxrt/mbedtls/mbedtls_config.h @@ -26,74 +26,13 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H -// Set mbedtls configuration -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_DEPRECATED_REMOVED -#define MBEDTLS_ENTROPY_HARDWARE_ALT -#define MBEDTLS_AES_ROM_TABLES -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_SHA256_SMALLER -#define MBEDTLS_SSL_PROTO_TLS1 -#define MBEDTLS_SSL_PROTO_TLS1_1 -#define MBEDTLS_SSL_PROTO_TLS1_2 -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -// Use a smaller output buffer to reduce size of SSL context -#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) -#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) - // Enable mbedtls modules -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C // #define MBEDTLS_ECP_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_ERROR_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS5_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_USE_C -// Memory allocation hooks -#include -#include -void *m_tracked_calloc(size_t nmemb, size_t size); -void m_tracked_free(void *ptr); -#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc -#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free -#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf +// Set MicroPython-specific options. +#define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) -#include "mbedtls/check_config.h" +// Include common mbedtls configuration. +#include "extmod/mbedtls/mbedtls_config_common.h" #endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/rp2/mbedtls/mbedtls_config.h b/ports/rp2/mbedtls/mbedtls_config.h index c80aa5bc18c2..61f622295ffa 100644 --- a/ports/rp2/mbedtls/mbedtls_config.h +++ b/ports/rp2/mbedtls/mbedtls_config.h @@ -26,90 +26,27 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H -// If you want to debug MBEDTLS uncomment the following and -// Pass 3 to mbedtls_debug_set_threshold in socket_new -// #define MBEDTLS_DEBUG_C - // Set mbedtls configuration -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_DEPRECATED_REMOVED -#define MBEDTLS_ENTROPY_HARDWARE_ALT -#define MBEDTLS_AES_ROM_TABLES -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED #define MBEDTLS_ECP_NIST_OPTIM #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_SHA256_SMALLER -#define MBEDTLS_SSL_PROTO_TLS1 -#define MBEDTLS_SSL_PROTO_TLS1_1 -#define MBEDTLS_SSL_PROTO_TLS1_2 -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -// Use a smaller output buffer to reduce size of SSL context -#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) -#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) // Enable mbedtls modules -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C #define MBEDTLS_ECDH_C #define MBEDTLS_ECP_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_ERROR_C #define MBEDTLS_GCM_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS5_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_USE_C #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE -// Memory allocation hooks -#include -#include -void *m_tracked_calloc(size_t nmemb, size_t size); -void m_tracked_free(void *ptr); -#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc -#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free -#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf - // Time hook #include time_t rp2_rtctime_seconds(time_t *timer); #define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds -#include "mbedtls/check_config.h" +// Set MicroPython-specific options. +#define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) + +// Include common mbedtls configuration. +#include "extmod/mbedtls/mbedtls_config_common.h" #endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/stm32/mbedtls/mbedtls_config.h b/ports/stm32/mbedtls/mbedtls_config.h index 2e0cb7651a48..b8548866f168 100644 --- a/ports/stm32/mbedtls/mbedtls_config.h +++ b/ports/stm32/mbedtls/mbedtls_config.h @@ -26,75 +26,14 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H -// Set mbedtls configuration -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_DEPRECATED_REMOVED -#define MBEDTLS_ENTROPY_HARDWARE_ALT -#define MBEDTLS_AES_ROM_TABLES -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_SHA256_SMALLER -#define MBEDTLS_SSL_PROTO_TLS1 -#define MBEDTLS_SSL_PROTO_TLS1_1 -#define MBEDTLS_SSL_PROTO_TLS1_2 -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -// Use a smaller output buffer to reduce size of SSL context -#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) -#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) - // Enable mbedtls modules -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C // #define MBEDTLS_ECP_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_ERROR_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS5_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_USE_C -// Memory allocation hooks -#include -#include -void *m_tracked_calloc(size_t nmemb, size_t size); -void m_tracked_free(void *ptr); -#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc -#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free -#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf +// Set MicroPython-specific options. +#define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) -#include "mbedtls/check_config.h" +// Include common mbedtls configuration. +#include "extmod/mbedtls/mbedtls_config_common.h" #endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/unix/mbedtls/mbedtls_config.h b/ports/unix/mbedtls/mbedtls_config.h index b119d09092f0..c83f1c86f3dd 100644 --- a/ports/unix/mbedtls/mbedtls_config.h +++ b/ports/unix/mbedtls/mbedtls_config.h @@ -26,69 +26,15 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H -// If you want to debug MBEDTLS uncomment the following and -// Pass 3 to mbedtls_debug_set_threshold in socket_new -// #define MBEDTLS_DEBUG_C - // Set mbedtls configuration -#define MBEDTLS_DEPRECATED_REMOVED -#define MBEDTLS_AES_ROM_TABLES -#define MBEDTLS_CIPHER_MODE_CBC #define MBEDTLS_CIPHER_MODE_CTR // needed for MICROPY_PY_UCRYPTOLIB_CTR -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_SHA256_SMALLER -#define MBEDTLS_SSL_PROTO_TLS1 -#define MBEDTLS_SSL_PROTO_TLS1_1 -#define MBEDTLS_SSL_PROTO_TLS1_2 -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -// Use a smaller output buffer to reduce size of SSL context -#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) -#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) // Enable mbedtls modules -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_ERROR_C #define MBEDTLS_HAVEGE_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS5_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C #define MBEDTLS_TIMING_C #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_USE_C -#include "mbedtls/check_config.h" +// Include common mbedtls configuration. +#include "extmod/mbedtls/mbedtls_config_common.h" #endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ From 9347545f9ee66210a835cb2f1e9860949feb139f Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 5 Oct 2022 10:48:31 +1100 Subject: [PATCH 1883/4290] extmod/mbedtls: Enable MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE. This was already enabled on all ports except mimxrt. Now it's enabled on all of them. Signed-off-by: Damien George --- extmod/mbedtls/mbedtls_config_common.h | 1 + ports/rp2/mbedtls/mbedtls_config.h | 1 - ports/stm32/mbedtls/mbedtls_config.h | 1 - ports/unix/mbedtls/mbedtls_config.h | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h index 6c9385dea5f7..4c2be6228af0 100644 --- a/extmod/mbedtls/mbedtls_config_common.h +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -82,6 +82,7 @@ #define MBEDTLS_SSL_CLI_C #define MBEDTLS_SSL_SRV_C #define MBEDTLS_SSL_TLS_C +#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE #define MBEDTLS_X509_CRT_PARSE_C #define MBEDTLS_X509_USE_C diff --git a/ports/rp2/mbedtls/mbedtls_config.h b/ports/rp2/mbedtls/mbedtls_config.h index 61f622295ffa..9c930b7d9c49 100644 --- a/ports/rp2/mbedtls/mbedtls_config.h +++ b/ports/rp2/mbedtls/mbedtls_config.h @@ -34,7 +34,6 @@ #define MBEDTLS_ECDH_C #define MBEDTLS_ECP_C #define MBEDTLS_GCM_C -#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE diff --git a/ports/stm32/mbedtls/mbedtls_config.h b/ports/stm32/mbedtls/mbedtls_config.h index b8548866f168..cc71aa7ec113 100644 --- a/ports/stm32/mbedtls/mbedtls_config.h +++ b/ports/stm32/mbedtls/mbedtls_config.h @@ -28,7 +28,6 @@ // Enable mbedtls modules // #define MBEDTLS_ECP_C -#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE // Set MicroPython-specific options. #define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) diff --git a/ports/unix/mbedtls/mbedtls_config.h b/ports/unix/mbedtls/mbedtls_config.h index c83f1c86f3dd..c8ffab0832a1 100644 --- a/ports/unix/mbedtls/mbedtls_config.h +++ b/ports/unix/mbedtls/mbedtls_config.h @@ -32,7 +32,6 @@ // Enable mbedtls modules #define MBEDTLS_HAVEGE_C #define MBEDTLS_TIMING_C -#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE // Include common mbedtls configuration. #include "extmod/mbedtls/mbedtls_config_common.h" From 8874a09119e74bb0edf73a63495b559d983767b7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 5 Oct 2022 11:02:47 +1100 Subject: [PATCH 1884/4290] extmod/mbedtls: Enable elliptic curve DH and DSA cryptography. This is necessary to access sites that only support these protocols. The rp2 port already has ECDH enabled, so this just adds ECDSA there. The other ports now gain both ECDH and ECDSA. The code size increase is: - rp2 (PICO_W): +2916 bytes flash, +24 bytes BSS - stm32 (PYBD_SF6): +20480 bytes flash, +32 bytes data, +48 bytes BSS - mimxrt (TEENSY41): +20708 bytes flash, +32 bytes data, +48 bytes BSS - unix (standard x86-64): +39344 executable, +1744 bytes data, +96 BSS This is obviously a large increase in code size. But there doesn't seem to be any other option because without elliptic curve cryptography devices are partially cut off from the internet. For use cases that require small firmware size, they'll need to build custom firmware with a custom mbedtls config. Signed-off-by: Damien George --- extmod/mbedtls/mbedtls_config_common.h | 6 ++++++ ports/mimxrt/mbedtls/mbedtls_config.h | 3 --- ports/rp2/mbedtls/mbedtls_config.h | 2 -- ports/stm32/mbedtls/mbedtls_config.h | 3 --- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h index 4c2be6228af0..252f293e0337 100644 --- a/extmod/mbedtls/mbedtls_config_common.h +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -47,6 +47,8 @@ #define MBEDTLS_ECP_DP_BP512R1_ENABLED #define MBEDTLS_ECP_DP_CURVE25519_ENABLED #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED // enabling this currently breaks ssl_data.py test +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #define MBEDTLS_NO_PLATFORM_ENTROPY #define MBEDTLS_PKCS1_V15 #define MBEDTLS_SHA256_SMALLER @@ -63,9 +65,13 @@ // Enable mbedtls modules. #define MBEDTLS_AES_C #define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C #define MBEDTLS_BIGNUM_C #define MBEDTLS_CIPHER_C #define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C #define MBEDTLS_ENTROPY_C #define MBEDTLS_ERROR_C #define MBEDTLS_MD_C diff --git a/ports/mimxrt/mbedtls/mbedtls_config.h b/ports/mimxrt/mbedtls/mbedtls_config.h index cc71aa7ec113..4140bb514555 100644 --- a/ports/mimxrt/mbedtls/mbedtls_config.h +++ b/ports/mimxrt/mbedtls/mbedtls_config.h @@ -26,9 +26,6 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H -// Enable mbedtls modules -// #define MBEDTLS_ECP_C - // Set MicroPython-specific options. #define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) diff --git a/ports/rp2/mbedtls/mbedtls_config.h b/ports/rp2/mbedtls/mbedtls_config.h index 9c930b7d9c49..1b6d3dd43a65 100644 --- a/ports/rp2/mbedtls/mbedtls_config.h +++ b/ports/rp2/mbedtls/mbedtls_config.h @@ -31,8 +31,6 @@ #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED // Enable mbedtls modules -#define MBEDTLS_ECDH_C -#define MBEDTLS_ECP_C #define MBEDTLS_GCM_C #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE diff --git a/ports/stm32/mbedtls/mbedtls_config.h b/ports/stm32/mbedtls/mbedtls_config.h index cc71aa7ec113..4140bb514555 100644 --- a/ports/stm32/mbedtls/mbedtls_config.h +++ b/ports/stm32/mbedtls/mbedtls_config.h @@ -26,9 +26,6 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_H -// Enable mbedtls modules -// #define MBEDTLS_ECP_C - // Set MicroPython-specific options. #define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) From e24159dec9588d83fc532aa6fcc2f418aae9df85 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2022 19:22:48 +1100 Subject: [PATCH 1885/4290] extmod/mbedtls: Remove MBEDTLS_ECP_DP_CURVE25519_ENABLED config. Curve25519 arithmetic is supported in mbedtls, but it's not used for TLS. So there's no need to have this option enabled. Reduces rp2 PICO_W firmware by 2440 bytes. Thanks to @Carglglz for the information. Signed-off-by: Damien George --- extmod/mbedtls/mbedtls_config_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h index 252f293e0337..9ec2af85537f 100644 --- a/extmod/mbedtls/mbedtls_config_common.h +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -45,7 +45,6 @@ #define MBEDTLS_ECP_DP_BP256R1_ENABLED #define MBEDTLS_ECP_DP_BP384R1_ENABLED #define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED // #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED // enabling this currently breaks ssl_data.py test #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED From 68f166dae9ad6dfd94038d5f4394defbb44238af Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2022 19:25:05 +1100 Subject: [PATCH 1886/4290] extmod/mbedtls: Remove brainpool curves from config. They are much slower than NIST (SECP) curves and shouldn't be needed. Reduces rp2 PICO_W firmware by 1328 bytes. Thanks to @Carglglz for the information. Signed-off-by: Damien George --- extmod/mbedtls/mbedtls_config_common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h index 9ec2af85537f..bfbc6f7ba298 100644 --- a/extmod/mbedtls/mbedtls_config_common.h +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -42,9 +42,6 @@ #define MBEDTLS_ECP_DP_SECP192K1_ENABLED #define MBEDTLS_ECP_DP_SECP224K1_ENABLED #define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED // #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED // enabling this currently breaks ssl_data.py test #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED From b161abc574b8e4fb2b00ef76be2b9c8967e18584 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 18 Oct 2022 00:18:54 +1100 Subject: [PATCH 1887/4290] py/obj: Verify floating point type is correct for repr C. Prevents double-precision floats being enabled on 32-bit architectures where they will not fit into the mp_obj_t encoding. Signed-off-by: Jim Mussared --- py/obj.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/py/obj.h b/py/obj.h index 8aa5b0a8e667..8d62dd4f3cf0 100644 --- a/py/obj.h +++ b/py/obj.h @@ -173,6 +173,10 @@ static inline bool mp_obj_is_obj(mp_const_obj_t o) { #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_NONE +#error "MICROPY_OBJ_REPR_C requires float to be enabled." +#endif + static inline bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } @@ -189,6 +193,9 @@ static inline bool mp_obj_is_small_int(mp_const_obj_t o) { #endif static inline bool mp_obj_is_float(mp_const_obj_t o) { + // Ensure that 32-bit arch can only use single precision. + MP_STATIC_ASSERT(sizeof(mp_float_t) <= sizeof(mp_obj_t)); + return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0xff800007) != 0x00000006; } static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { From 5ee1cb27711d3747747db3ecd7b761c2a064addf Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 18 Oct 2022 00:22:53 +1100 Subject: [PATCH 1888/4290] stm32/boards/ARDUINO_PORTENTA_H7: Revert to single-precision float. Using repr C is incompatible with double-precision floats on 32-bit arch. Signed-off-by: Jim Mussared --- ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.mk b/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.mk index e5b48d0644f0..7151a5abc5d7 100644 --- a/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.mk +++ b/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.mk @@ -10,7 +10,7 @@ BOOTLOADER_DFU_USB_PID = 0x035b # MCU settings MCU_SERIES = h7 CMSIS_MCU = STM32H747xx -MICROPY_FLOAT_IMPL = double +MICROPY_FLOAT_IMPL = single AF_FILE = boards/stm32h743_af.csv LD_FILES = boards/ARDUINO_PORTENTA_H7/stm32h747.ld TEXT0_ADDR = 0x08040000 From 1ba0e8ff96334af986d2b7d90f6d86af27595d28 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Thu, 20 Oct 2022 13:14:25 +1100 Subject: [PATCH 1889/4290] py/persistentcode: Only emit sub-version if generated code has native. In order for v1.19.1 to load a .mpy, the formerly-feature-flags which are now used for the sub-version must be zero. The sub-version is only used to indicate a native version change, so it should be zero when emitting bytecode-only .mpy files. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- py/persistentcode.c | 7 ++----- tools/mpy-tool.py | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/py/persistentcode.c b/py/persistentcode.c index 67c8f327f002..5408f756cf8f 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -591,21 +591,18 @@ void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print) { // header contains: // byte 'M' // byte version - // byte feature flags + // byte native arch (and sub-version if native) // byte number of bits in a small int byte header[4] = { 'M', MPY_VERSION, - MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION), + cm->has_native ? MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION) | MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC) : 0, #if MICROPY_DYNAMIC_COMPILER mp_dynamic_compiler.small_int_bits, #else MP_SMALL_INT_BITS, #endif }; - if (cm->has_native) { - header[2] |= MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC); - } mp_print_bytes(print, header, sizeof(header)); // Number of entries in constant table. diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 8b644c137f4c..0b8a0403ca28 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -1676,7 +1676,7 @@ def merge_mpy(compiled_modules, output_file): header = bytearray(4) header[0] = ord("M") header[1] = config.MPY_VERSION - header[2] = config.native_arch << 2 | config.MPY_SUB_VERSION + header[2] = config.native_arch << 2 | config.MPY_SUB_VERSION if config.native_arch else 0 header[3] = config.mp_small_int_bits merged_mpy.extend(header) From edc3f3d0d3c4099dc6bce5371df0e1c3c5a4aecb Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 29 Jun 2022 15:31:21 +0200 Subject: [PATCH 1890/4290] samd/clock_config: Extend the range of machine.freq(). The value given for machine.freq(f) is extend to the range of 1_000_000 to 200_000_000. Frequencies below 48 MHz will be forced to an integer fraction of 48 MHz. At frequencies below 8 MHz USB is switched off. The power consumption e.g. of ADAFRUIT_ITSYBITSY_M4_EXPRESS drops to about 1.5 mA at 1 MHz. Since the peripheral frequency is dropped as well, timing e.g. of PWM, UART, I2C and SPI is affected and frequency/baud rate has to set again after a frequency change below 48 MHz. --- ports/samd/mcu/samd51/clock_config.c | 72 ++++++++++++++++++++-------- ports/samd/modmachine.c | 4 +- ports/samd/samd_soc.c | 2 +- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index 31c8f5a8654c..9fb48705adcb 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -54,35 +54,63 @@ uint32_t get_peripheral_freq(void) { } void set_cpu_freq(uint32_t cpu_freq_arg) { - cpu_freq = cpu_freq_arg; // Setup GCLK0 for 48MHz as default state to keep the MCU running during config change. GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL0) { } - // Setup DPLL0 for 120 MHz // first: disable DPLL0 in case it is running OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = 0; while (OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.ENABLE == 1) { } - // Now configure the registers - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(1) | OSCCTRL_DPLLCTRLB_LBYPASS | - OSCCTRL_DPLLCTRLB_REFCLK(0) | OSCCTRL_DPLLCTRLB_WUF | OSCCTRL_DPLLCTRLB_FILTER(0x01); - - uint32_t div = cpu_freq / DPLLx_REF_FREQ; - uint32_t frac = (cpu_freq - div * DPLLx_REF_FREQ) / (DPLLx_REF_FREQ / 32); - OSCCTRL->Dpll[0].DPLLRATIO.reg = (frac << 16) + div - 1; - // enable it again - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | OSCCTRL_DPLLCTRLA_RUNSTDBY; - - // Per errata 2.13.1 - while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 1)) { + if (cpu_freq_arg > DFLL48M_FREQ) { + + cpu_freq = cpu_freq_arg; + peripheral_freq = DFLL48M_FREQ; + // Now configure the registers + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(1) | OSCCTRL_DPLLCTRLB_LBYPASS | + OSCCTRL_DPLLCTRLB_REFCLK(0) | OSCCTRL_DPLLCTRLB_WUF | OSCCTRL_DPLLCTRLB_FILTER(0x01); + + uint32_t div = cpu_freq / DPLLx_REF_FREQ; + uint32_t frac = (cpu_freq - div * DPLLx_REF_FREQ) / (DPLLx_REF_FREQ / 32); + OSCCTRL->Dpll[0].DPLLRATIO.reg = (frac << 16) + div - 1; + // enable it again + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | OSCCTRL_DPLLCTRLA_RUNSTDBY; + + // Per errata 2.13.1 + while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 1)) { + } + // Setup GCLK0 for DPLL0 output (48 or 48-200MHz) + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DPLL0; + while (GCLK->SYNCBUSY.bit.GENCTRL0) { + } + // Set GCLK 2 back to 48 MHz + GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL2) { + } + } else { + int div = DFLL48M_FREQ / cpu_freq_arg; + // Setup GCLK1 for the low freq + GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(div) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL2) { + } + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_DIV(div) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL0) { + } + peripheral_freq = DFLL48M_FREQ / div; + cpu_freq = DFLL48M_FREQ / div; } - - // Setup GCLK0 for DPLL0 output (48 or 48-200MHz) - GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DPLL0; - while (GCLK->SYNCBUSY.bit.GENCTRL0) { + if (cpu_freq >= 8000000) { + // Setup GCLK5 for DFLL48M output (48 MHz) + GCLK->GENCTRL[5].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + while (GCLK->SYNCBUSY.bit.GENCTRL5) { + } + } else { + // Setup GCLK5 off if CPU Clk < 8 MHz + GCLK->GENCTRL[5].reg = 0; + while (GCLK->SYNCBUSY.bit.GENCTRL5) { + } } } @@ -120,9 +148,10 @@ void init_clocks(uint32_t cpu_freq) { // SAMD51 clock settings // GCLK0: 48MHz from DFLL48M or 48 - 200 MHz from DPLL0 (SAMD51) // GCLK1: 32768 Hz from 32KULP or DFLL48M - // GCLK2: 48MHz from DFLL48M for Peripheral devices - // GCLK3: 16Mhz for the us-counter (TC0/TC1) + // GCLK2: 8-48MHz from DFLL48M for Peripheral devices + // GCLK3: 8Mhz for the us-counter (TC0/TC1) // GCLK4: 32kHz from crystal, if present + // GCLK5: 48MHz from DFLL48M for USB // DPLL0: 48 - 200 MHz // Steps to set up clocks: @@ -136,6 +165,7 @@ void init_clocks(uint32_t cpu_freq) { // Setup GCLK2 to 48MHz for Peripherals // Setup GCLK3 to 8MHz for TC0/TC1 // Setup GCLK4 to 32kHz crystal, if present + // Setup GCLK5 to 48 MHz // Setup GCLK0 for 48MHz as default state to keep the MCU running during config change. GCLK->GENCTRL[0].reg = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; @@ -238,7 +268,7 @@ void init_clocks(uint32_t cpu_freq) { peripheral_freq = DFLL48M_FREQ; // To be changed if CPU_FREQ < 48M - // Setup GCLK2 for DPLL1 output (48 MHz) + // Setup GCLK2 for DFLL48M output (48 MHz), may be scaled down later by calls to set_cpu_freq GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL2) { } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index b9de026ed425..d16b660645f3 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -69,9 +69,9 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { } else { #if defined(MCU_SAMD51) uint32_t freq = mp_obj_get_int(args[0]); - if (freq >= 48000000 && freq <= 200000000) { + if (freq >= 1000000 && freq <= 200000000) { set_cpu_freq(freq); - SysTick_Config(freq / 1000); + SysTick_Config(get_cpu_freq() / 1000); } #endif return mp_const_none; diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index f4a27f3df740..113529aeea36 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -46,7 +46,7 @@ static void usb_init(void) { PM->APBBMASK.bit.USB_ = 1; uint8_t alt = 6; // alt G, USB #elif defined(MCU_SAMD51) - GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; + GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK5; while (GCLK->PCHCTRL[USB_GCLK_ID].bit.CHEN == 0) { } MCLK->AHBMASK.bit.USB_ = 1; From 1c32cec7f11864a9bc67f988e39e7dfc7c33188e Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 29 Jun 2022 17:22:20 +0200 Subject: [PATCH 1891/4290] samd/clock_config: Support changing machine.freq() for SAMD21. The range is 1MHz - 48 MHz. Note that below 8 MHz there is no USB support. The frequency will be set to an integer fraction of 48 MHz. And after changing the frequency, the peripherals like PWM, UART, I2C, SPI have to be reconfigured. Current consumption e.g. of the Seeed Xiao board at 1 MHz is about 1.5 mA, mostly caused by the on-board LED (green LED with 1k resistor at 3.3V). --- ports/samd/mcu/samd21/clock_config.c | 43 +++++++++++++++++++++------- ports/samd/mcu/samd21/mpconfigmcu.h | 1 + ports/samd/mcu/samd51/mpconfigmcu.h | 1 + ports/samd/modmachine.c | 4 +-- ports/samd/samd_soc.c | 2 +- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index 2402ed2e3107..204a5294f257 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -51,7 +51,36 @@ uint32_t get_peripheral_freq(void) { } void set_cpu_freq(uint32_t cpu_freq_arg) { - cpu_freq = cpu_freq_arg; + + // Set 1 waitstate to be safe + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_MANW | NVMCTRL_CTRLB_RWS(1); + + int div = DFLL48M_FREQ / cpu_freq_arg; + peripheral_freq = cpu_freq = DFLL48M_FREQ / div; + + // Enable GCLK output: 48M on both CCLK0 and GCLK2 + GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(div); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(div); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(2); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + if (cpu_freq >= 8000000) { + // Enable GCLK output: 48MHz on GCLK5 for USB + GCLK->GENDIV.reg = GCLK_GENDIV_ID(5) | GCLK_GENDIV_DIV(1); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(5); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + } else { + // Disable GCLK output on GCLK5 for USB, since USB is not reliable below 8 Mhz. + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(5); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + } + // Set 0 waitstates for slower CPU clock + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_MANW | NVMCTRL_CTRLB_RWS(cpu_freq > 24000000 ? 1 : 0); } void check_usb_recovery_mode(void) { @@ -76,6 +105,7 @@ void init_clocks(uint32_t cpu_freq) { // GCLK2: 48MHz from DFLL for Peripherals // GCLK3: 1Mhz for the us-counter (TC4/TC5) // GCLK4: 32kHz from crystal, if present + // GCLK5: 48MHz from DFLL for USB // GCLK8: 1kHz clock for WDT NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" @@ -180,15 +210,7 @@ void init_clocks(uint32_t cpu_freq) { #endif // MICROPY_HW_XOSC32K - // Enable GCLK output: 48M on both CCLK0 and GCLK2 - GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(1); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0); - while (GCLK->STATUS.bit.SYNCBUSY) { - } - GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(2); - while (GCLK->STATUS.bit.SYNCBUSY) { - } + set_cpu_freq(cpu_freq); // Enable GCLK output: 1MHz on GCLK3 for TC4 GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(48); @@ -200,7 +222,6 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); while (GCLK->STATUS.bit.SYNCBUSY) { } - } void enable_sercom_clock(int id) { diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index a84b31276b42..e0af60552b02 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -19,6 +19,7 @@ #define CPU_FREQ (48000000) #define DFLL48M_FREQ (48000000) +#define MAX_CPU_FREQ (48000000) #define IRQ_PRI_PENDSV ((1 << __NVIC_PRIO_BITS) - 1) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 19193992f058..819bc1bb11b7 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -26,6 +26,7 @@ unsigned long trng_random_u32(void); #define CPU_FREQ (120000000) #define DFLL48M_FREQ (48000000) +#define MAX_CPU_FREQ (200000000) #define DPLLx_REF_FREQ (32768) #define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index d16b660645f3..21d700ac31ca 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -67,13 +67,11 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { return MP_OBJ_NEW_SMALL_INT(get_cpu_freq()); } else { - #if defined(MCU_SAMD51) uint32_t freq = mp_obj_get_int(args[0]); - if (freq >= 1000000 && freq <= 200000000) { + if (freq >= 1000000 && freq <= MAX_CPU_FREQ) { set_cpu_freq(freq); SysTick_Config(get_cpu_freq() / 1000); } - #endif return mp_const_none; } } diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 113529aeea36..6d8348ebcd83 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -41,7 +41,7 @@ static void usb_init(void) { // Init USB clock #if defined(MCU_SAMD21) - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_USB; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK5 | GCLK_CLKCTRL_ID_USB; PM->AHBMASK.bit.USB_ = 1; PM->APBBMASK.bit.USB_ = 1; uint8_t alt = 6; // alt G, USB From 64e3c351de0959660d1a6b691ee7dbf2de565fbe Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 29 Jun 2022 14:09:57 +0200 Subject: [PATCH 1892/4290] samd/modmachine: Add machine.reset_cause(). --- ports/samd/modmachine.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 21d700ac31ca..db3f159cc2c3 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -139,6 +139,17 @@ STATIC mp_obj_t machine_enable_irq(mp_obj_t state_in) { } MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq); +STATIC mp_obj_t machine_reset_cause(void) { + #if defined(MCU_SAMD21) + return MP_OBJ_NEW_SMALL_INT(PM->RCAUSE.reg); + #elif defined(MCU_SAMD51) + return MP_OBJ_NEW_SMALL_INT(RSTC->RCAUSE.reg); + #else + return MP_OBJ_NEW_SMALL_INT(0); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); + STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, @@ -165,8 +176,18 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, { 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) }, { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, + + // Class constants. + // Use numerical constants instead of the symbolic names, + // since the names differ between SAMD21 and SAMD51. + { MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(0x01) }, + { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(0x10) }, + { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(0x20) }, + { MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(0x40) }, + { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(0x80) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); From 0d3f0d7470586f9c328a047ac3043420df16d4ab Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 2 Jul 2022 18:12:55 +0200 Subject: [PATCH 1893/4290] samd/boards/SPARKFUN_SAMD51_THING_PLUS: Add board files for Thing Plus. That device uses an SAMD51J20 MCU with 256k RAM and 1024k flash. --- .../SPARKFUN_SAMD51_THING_PLUS/board.json | 21 ++++++++++ .../mpconfigboard.h | 4 ++ .../mpconfigboard.mk | 8 ++++ .../SPARKFUN_SAMD51_THING_PLUS/pins.csv | 42 +++++++++++++++++++ ports/samd/boards/samd51x20a.ld | 20 +++++++++ 5 files changed, 95 insertions(+) create mode 100644 ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/board.json create mode 100644 ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h create mode 100644 ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.mk create mode 100644 ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv create mode 100644 ports/samd/boards/samd51x20a.ld diff --git a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/board.json b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/board.json new file mode 100644 index 000000000000..af643f5c5f3c --- /dev/null +++ b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/board.json @@ -0,0 +1,21 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Battery Charging", + "Breadboard Friendly", + "Micro USB", + "QWIIC", + "SPI Flash" + ], + "images": [ + "sparkfun_samd51_thing_plus.jpg" + ], + "mcu": "samd51", + "product": "Sparkfun SAMD51 Thing Plus", + "thumbnail": "", + "url": "https://www.sparkfun.com/products/14713", + "vendor": "Sparkfun" +} diff --git a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h new file mode 100644 index 000000000000..e797ccca9da1 --- /dev/null +++ b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h @@ -0,0 +1,4 @@ +#define MICROPY_HW_BOARD_NAME "Sparkfun SAMD51 Thing Plus" +#define MICROPY_HW_MCU_NAME "SAMD51J20A" + +#define MICROPY_HW_XOSC32K (1) diff --git a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.mk b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.mk new file mode 100644 index 000000000000..9e5cf887dfce --- /dev/null +++ b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.mk @@ -0,0 +1,8 @@ +MCU_SERIES = SAMD51 +CMSIS_MCU = SAMD51J20A +LD_FILES = boards/samd51x20a.ld sections.ld +TEXT0 = 0x4000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 diff --git a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv new file mode 100644 index 000000000000..b60fb909714e --- /dev/null +++ b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv @@ -0,0 +1,42 @@ +# Pin rows contain Pin number and pin name. +# Pin rows start with PIN_ +# LED rows start with LED_ +# If the pin name is omitted, the pin number is added as name. +# Rows for empty entries have to start with '-' +# Empty lines and lines not starting with PIN_ or LED_ are ignored + +PIN_PA13,D0 +PIN_PA12,D1 +PIN_PB23,RXD +PIN_PB22,TXD +PIN_PA06,D4 +PIN_PA15,D5 +PIN_PA20,D6 +PIN_PA21,D7 +- +PIN_PA07,D9 +PIN_PA18,D10 +PIN_PA16,D11 +PIN_PA19,D12 +PIN_PA17,D13 +PIN_PA02,A0 +PIN_PB08,A1 +PIN_PB09,A2 +PIN_PA04,A3 +PIN_PA05,A4 +PIN_PB02,A5 +PIN_PA22,SDA +PIN_PA23,SCL +PIN_PB12,MOSI +PIN_PB11,MISO +PIN_PB13,SCK +PIN_PA08,FLASH_MOSI +PIN_PA09,FLASH_SCK +PIN_PA10,FLASH_CS +PIN_PA11,FLASH_MISO +PIN_PA30,SWDCLK +PIN_PA31,SWDIO + +LED_PA17,LED +LED_PB03,RXLED +LED_PA27,TXLED diff --git a/ports/samd/boards/samd51x20a.ld b/ports/samd/boards/samd51x20a.ld new file mode 100644 index 000000000000..f0d5e5c6aeb6 --- /dev/null +++ b/ports/samd/boards/samd51x20a.ld @@ -0,0 +1,20 @@ +/* + GNU linker script for SAMD51x20 +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 1024K - 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* Top end of the stack, with room for double-tap variable */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_sstack = _estack - 16K; + +_oflash_fs = ORIGIN(FLASH) + 384K - 16K; +_sflash_fs = LENGTH(FLASH) - 384K + 16K - 1; + +_sheap = _ebss; +_eheap = _sstack; From a7113e95d78583a47f8074965e17d1e0499e0494 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 7 Jul 2022 09:49:51 +0200 Subject: [PATCH 1894/4290] samd/modmachine: Add machine.dht_readinto and enable on SAMD51. --- ports/samd/mcu/samd51/mpconfigmcu.h | 1 + ports/samd/mcu/samd51/mpconfigmcu.mk | 2 ++ ports/samd/modmachine.c | 4 ++++ ports/samd/mphalport.h | 3 +++ 4 files changed, 10 insertions(+) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 819bc1bb11b7..a266adf93cad 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -13,6 +13,7 @@ #define MP_NEED_LOG2 (1) #define MICROPY_PY_CMATH (0) +#define MICROPY_PY_MACHINE_DHT_READINTO (1) #define MICROPY_PY_UOS_URANDOM (1) #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) unsigned long trng_random_u32(void); diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk index f8ed02f841d9..ed4df82c6912 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.mk +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -2,6 +2,8 @@ MICROPY_VFS_LFS2 ?= 1 SRC_S += shared/runtime/gchelper_m3.s +SRC_C += drivers/dht/dht.c \ + LIBM_SRC_C += $(addprefix lib/libm/,\ acoshf.c \ asinfacosf.c \ diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index db3f159cc2c3..14baf279d549 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -30,6 +30,7 @@ #include "extmod/machine_pulse.h" #include "extmod/machine_i2c.h" #include "extmod/machine_spi.h" +#include "drivers/dht/dht.h" #include "modmachine.h" #include "samd_soc.h" @@ -179,6 +180,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, + #if MICROPY_PY_MACHINE_DHT_READINTO + { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) }, + #endif // Class constants. // Use numerical constants instead of the symbolic names, diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index 6f4f838cfba2..3879240f9a6a 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -99,6 +99,9 @@ static inline uint64_t mp_hal_time_ns(void) { #define MP_HAL_PIN_FMT "%u" #define mp_hal_pin_obj_t uint +#define mp_hal_quiet_timing_enter() MICROPY_BEGIN_ATOMIC_SECTION() +#define mp_hal_quiet_timing_exit(irq_state) MICROPY_END_ATOMIC_SECTION(irq_state) + extern uint32_t machine_pin_open_drain_mask[]; mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in); From fe31fca462011785cf78b4730bf34bb552e9a707 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 21 Jun 2022 14:27:20 +0200 Subject: [PATCH 1895/4290] samd/mcu/samd51: Enable onewire support for SAMD51. --- ports/samd/mcu/samd51/mpconfigmcu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index a266adf93cad..5735f512b5a7 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -14,6 +14,7 @@ #define MICROPY_PY_CMATH (0) #define MICROPY_PY_MACHINE_DHT_READINTO (1) +#define MICROPY_PY_ONEWIRE (1) #define MICROPY_PY_UOS_URANDOM (1) #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) unsigned long trng_random_u32(void); From 4c9e4c3310faff5ec05b183454df88d0f33f9e78 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 10 Jul 2022 12:04:14 +0200 Subject: [PATCH 1896/4290] samd/mcu/samd51: Enable FAT support for SAMD51. Tested with a SD card connected to a SAMD51 board. The SEEED WIO terminal has a SD-Card reader built-in. Also a side change to remove a few obsolete lines from Makefile. --- ports/samd/Makefile | 4 --- ports/samd/fatfs_port.c | 41 ++++++++++++++++++++++++++++ ports/samd/mcu/samd51/mpconfigmcu.h | 6 ++++ ports/samd/mcu/samd51/mpconfigmcu.mk | 5 +++- ports/samd/modutime.c | 2 +- 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 ports/samd/fatfs_port.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 2f97b1993e99..abec4e83a553 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -61,7 +61,6 @@ CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-a CFLAGS += $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__ CFLAGS += $(CFLAGS_EXTRA) -CFLAGS += -DMPCONFIG_MCU_H='' LDFLAGS += -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref @@ -169,9 +168,6 @@ CFLAGS += -DMICROPY_MODULE_FROZEN_STR CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool endif -# Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" -$(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces - all: $(BUILD)/firmware.uf2 $(BUILD)/firmware.elf: $(OBJ) diff --git a/ports/samd/fatfs_port.c b/ports/samd/fatfs_port.c new file mode 100644 index 000000000000..9ee1764ebc0a --- /dev/null +++ b/ports/samd/fatfs_port.c @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2021 Robert Hammelrath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "mphalport.h" +#include "py/runtime.h" +#include "shared/timeutils/timeutils.h" +#include "lib/oofatfs/ff.h" + +extern uint32_t time_offset; + +MP_WEAK DWORD get_fattime(void) { + timeutils_struct_time_t tm; + + timeutils_seconds_since_epoch_to_struct_time(mp_hal_ticks_ms_64() / 1000 + time_offset, &tm); + return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) | ((tm.tm_mday) << 16) | + ((tm.tm_hour) << 11) | ((tm.tm_min) << 5) | (tm.tm_sec / 2); +} diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 5735f512b5a7..686cfd6104df 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -22,6 +22,12 @@ unsigned long trng_random_u32(void); // Due to a limitation in the TC counter for us, the ticks period is 2**29 #define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) +// 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 VFS_BLOCK_SIZE_BYTES (1536) // #define MICROPY_HW_UART_TXBUF (1) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk index ed4df82c6912..305e780b8787 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.mk +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -1,8 +1,11 @@ MICROPY_VFS_LFS2 ?= 1 +MICROPY_VFS_FAT ?= 1 SRC_S += shared/runtime/gchelper_m3.s -SRC_C += drivers/dht/dht.c \ +SRC_C += \ + fatfs_port.c \ + drivers/dht/dht.c \ LIBM_SRC_C += $(addprefix lib/libm/,\ acoshf.c \ diff --git a/ports/samd/modutime.c b/ports/samd/modutime.c index a54544e62c6c..4169c15d9117 100644 --- a/ports/samd/modutime.c +++ b/ports/samd/modutime.c @@ -29,7 +29,7 @@ #include "shared/timeutils/timeutils.h" #include "mphalport.h" -static uint32_t time_offset = 0; +uint32_t time_offset = 0; // localtime([secs]) STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { From 03075a68399a6450fd0e238dd75314805f8365b7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 1 Aug 2022 17:23:11 +0200 Subject: [PATCH 1897/4290] samd/modmachine: Implement machine.lightsleep(). Which just sets the CPU clock to 200kHz and switches the peripheral clock off. There are two modes: machine.lightsleep(duration_ms) and machine.lightsleep() In any mode any configured pin.irq() event will terminate the sleep. Current consumption in lightsleep for some boards: - 1.5 - 2.5 mA when supplied trough an active USB (Seeed XIAO w/o power LED, Adafruit ItsyBitsy) - 0.8 - 2 mA when supplied through Gnd/+5V (Vusb) (Seeed XIAO w/o power LED, Adafruit ItsyBitsy) - < 1 mA for SAMD51 when supplied trough a battery connector (Sparkfun Thing SAMD51 plus) Related change: move the calls to SysTick_Config() into set_cpu_freq(). It is required after each CPU freq change to have ticks_ms run at the proper rate. --- ports/samd/machine_pin.c | 3 ++ ports/samd/mcu/samd21/clock_config.c | 1 + ports/samd/mcu/samd51/clock_config.c | 1 + ports/samd/modmachine.c | 61 +++++++++++++++++++++++++++- ports/samd/samd_soc.c | 1 - 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index fc72c8f7569f..2dc10f9b4634 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -57,6 +57,8 @@ typedef struct _machine_pin_irq_obj_t { STATIC const mp_irq_methods_t machine_pin_irq_methods; +bool EIC_occured; + uint32_t machine_pin_open_drain_mask[4]; // Open drain behaviour is simulated. @@ -410,6 +412,7 @@ void EIC_Handler() { for (int eic_id = 0; eic_id < 16; eic_id++, mask <<= 1) { // Did the ISR fire? if (isr & mask) { + EIC_occured = true; EIC->INTFLAG.reg |= mask; // clear the ISR flag machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); if (irq != NULL) { diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index 204a5294f257..a4011c05cbbc 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -81,6 +81,7 @@ void set_cpu_freq(uint32_t cpu_freq_arg) { } // Set 0 waitstates for slower CPU clock NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_MANW | NVMCTRL_CTRLB_RWS(cpu_freq > 24000000 ? 1 : 0); + SysTick_Config(cpu_freq / 1000); } void check_usb_recovery_mode(void) { diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index 9fb48705adcb..f67d297e8eb1 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -112,6 +112,7 @@ void set_cpu_freq(uint32_t cpu_freq_arg) { while (GCLK->SYNCBUSY.bit.GENCTRL5) { } } + SysTick_Config(cpu_freq / 1000); } void check_usb_recovery_mode(void) { diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 14baf279d549..2a8e34a966a8 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -50,6 +50,10 @@ #define DBL_TAP_MAGIC_LOADER 0xf01669ef #define DBL_TAP_MAGIC_RESET 0xf02669ef +#define LIGHTSLEEP_CPU_FREQ 200000 + +extern bool EIC_occured; + STATIC mp_obj_t machine_reset(void) { *DBL_TAP_ADDR = DBL_TAP_MAGIC_RESET; NVIC_SystemReset(); @@ -71,7 +75,6 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { uint32_t freq = mp_obj_get_int(args[0]); if (freq >= 1000000 && freq <= MAX_CPU_FREQ) { set_cpu_freq(freq); - SysTick_Config(get_cpu_freq() / 1000); } return mp_const_none; } @@ -151,6 +154,60 @@ STATIC mp_obj_t machine_reset_cause(void) { } MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); +STATIC mp_obj_t machine_lightsleep(size_t n_args, const mp_obj_t *args) { + int32_t duration = -1; + uint32_t freq = get_cpu_freq(); + if (n_args > 0) { + duration = mp_obj_get_int(args[0]); + } + EIC_occured = false; + // Slow down + set_cpu_freq(LIGHTSLEEP_CPU_FREQ); + #if defined(MCU_SAMD21) + // Switch the peripheral clock off + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2); + while (GCLK->STATUS.bit.SYNCBUSY) { + } + // Switch the EIC temporarily to GCLK3, since GCLK2 is off + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | EIC_GCLK_ID; + if (duration > 0) { + uint32_t t0 = systick_ms; + while ((systick_ms - t0 < duration) && (EIC_occured == false)) { + __WFI(); + } + } else { + while (EIC_occured == false) { + __WFI(); + } + } + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | EIC_GCLK_ID; + + #elif defined(MCU_SAMD51) + // Switch the peripheral clock off + GCLK->GENCTRL[2].reg = 0; + while (GCLK->SYNCBUSY.bit.GENCTRL2) { + } + // Switch the EIC temporarily to GCLK3, since GCLK2 is off + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK3; + if (duration > 0) { + uint32_t t0 = systick_ms; + while ((systick_ms - t0 < duration) && (EIC_occured == false)) { + __WFI(); + } + } else { + while (EIC_occured == false) { + __WFI(); + } + } + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK2; + + #endif + // Speed up again + set_cpu_freq(freq); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lightsleep_obj, 0, 1, machine_lightsleep); + STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, @@ -179,6 +236,8 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { 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) }, { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) }, + { MP_ROM_QSTR(MP_QSTR_lightsleep), MP_ROM_PTR(&machine_lightsleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) }, #if MICROPY_PY_MACHINE_DHT_READINTO { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) }, diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 6d8348ebcd83..3608306e8719 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -108,7 +108,6 @@ void init_us_counter(void) { void samd_init(void) { init_clocks(get_cpu_freq()); - SysTick_Config(get_cpu_freq() / 1000); init_us_counter(); usb_init(); check_usb_recovery_mode(); From f0399d35e4f7ad4e48b22f02b80a7ee506c9ec64 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 11 Aug 2022 11:22:58 +0200 Subject: [PATCH 1898/4290] samd/modmachine: Get the bootloader magic address from the lib. Instead of being hard-coded, and then it works for all MCUs. That fits except for a Sparkfun SAMD51 Thing Plus (known) bug, which uses 192k - 4 as magic address. Therefore, that address is set as well to avoid a problem when this bug is fixed by Sparkfun. --- .../SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h | 6 ++++++ ports/samd/modmachine.c | 14 +++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h index e797ccca9da1..a51b71c363e1 100644 --- a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h +++ b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/mpconfigboard.h @@ -2,3 +2,9 @@ #define MICROPY_HW_MCU_NAME "SAMD51J20A" #define MICROPY_HW_XOSC32K (1) + +// There seems to be an inconsistency in the SAMD51 Thing bootloader in that +// the bootloader magic address is at the end of a 192k RAM area, instead of +// 256k. Since the SAMD51x20A has 256k RAM, the loader symbol is at that address +// and so there is a fix here using the previous definition. +#define DBL_TAP_ADDR_ALT ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 0x10000 - 4)) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 2a8e34a966a8..ce5fef76f753 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -41,21 +41,26 @@ #include "hpl_pm_base.h" #if MICROPY_PY_MACHINE - #if defined(MCU_SAMD21) -#define DBL_TAP_ADDR ((volatile uint32_t *)(0x20000000 + 32 * 1024 - 4)) +#define DBL_TAP_ADDR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4)) #elif defined(MCU_SAMD51) -#define DBL_TAP_ADDR ((volatile uint32_t *)(0x20000000 + 192 * 1024 - 4)) +#define DBL_TAP_ADDR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4)) #endif +// A board may define a DPL_TAP_ADDR_ALT, which will be set as well +// Needed at the moment for Sparkfun SAMD51 Thing Plus #define DBL_TAP_MAGIC_LOADER 0xf01669ef #define DBL_TAP_MAGIC_RESET 0xf02669ef #define LIGHTSLEEP_CPU_FREQ 200000 extern bool EIC_occured; +extern uint32_t _dbl_tap_addr; STATIC mp_obj_t machine_reset(void) { *DBL_TAP_ADDR = DBL_TAP_MAGIC_RESET; + #ifdef DBL_TAP_ADDR_ALT + *DBL_TAP_ADDR_ALT = DBL_TAP_MAGIC_RESET; + #endif NVIC_SystemReset(); return mp_const_none; } @@ -63,6 +68,9 @@ MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset); STATIC mp_obj_t machine_bootloader(void) { *DBL_TAP_ADDR = DBL_TAP_MAGIC_LOADER; + #ifdef DBL_TAP_ADDR_ALT + *DBL_TAP_ADDR_ALT = DBL_TAP_MAGIC_LOADER; + #endif NVIC_SystemReset(); return mp_const_none; } From ddd41b8bbf6823ea730e781d508babbecdd41304 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 13 Aug 2022 17:33:04 +0200 Subject: [PATCH 1899/4290] samd/clock_config: Document the #defines use in init_clocks(). Which may be set in the respective mpconfigboard.h files. --- ports/samd/mcu/samd21/clock_config.c | 34 +++++++++++++++++++++++ ports/samd/mcu/samd51/clock_config.c | 40 ++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index a4011c05cbbc..a195cb692053 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -96,6 +96,40 @@ void check_usb_recovery_mode(void) { #endif // MICROPY_HW_XOSC32K } +// Purpose of the #defines for the clock configuration. +// +// Both CPU and periperal devices are clocked by the DFLL48M clock. +// DFLL48M is either free running, or controlled by the 32kHz crystal, or +// Synchronized with the USB clock. +// +// #define MICROPY_HW_XOSC32K (0 | 1) +// +// If MICROPY_HW_XOSC32K = 1, the 32kHz crystal is used as input for GCLK 1, which +// serves as refernce clock source for the DFLL48M oscillator, +// The crystal is used, unless MICROPY_HW_MCU_OSC32KULP is set. +// In that case GCLK1 (and the CPU clock) is driven by the 32K Low power oscillator. +// The reason for offering this option is a design flaw of the Adafruit +// Feather boards, where the RGB Led and Debug signals interfere with the +// crystal, causing the CPU to fail if it is driven by the crystal. +// +// If MICROPY_HW_XOSC32K = 0, the 32kHz signal for GCLK1 (and the CPU) is +// created by dividing the 48MHz clock of DFLL48M, but not used otherwise. +// +// If MICROPY_HW_DFLL_USB_SYNC = 0, the DFLL48M oscillator is free running using +// the pre-configured trim values. In that mode, the peripheral clock is +// not exactly 48Mhz and has a substantional temperature drift. +// +// If MICROPY_HW_DFLL_USB_SYNC = 1, the DFLL48 is synchronized with the 1 kHz USB sync +// signal. If after boot there is no USB sync withing 500ms, the configuratuion falls +// back to a free running 48Mhz oscillator. +// +// In all modes, the 48MHz signal has a substantial jitter, largest when +// MICROPY_HW_DFLL_USB_SYNC is active. That is caused by the repective +// reference frequencies of 32kHz or 1 kHz being low. That affects most +// PWM. Std Dev at 1kHz 0.156Hz (w. Crystal) up to 0.4 Hz (with USB sync). +// +// If none of the mentioned defines is set, the device uses the internal oscillators. + void init_clocks(uint32_t cpu_freq) { dfll48m_calibration = 0; // please the compiler diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index f67d297e8eb1..3bc4616de9e9 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -142,6 +142,46 @@ void check_usb_recovery_mode(void) { #endif // MICROPY_HW_XOSC32K } +// Purpose of the #defines for the clock configuration. +// +// The CPU clock is generated by DPLL0, which takes 32768 Hz as reference frequency, +// supplied through GCLK1. +// +// DFLL48M is used for the peripheral clock, e.g. for PWM, UART, SPI, I2C. +// DFLL48M is either free running, or controlled by the 32kHz crystal, or +// Synchronized with the USB clock. +// +// GCLK1 takes it's input either from the 32kHz crystal, the internal low power +// RC oscillator or from DFLL48M. +// +// #define MICROPY_HW_XOSC32K (0 | 1) +// +// If MICROPY_HW_XOSC32K = 1, the 32kHz crystal is used for the DFLL48M oscillator +// and for GCLK1, feeding the CPU, unless MICROPY_HW_MCU_OSC32KULP is set. +// In that case GCLK1 (and the CPU clock) is driven by the 32K Low power oscillator. +// The reason for offering this option is a design flaw of the Adafruit +// Feather boards, where the RGB Led and Debug signals interfere with the +// crystal, causing the CPU to fail if it is driven by the crystal. The +// peripheral devices are affected as well, but continue it's operation. +// +// If MICROPY_HW_XOSC32K = 0, the 32kHz signal for GCLK1 (and the CPU) is +// created by dividing the 48MHz clock of DFLL48M. +// +// If MICROPY_HW_DFLL_USB_SYNC = 0, the DFLL48M oscillator is free running using +// the pre-configured trim values. In that mode, the peripheral clock is +// not exactly 48Mhz and has a substantional temperature drift. +// +// If MICROPY_HW_DFLL_USB_SYNC = 1, the DFLL48 is synchronized with the 1 kHz USB sync +// signal. If after boot there is no USB sync withing 500ms, the configuratuion falls +// back to a free running 48Mhz oscillator. +// +// In all modes, the 48MHz signal has a substantial jitter, largest when +// MICROPY_HW_DFLL_USB_SYNC is active. That is caused by the repective +// reference frequencies of 32kHz or 1 kHz being low. That affects most +// PWM. Std Dev at 1kHz 0.156Hz (w. Crystal) up to 0.4 Hz (with USB sync). +// +// If none of the mentioned defines is set, the device uses the internal oscillators. + void init_clocks(uint32_t cpu_freq) { dfll48m_calibration = 0; // please the compiler From 2251cb774b7b7db12323a32b339903fa27ff7b08 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 18 Aug 2022 11:58:09 +0200 Subject: [PATCH 1900/4290] samd/machine_uart: Implement uart.txdone() and uart.flush(). Using the stream method for uart.flush(). uart.txdone() returns True, if the uart not busy, False otherwise. uart.flush() waits until all bytes have been transmitted or a timeout triggers. The timeout is determined by the buffer size and the baud rate. Also fix two inconsistencies when not using txbuf: - Report in ioctl as being writeable if there is room in the tx buffer, only if it is configured. - Print the txbuf size if configured. --- ports/samd/machine_uart.c | 53 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index 1031f26c2648..76b564e874a6 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -116,9 +116,17 @@ void sercom_enable(Sercom *uart, int state) { 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, " - "timeout=%u, timeout_char=%u, rxbuf=%d)", + "timeout=%u, timeout_char=%u, rxbuf=%d" + #if MICROPY_HW_UART_TXBUF + ", txbuf=%d" + #endif + ")", self->id, self->baudrate, self->bits, _parity_name[self->parity], - self->stop + 1, self->timeout, self->timeout_char, self->read_buffer.size - 1); + self->stop + 1, self->timeout, self->timeout_char, self->read_buffer.size - 1 + #if MICROPY_HW_UART_TXBUF + , self->write_buffer.size - 1 + #endif + ); } STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -385,6 +393,22 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak); +STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { + machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + Sercom *uart = sercom_instance[self->id]; + + if (uart->USART.INTFLAG.bit.DRE + #if MICROPY_HW_UART_TXBUF + && ringbuf_avail(&self->write_buffer) == 0 + #endif + && uart->USART.INTFLAG.bit.TXC) { + return mp_const_true; + } else { + return mp_const_false; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); + void uart_deinit_all(void) { for (int i = 0; i < SERCOM_INST_NUM; i++) { if (uart_table[i] != NULL) { @@ -399,7 +423,9 @@ STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) }, { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) }, + { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, @@ -414,7 +440,6 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz uint8_t *dest = buf_in; Sercom *uart = sercom_instance[self->id]; - // t.b.d. Cater timeout for timer wrap after 50 days. for (size_t i = 0; i < size; i++) { // Wait for the first/next character while (ringbuf_avail(&self->read_buffer) == 0) { @@ -488,9 +513,29 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint if ((flags & MP_STREAM_POLL_RD) && (uart->USART.INTFLAG.bit.RXC != 0 || ringbuf_avail(&self->read_buffer) > 0)) { ret |= MP_STREAM_POLL_RD; } - if ((flags & MP_STREAM_POLL_WR) && (uart->USART.INTFLAG.bit.DRE != 0)) { + if ((flags & MP_STREAM_POLL_WR) && (uart->USART.INTFLAG.bit.DRE != 0 + #if MICROPY_HW_UART_TXBUF + || ringbuf_avail(&self->write_buffer) > 0 + #endif + )) { ret |= MP_STREAM_POLL_WR; } + } else if (request == MP_STREAM_FLUSH) { + // The timeout is defined by the buffer size and the baudrate. + // Take the worst case assumtions at 13 bit symbol size times 2. + uint64_t timeout = mp_hal_ticks_ms_64() + (3 + #if MICROPY_HW_UART_TXBUF + + self->write_buffer.size + #endif + ) * 13000 * 2 / self->baudrate; + do { + if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) { + return 0; + } + MICROPY_EVENT_POLL_HOOK + } while (mp_hal_ticks_ms_64() < timeout); + *errcode = MP_ETIMEDOUT; + ret = MP_STREAM_ERROR; } else { *errcode = MP_EINVAL; ret = MP_STREAM_ERROR; From be31fde012e0cf522ec9d70f50923a0a899f438c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 8 Sep 2022 17:55:08 +0200 Subject: [PATCH 1901/4290] samd/mcu: Make some settings in mpconfigmcu.h conditional. And set the default for MICROPY_PY_MATH as 1 for both MCU types. --- ports/samd/mcu/samd21/mpconfigmcu.h | 13 ++++++++++++- ports/samd/mcu/samd21/mpconfigmcu.mk | 29 ++++++++++++++++++++++++++++ ports/samd/mcu/samd51/mpconfigmcu.h | 11 +++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index e0af60552b02..8d155f93ab03 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -9,13 +9,24 @@ #define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) + +#ifndef MICROPY_PY_BUILTINS_COMPLEX #define MICROPY_PY_BUILTINS_COMPLEX (0) -#define MICROPY_PY_MATH (0) +#endif + +#ifndef MICROPY_PY_MATH +#define MICROPY_PY_MATH (1) +#endif + +#ifndef MICROPY_PY_CMATH #define MICROPY_PY_CMATH (0) +#endif #define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages; +#ifndef MICROPY_HW_UART_TXBUF #define MICROPY_HW_UART_TXBUF (1) +#endif #define CPU_FREQ (48000000) #define DFLL48M_FREQ (48000000) diff --git a/ports/samd/mcu/samd21/mpconfigmcu.mk b/ports/samd/mcu/samd21/mpconfigmcu.mk index cc435da8cc91..287d6d18be7b 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.mk +++ b/ports/samd/mcu/samd21/mpconfigmcu.mk @@ -1 +1,30 @@ SRC_S += shared/runtime/gchelper_m0.s + +LIBM_SRC_C += $(addprefix lib/libm/,\ + acoshf.c \ + asinfacosf.c \ + asinhf.c \ + atan2f.c \ + atanf.c \ + atanhf.c \ + ef_rem_pio2.c \ + erf_lgamma.c \ + fmodf.c \ + kf_cos.c \ + kf_rem_pio2.c \ + kf_sin.c \ + kf_tan.c \ + log1pf.c \ + math.c \ + nearbyintf.c \ + roundf.c \ + sf_cos.c \ + sf_erf.c \ + sf_frexp.c \ + sf_ldexp.c \ + sf_modf.c \ + sf_sin.c \ + sf_tan.c \ + wf_lgamma.c \ + wf_tgamma.c \ + ) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 686cfd6104df..666370c983b7 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -8,10 +8,19 @@ #define MICROPY_EMIT_INLINE_THUMB (1) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) + +#ifndef MICROPY_PY_BUILTINS_COMPLEX #define MICROPY_PY_BUILTINS_COMPLEX (0) +#endif + +#ifndef MICROPY_PY_MATH #define MICROPY_PY_MATH (1) #define MP_NEED_LOG2 (1) +#endif + +#ifndef MICROPY_PY_CMATH #define MICROPY_PY_CMATH (0) +#endif #define MICROPY_PY_MACHINE_DHT_READINTO (1) #define MICROPY_PY_ONEWIRE (1) @@ -30,7 +39,9 @@ unsigned long trng_random_u32(void); #define VFS_BLOCK_SIZE_BYTES (1536) // +#ifndef MICROPY_HW_UART_TXBUF #define MICROPY_HW_UART_TXBUF (1) +#endif #define CPU_FREQ (120000000) #define DFLL48M_FREQ (48000000) From fc9d66fac64422a6a6ea4a79bfd8b2460cc8e9e8 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 15 Sep 2022 15:58:54 +0200 Subject: [PATCH 1902/4290] samd/machine_rtc: Add the machine.RTC class. Methods implemented are: - rtc.init(date) - rtc.datetime([new_date]) - rtc.calibration(value) The presence of this class can be controlled by MICROPY_PY_MACHINE_RTC. If the RTC module is used, the time module uses the RTC as well. For boards without a 32kHz crystal, using RTC makes no sense, since it will then use the ULP32K oscillator, which is not precise at all. Therefore, it will by default only be enabled for boards using a crystal, but can be enabled in the respective mpconfigboard.h. --- ports/samd/Makefile | 1 + ports/samd/fatfs_port.c | 6 +- ports/samd/machine_rtc.c | 181 +++++++++++++++++++++++++++ ports/samd/mcu/samd21/clock_config.c | 17 ++- ports/samd/mcu/samd21/mpconfigmcu.h | 6 + ports/samd/mcu/samd51/clock_config.c | 20 +-- ports/samd/mcu/samd51/mpconfigmcu.h | 6 + ports/samd/modmachine.c | 3 + ports/samd/modmachine.h | 3 + ports/samd/modutime.c | 30 ++++- ports/samd/samd_soc.c | 7 ++ 11 files changed, 263 insertions(+), 17 deletions(-) create mode 100644 ports/samd/machine_rtc.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index abec4e83a553..e6e592a0352b 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -94,6 +94,7 @@ SRC_C += \ machine_i2c.c \ machine_led.c \ machine_pin.c \ + machine_rtc.c \ machine_spi.c \ machine_timer.c \ machine_uart.c \ diff --git a/ports/samd/fatfs_port.c b/ports/samd/fatfs_port.c index 9ee1764ebc0a..a3e3f1b67b3a 100644 --- a/ports/samd/fatfs_port.c +++ b/ports/samd/fatfs_port.c @@ -33,9 +33,13 @@ extern uint32_t time_offset; MP_WEAK DWORD get_fattime(void) { + #if MICROPY_PY_MACHINE_RTC + return (RTC->MODE2.CLOCK.reg >> 1) + (20 << 25); + #else + extern void rtc_gettime(timeutils_struct_time_t *tm); timeutils_struct_time_t tm; - timeutils_seconds_since_epoch_to_struct_time(mp_hal_ticks_ms_64() / 1000 + time_offset, &tm); return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) | ((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) | ((tm.tm_min) << 5) | (tm.tm_sec / 2); + #endif } diff --git a/ports/samd/machine_rtc.c b/ports/samd/machine_rtc.c new file mode 100644 index 000000000000..57bfa998e583 --- /dev/null +++ b/ports/samd/machine_rtc.c @@ -0,0 +1,181 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * Copyright (c) 2022 "Robert Hammelrath" + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "shared/timeutils/timeutils.h" +#include "modmachine.h" +#include "py/mphal.h" +#include "sam.h" + +#if MICROPY_PY_MACHINE_RTC + +typedef struct _machine_rtc_obj_t { + mp_obj_base_t base; + mp_obj_t callback; +} machine_rtc_obj_t; + +// Singleton RTC object. +STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}}; + +// Start the RTC Timer. +void machine_rtc_start(bool force) { + #if defined(MCU_SAMD21) + + if (RTC->MODE2.CTRL.bit.ENABLE == 0 || force) { + // Enable the 1k Clock + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK8 | GCLK_CLKCTRL_ID_RTC; + + RTC->MODE2.CTRL.reg = RTC_MODE2_CTRL_SWRST; + while (RTC->MODE2.STATUS.bit.SYNCBUSY) { + } + RTC->MODE2.CTRL.reg = + RTC_MODE2_CTRL_MODE_CLOCK | + RTC_MODE2_CTRL_PRESCALER_DIV1024 | + RTC_MODE2_CTRL_ENABLE; + while (RTC->MODE2.STATUS.bit.SYNCBUSY) { + } + } + + #elif defined(MCU_SAMD51) + + if (RTC->MODE2.CTRLA.bit.ENABLE == 0 || force) { + RTC->MODE2.CTRLA.reg = RTC_MODE2_CTRLA_SWRST; + while (RTC->MODE2.SYNCBUSY.bit.SWRST) { + } + RTC->MODE2.CTRLA.reg = + RTC_MODE2_CTRLA_MODE_CLOCK | + RTC_MODE2_CTRLA_CLOCKSYNC | + RTC_MODE2_CTRLA_PRESCALER_DIV1024 | + RTC_MODE2_CTRLA_ENABLE; + while (RTC->MODE2.SYNCBUSY.bit.ENABLE) { + } + } + #endif +} + +// Get the time from the RTC and put it into a tm struct. +void rtc_gettime(timeutils_struct_time_t *tm) { + tm->tm_year = RTC->MODE2.CLOCK.bit.YEAR + 2000; + tm->tm_mon = RTC->MODE2.CLOCK.bit.MONTH; + tm->tm_mday = RTC->MODE2.CLOCK.bit.DAY; + tm->tm_hour = RTC->MODE2.CLOCK.bit.HOUR; + tm->tm_min = RTC->MODE2.CLOCK.bit.MINUTE; + tm->tm_sec = RTC->MODE2.CLOCK.bit.SECOND; +} + +STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // Check arguments. + mp_arg_check_num(n_args, n_kw, 0, 0, false); + // RTC was already started at boot time. So nothing to do here. + // Return constant object. + return (mp_obj_t)&machine_rtc_obj; +} + +STATIC mp_obj_t machine_rtc_datetime_helper(size_t n_args, const mp_obj_t *args) { + // Rtc *rtc = RTC; + if (n_args == 1) { + // Get date and time. + timeutils_struct_time_t tm; + rtc_gettime(&tm); + + mp_obj_t tuple[8] = { + mp_obj_new_int(tm.tm_year), + mp_obj_new_int(tm.tm_mon), + mp_obj_new_int(tm.tm_mday), + mp_obj_new_int(timeutils_calc_weekday(tm.tm_year, tm.tm_mon, tm.tm_mday)), + mp_obj_new_int(tm.tm_hour), + mp_obj_new_int(tm.tm_min), + mp_obj_new_int(tm.tm_sec), + mp_obj_new_int(0), + }; + return mp_obj_new_tuple(8, tuple); + } else { + // Set date and time. + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[1], 8, &items); + + uint32_t date = + RTC_MODE2_CLOCK_YEAR(mp_obj_get_int(items[0]) % 100) | + RTC_MODE2_CLOCK_MONTH(mp_obj_get_int(items[1])) | + RTC_MODE2_CLOCK_DAY(mp_obj_get_int(items[2])) | + RTC_MODE2_CLOCK_HOUR(mp_obj_get_int(items[4])) | + RTC_MODE2_CLOCK_MINUTE(mp_obj_get_int(items[5])) | + RTC_MODE2_CLOCK_SECOND(mp_obj_get_int(items[6])); + + RTC->MODE2.CLOCK.reg = date; + #if defined(MCU_SAMD21) + while (RTC->MODE2.STATUS.bit.SYNCBUSY) { + } + #elif defined(MCU_SAMD51) + while (RTC->MODE2.SYNCBUSY.bit.CLOCKSYNC) { + } + #endif + + return mp_const_none; + } +} + +STATIC mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) { + return machine_rtc_datetime_helper(n_args, args); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_datetime_obj, 1, 2, machine_rtc_datetime); + +STATIC mp_obj_t machine_rtc_init(mp_obj_t self_in, mp_obj_t date) { + mp_obj_t args[2] = {self_in, date}; + machine_rtc_datetime_helper(2, args); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_init_obj, machine_rtc_init); + +// calibration(cal) +// When the argument is a number in the range [-16 to 15], set the calibration value. +STATIC mp_obj_t machine_rtc_calibration(mp_obj_t self_in, mp_obj_t cal_in) { + int8_t cal = 0; + // Make it negative for a "natural" behavior: + // value > 0: faster, value < 0: slower + cal = -mp_obj_get_int(cal_in); + RTC->MODE2.FREQCORR.reg = (uint8_t)cal; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_calibration_obj, machine_rtc_calibration); + +STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_rtc_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&machine_rtc_datetime_obj) }, + { MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&machine_rtc_calibration_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + make_new, machine_rtc_make_new, + locals_dict, &machine_rtc_locals_dict + ); + +#endif // MICROPY_PY_MACHINE_RTC diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index a195cb692053..00f743cc49d1 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -141,7 +141,7 @@ void init_clocks(uint32_t cpu_freq) { // GCLK3: 1Mhz for the us-counter (TC4/TC5) // GCLK4: 32kHz from crystal, if present // GCLK5: 48MHz from DFLL for USB - // GCLK8: 1kHz clock for WDT + // GCLK8: 1kHz clock for WDT and RTC NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" NVMCTRL->CTRLB.bit.RWS = 1; // 1 read wait state for 48MHz @@ -203,6 +203,11 @@ void init_clocks(uint32_t cpu_freq) { SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_ENABLE; while (SYSCTRL->PCLKSR.bit.DFLLLCKF == 0) { } + // Set GCLK8 to 1 kHz. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(8); + while (GCLK->STATUS.bit.SYNCBUSY) { + } #else // MICROPY_HW_XOSC32K @@ -242,6 +247,11 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(1); while (GCLK->STATUS.bit.SYNCBUSY) { } + // Set GCLK8 to 1 kHz. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); + while (GCLK->STATUS.bit.SYNCBUSY) { + } #endif // MICROPY_HW_XOSC32K @@ -252,11 +262,6 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(3); while (GCLK->STATUS.bit.SYNCBUSY) { } - // Set GCLK8 to 1 kHz. - GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); - while (GCLK->STATUS.bit.SYNCBUSY) { - } } void enable_sercom_clock(int id) { diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 8d155f93ab03..331df8e2130a 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -28,6 +28,12 @@ #define MICROPY_HW_UART_TXBUF (1) #endif +#ifndef MICROPY_PY_MACHINE_RTC +#if MICROPY_HW_XOSC32K +#define MICROPY_PY_MACHINE_RTC (1) +#endif +#endif + #define CPU_FREQ (48000000) #define DFLL48M_FREQ (48000000) #define MAX_CPU_FREQ (48000000) diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index 3bc4616de9e9..c5f508cae8b6 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -215,16 +215,19 @@ void init_clocks(uint32_t cpu_freq) { #if MICROPY_HW_XOSC32K // OSCILLATOR CONTROL + // Enable the clock for RTC + OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K; // Setup XOSC32K OSC32KCTRL->INTFLAG.reg = OSC32KCTRL_INTFLAG_XOSC32KRDY | OSC32KCTRL_INTFLAG_XOSC32KFAIL; - OSC32KCTRL->XOSC32K.bit.CGM = OSC32KCTRL_XOSC32K_CGM_HS_Val; - OSC32KCTRL->XOSC32K.bit.XTALEN = 1; // 0: Generator 1: Crystal - OSC32KCTRL->XOSC32K.bit.EN32K = 1; - OSC32KCTRL->XOSC32K.bit.ONDEMAND = 0; - OSC32KCTRL->XOSC32K.bit.RUNSTDBY = 1; - OSC32KCTRL->XOSC32K.bit.STARTUP = 4; OSC32KCTRL->CFDCTRL.bit.CFDEN = 1; // Fall back to internal Osc on crystal fail - OSC32KCTRL->XOSC32K.bit.ENABLE = 1; + OSC32KCTRL->XOSC32K.reg = + OSC32KCTRL_XOSC32K_CGM_HS | + OSC32KCTRL_XOSC32K_XTALEN | + OSC32KCTRL_XOSC32K_EN32K | + OSC32KCTRL_XOSC32K_EN1K | + OSC32KCTRL_XOSC32K_RUNSTDBY | + OSC32KCTRL_XOSC32K_STARTUP(4) | + OSC32KCTRL_XOSC32K_ENABLE; // make sure osc32kcrtl is ready while (OSC32KCTRL->STATUS.bit.XOSC32KRDY == 0) { } @@ -270,6 +273,9 @@ void init_clocks(uint32_t cpu_freq) { #else // MICROPY_HW_XOSC32K + // Enable the clock for RTC + OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K; + // Derive GCLK1 from DFLL48M at DPLL0_REF_FREQ as defined in mpconfigboard.h (e.g. 32768 Hz) GCLK->GENCTRL[1].reg = ((DFLL48M_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) << GCLK_GENCTRL_DIV_Pos | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 666370c983b7..541fba9009f3 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -28,6 +28,12 @@ #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) unsigned long trng_random_u32(void); +#ifndef MICROPY_PY_MACHINE_RTC +#if MICROPY_HW_XOSC32K +#define MICROPY_PY_MACHINE_RTC (1) +#endif +#endif + // Due to a limitation in the TC counter for us, the ticks period is 2**29 #define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index ce5fef76f753..12e9f7c34134 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -238,6 +238,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, { 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) }, + #endif { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index e99ca990fbba..8f85e149896f 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -38,5 +38,8 @@ extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_timer_type; extern const mp_obj_type_t machine_uart_type; extern const mp_obj_type_t machine_wdt_type; +#if MICROPY_PY_MACHINE_RTC +extern const mp_obj_type_t machine_rtc_type; +#endif #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/modutime.c b/ports/samd/modutime.c index 4169c15d9117..6b04134497fb 100644 --- a/ports/samd/modutime.c +++ b/ports/samd/modutime.c @@ -29,20 +29,34 @@ #include "shared/timeutils/timeutils.h" #include "mphalport.h" +#if !MICROPY_PY_MACHINE_RTC uint32_t time_offset = 0; +#endif // !MICROPY_PY_MACHINE_RTC // localtime([secs]) STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { timeutils_struct_time_t tm; mp_int_t seconds; + + #if MICROPY_PY_MACHINE_RTC + extern void rtc_gettime(timeutils_struct_time_t *tm); + if (n_args == 0 || args[0] == mp_const_none) { + rtc_gettime(&tm); + } else { + seconds = mp_obj_get_int(args[0]); + timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); + } + + #else if (n_args == 0 || args[0] == mp_const_none) { - // seconds = pyb_rtc_get_us_since_epoch() / 1000 / 1000; seconds = mp_hal_ticks_ms_64() / 1000 + time_offset; } else { seconds = mp_obj_get_int(args[0]); time_offset = seconds - mp_hal_ticks_ms_64() / 1000; } timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); + + #endif // MICROPY_PY_MACHINE_RTC mp_obj_t tuple[8] = { tuple[0] = mp_obj_new_int(tm.tm_year), tuple[1] = mp_obj_new_int(tm.tm_mon), @@ -50,8 +64,8 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { tuple[3] = mp_obj_new_int(tm.tm_hour), tuple[4] = mp_obj_new_int(tm.tm_min), tuple[5] = mp_obj_new_int(tm.tm_sec), - tuple[6] = mp_obj_new_int(tm.tm_wday), - tuple[7] = mp_obj_new_int(tm.tm_yday), + tuple[6] = mp_obj_new_int(timeutils_calc_weekday(tm.tm_year, tm.tm_mon, tm.tm_mday)), + tuple[7] = mp_obj_new_int(timeutils_year_day(tm.tm_year, tm.tm_mon, tm.tm_mday)), }; return mp_obj_new_tuple(8, tuple); } @@ -76,7 +90,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); // time() STATIC mp_obj_t time_time(void) { + #if MICROPY_PY_MACHINE_RTC + extern void rtc_gettime(timeutils_struct_time_t *tm); + timeutils_struct_time_t tm; + rtc_gettime(&tm); + return mp_obj_new_int_from_uint(timeutils_mktime( + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec)); + + #else return mp_obj_new_int_from_uint(mp_hal_ticks_ms_64() / 1000 + time_offset); + + #endif // MICROPY_PY_MACHINE_RTC } STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 3608306e8719..bd3eea536fdb 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -38,6 +38,10 @@ #include "tusb.h" #include "mphalport.h" +#if MICROPY_PY_MACHINE_RTC +extern void machine_rtc_start(bool force); +#endif + static void usb_init(void) { // Init USB clock #if defined(MCU_SAMD21) @@ -114,4 +118,7 @@ void samd_init(void) { #if defined(MCU_SAMD51) mp_hal_ticks_cpu_enable(); #endif + #if MICROPY_PY_MACHINE_RTC + machine_rtc_start(false); + #endif } From e33db80a5958772095a16b0b3753ed3aa72d07b2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 29 Sep 2022 16:13:23 +0200 Subject: [PATCH 1903/4290] samd/clock_config: Extend the SAMD51 us-counter to 60 bit. This removes the difference in the time.ticks_us() range between SAMD21 and SAMD51. The function mp_hal_ticks_us_64() is added and used for: - SAMD51's mp_hal_ticks_us and mp_hal_delay_us(). For SAMD21, keep the previous methods, which are faster. - mp_hal_ticks_ms() and mp_hal_tick_ms_64(), which saves some bytes and removes a potential race condition every 50 days. Also set the us-counter for SAMD51 to 16 MHz for a faster reading of the microsecond value. Note: With SAMD51, mp_hal_ticks_us_64() has a 60 bit range only, which is still a long time (~36000 years). --- ports/samd/mcu/samd51/clock_config.c | 8 +++--- ports/samd/mcu/samd51/mpconfigmcu.h | 3 --- ports/samd/mphalport.c | 40 ++++++++++++++++++++++++---- ports/samd/mphalport.h | 23 +++++----------- ports/samd/samd_isr.c | 24 ++++++++++++----- ports/samd/samd_soc.c | 8 +++++- 6 files changed, 71 insertions(+), 35 deletions(-) diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index c5f508cae8b6..b55419d24b67 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -190,7 +190,7 @@ void init_clocks(uint32_t cpu_freq) { // GCLK0: 48MHz from DFLL48M or 48 - 200 MHz from DPLL0 (SAMD51) // GCLK1: 32768 Hz from 32KULP or DFLL48M // GCLK2: 8-48MHz from DFLL48M for Peripheral devices - // GCLK3: 8Mhz for the us-counter (TC0/TC1) + // GCLK3: 16Mhz for the us-counter (TC0/TC1) // GCLK4: 32kHz from crystal, if present // GCLK5: 48MHz from DFLL48M for USB // DPLL0: 48 - 200 MHz @@ -204,7 +204,7 @@ void init_clocks(uint32_t cpu_freq) { // Setup DPLL0 to 120MHz // Setup GCLK0 to 120MHz // Setup GCLK2 to 48MHz for Peripherals - // Setup GCLK3 to 8MHz for TC0/TC1 + // Setup GCLK3 to 16MHz for TC0/TC1 // Setup GCLK4 to 32kHz crystal, if present // Setup GCLK5 to 48 MHz @@ -320,8 +320,8 @@ void init_clocks(uint32_t cpu_freq) { while (GCLK->SYNCBUSY.bit.GENCTRL2) { } - // Setup GCLK3 for 8MHz, Used for TC0/1 counter - GCLK->GENCTRL[3].reg = GCLK_GENCTRL_DIV(6) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; + // Setup GCLK3 for 16MHz, Used for TC0/1 counter + GCLK->GENCTRL[3].reg = GCLK_GENCTRL_DIV(3) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; while (GCLK->SYNCBUSY.bit.GENCTRL3) { } } diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 541fba9009f3..16b2c101f02b 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -34,9 +34,6 @@ unsigned long trng_random_u32(void); #endif #endif -// Due to a limitation in the TC counter for us, the ticks period is 2**29 -#define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) - // fatfs configuration used in ffconf.h #define MICROPY_FATFS_ENABLE_LFN (1) #define MICROPY_FATFS_RPATH (2) diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index ad3817768f77..b60bada480b4 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -37,6 +37,8 @@ #define MICROPY_HW_STDIN_BUFFER_LEN 128 #endif +extern volatile uint32_t ticks_us64_upper; + STATIC uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN]; ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0 }; @@ -111,19 +113,47 @@ void mp_hal_delay_ms(mp_uint_t ms) { void mp_hal_delay_us(mp_uint_t us) { if (us > 0) { - uint32_t start = mp_hal_ticks_us(); #if defined(MCU_SAMD21) - // SAMD21 counter has effective 32 bit width + uint32_t start = mp_hal_ticks_us(); while ((mp_hal_ticks_us() - start) < us) { } - #elif defined(MCU_SAMD51) - // SAMD51 counter has effective 29 bit width - while (((mp_hal_ticks_us() - start) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)) < us) { + #else + uint64_t stop = mp_hal_ticks_us_64() + us; + while (mp_hal_ticks_us_64() < stop) { } #endif } } +uint64_t mp_hal_ticks_us_64(void) { + uint32_t us64_upper = ticks_us64_upper; + uint32_t us64_lower; + uint8_t intflag; + __disable_irq(); + #if defined(MCU_SAMD21) + us64_lower = REG_TC4_COUNT32_COUNT; + intflag = TC4->COUNT32.INTFLAG.reg; + #elif defined(MCU_SAMD51) + TC0->COUNT32.CTRLBSET.reg = TC_CTRLBSET_CMD_READSYNC; + while (TC0->COUNT32.CTRLBSET.reg != 0) { + } + us64_lower = REG_TC0_COUNT32_COUNT; + intflag = TC0->COUNT32.INTFLAG.reg; + #endif + __enable_irq(); + if ((intflag & TC_INTFLAG_OVF) && us64_lower < 0x10000000) { + // The timer counter overflowed before reading it but the IRQ handler + // has not yet been called, so perform the IRQ arithmetic now. + us64_upper++; + } + #if defined(MCU_SAMD21) + return ((uint64_t)us64_upper << 32) | us64_lower; + #elif defined(MCU_SAMD51) + return ((uint64_t)us64_upper << 28) | (us64_lower >> 4); + #endif + +} + uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { uintptr_t ret = 0; diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index 3879240f9a6a..2cbb3333f60f 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -37,7 +37,7 @@ extern int mp_interrupt_char; extern volatile uint32_t systick_ms; -extern volatile uint32_t systick_ms_upper; +uint64_t mp_hal_ticks_us_64(void); void mp_hal_set_interrupt_char(int c); @@ -47,28 +47,19 @@ void mp_hal_set_interrupt_char(int c); #define mp_hal_delay_us_fast mp_hal_delay_us -static inline mp_uint_t mp_hal_ticks_ms(void) { - return systick_ms; +static inline uint64_t mp_hal_ticks_ms_64(void) { + return mp_hal_ticks_us_64() / 1000; } -static inline uint64_t mp_hal_ticks_ms_64(void) { - return ((uint64_t)systick_ms_upper << 32) + systick_ms; +static inline mp_uint_t mp_hal_ticks_ms(void) { + return (mp_uint_t)mp_hal_ticks_ms_64(); } static inline mp_uint_t mp_hal_ticks_us(void) { #if defined(MCU_SAMD21) - return REG_TC4_COUNT32_COUNT; - - #elif defined(MCU_SAMD51) - - TC0->COUNT32.CTRLBSET.reg = TC_CTRLBSET_CMD_READSYNC; - while (TC0->COUNT32.CTRLBSET.reg != 0) { - } - return REG_TC0_COUNT32_COUNT >> 3; - #else - return systick_ms * 1000; + return (mp_uint_t)mp_hal_ticks_us_64(); #endif } @@ -89,7 +80,7 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { #endif static inline uint64_t mp_hal_time_ns(void) { - return mp_hal_ticks_ms_64() * 1000000; + return mp_hal_ticks_us_64() * 1000; } // C-level pin HAL diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index b507d5d1aa73..1d6febaaa226 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -41,7 +41,7 @@ extern void EIC_Handler(void); const ISR isr_vector[]; volatile uint32_t systick_ms; -volatile uint32_t systick_ms_upper; +volatile uint32_t ticks_us64_upper; void Reset_Handler(void) __attribute__((naked)); void Reset_Handler(void) { @@ -93,15 +93,27 @@ void Default_Handler(void) { void SysTick_Handler(void) { uint32_t next_tick = systick_ms + 1; systick_ms = next_tick; - if (systick_ms == 0) { - systick_ms_upper += 1; - } if (soft_timer_next == next_tick) { pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler); } } +void us_timer_IRQ(void) { + #if defined(MCU_SAMD21) + if (TC4->COUNT32.INTFLAG.reg & TC_INTFLAG_OVF) { + ticks_us64_upper++; + } + TC4->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF; + #elif defined(MCU_SAMD51) + if (TC0->COUNT32.INTFLAG.reg & TC_INTFLAG_OVF) { + ticks_us64_upper++; + } + TC0->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF; + #endif +} + +// Sercom IRQ handler support void (*sercom_irq_handler_table[SERCOM_INST_NUM])(int num) = {}; void sercom_register_irq(int sercom_id, void (*sercom_irq_handler)) { @@ -180,7 +192,7 @@ const ISR isr_vector[] __attribute__((section(".isr_vector"))) = { 0, // 16 Timer Counter Control 1 (TCC1) 0, // 17 Timer Counter Control 2 (TCC2) 0, // 18 Basic Timer Counter 3 (TC3) - 0, // 19 Basic Timer Counter 4 (TC4) + &us_timer_IRQ, // 19 Basic Timer Counter 4 (TC4) 0, // 20 Basic Timer Counter 5 (TC5) 0, // 21 Basic Timer Counter 6 (TC6) 0, // 22 Basic Timer Counter 7 (TC7) @@ -316,7 +328,7 @@ const ISR isr_vector[] __attribute__((section(".isr_vector"))) = { 0, // 104 Timer Counter Control 4 (TCC4): TCC4_CNT_A ... 0, // 105 Timer Counter Control 4 (TCC4): TCC4_MC_0 0, // 106 Timer Counter Control 4 (TCC4): TCC4_MC_1 - 0, // 107 Basic Timer Counter 0 (TC0) + &us_timer_IRQ, // 107 Basic Timer Counter 0 (TC0) 0, // 108 Basic Timer Counter 1 (TC1) 0, // 109 Basic Timer Counter 2 (TC2) 0, // 110 Basic Timer Counter 3 (TC3) diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index bd3eea536fdb..a81e7c68810d 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -68,7 +68,7 @@ static void usb_init(void) { tusb_init(); } -// Initialize the microsecond counter on TC 0/1 +// Initialize the µs counter on TC 0/1 or TC4/5 void init_us_counter(void) { #if defined(MCU_SAMD21) @@ -89,6 +89,9 @@ void init_us_counter(void) { TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ | TC_READREQ_RCONT | 0x10; while (TC4->COUNT32.STATUS.bit.SYNCBUSY) { } + // Enable the IRQ + TC4->COUNT32.INTENSET.reg = TC_INTENSET_OVF; + NVIC_EnableIRQ(TC4_IRQn); #elif defined(MCU_SAMD51) @@ -107,6 +110,9 @@ void init_us_counter(void) { while (TC0->COUNT32.SYNCBUSY.bit.ENABLE) { } + // Enable the IRQ + TC0->COUNT32.INTENSET.reg = TC_INTENSET_OVF; + NVIC_EnableIRQ(TC0_IRQn); #endif } From e7aa9700cad4ace55fb9100c98b2bbfa811870d2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 4 Oct 2022 13:39:43 +0200 Subject: [PATCH 1904/4290] samd/boards/SEEED_WIO_TERMINAL: Declare more pins for SEEED WIO board. Defining all pins from the external 40 Pin connector, and some internal pins like the one for SD and LCD. --- ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv index 72da71224a4d..9bc57070d198 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv @@ -22,9 +22,43 @@ PIN_PD20,SWITCH_U PIN_PC26,BUTTON_1 PIN_PC27,BUTTON_2 PIN_PC28,BUTTON_3 -PIN_PD11,BUZZER_CTR PIN_PC14,5V_ENABLE PIN_PC15,3V3_ENABLE +PIN_PB26,TX +PIN_PB27,RX +PIN_PA13,SDA0 +PIN_PA12,SCL0 +PIN_PA17,SDA1 +PIN_PA16,SCL1 +PIN_PB02,MOSI +PIN_PB00,MISO +PIN_PB03,SCK +PIN_PB01,CS +PIN_PB15,GPCLK0 +PIN_PB12,GPCLK1 +PIN_PB13,GPCLK2 +PIN_PC16,SD_MOSI +PIN_PC18,SD_MISO +PIN_PC17,SD_SCK +PIN_PC19,SD_CS +PIN_PD21,SD_DET +PIN_PA20,I2S_LRCLK +PIN_PA21,I2S_SDIN +PIN_PA22,I2S_SDOUT +PIN_PB16,I2C_BCLK +PIN_PB18,LCD_MISO +PIN_PB19,LCD_MOSI +PIN_PB20,LCD_SCK +PIN_PB21,LCD_CS +PIN_PC05,LCD_BACKLIGHT +PIN_PC06,LCD_D/C +PIN_PC07,LCD_RESET +PIN_PC10,LCD_XL +PIN_PC11,LCD_YU +PIN_PC12,LCD_XR +PIN_PC13,LCD_YD +PIN_PC30,MIC +PIN_PD11,BUZZER LED_PA15,LED_BLUE LED_PC05,LED_LCD From e5cf3fab951adf39e7d39c2a8600b61f84e517ce Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 17 Sep 2022 17:27:27 +0200 Subject: [PATCH 1905/4290] samd/machine_pin: Change the pin handling and naming/numbering. Pin numbers are now the MCU port numbers in the range: PA0..PA31: 0..31 PB0..PB31: 32..63 PC0..PC31: 64..95 PD0..PD31: 96..127 Pins can be denoted by the GPIO port number, the name as defined in pins.csv or a string in the form Pxnn, like "PA16" or "PD03". The pins.c and pins.h files are now obsolete. The pin objects are part of the AF table. As result of a simplification, the code now supports using pin names or numbers instead of pin objects for modules like UART, SPI, PWM, I2C, ADC, pininfo. --- ports/samd/Makefile | 26 +--- .../{make-pin-af.py => make-pin-table.py} | 54 +++++++- ports/samd/boards/make-pins.py | 128 ------------------ ports/samd/machine_adc.c | 4 +- ports/samd/machine_led.c | 27 ++-- ports/samd/machine_pin.c | 119 ++++++---------- ports/samd/machine_pwm.c | 4 +- ports/samd/modsamd.c | 60 ++++---- ports/samd/pin_af.c | 69 +++++++++- ports/samd/pin_af.h | 18 ++- 10 files changed, 221 insertions(+), 288 deletions(-) rename ports/samd/boards/{make-pin-af.py => make-pin-table.py} (59%) delete mode 100644 ports/samd/boards/make-pins.py diff --git a/ports/samd/Makefile b/ports/samd/Makefile index e6e592a0352b..f512fb0b2e33 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -47,14 +47,10 @@ INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include/pio INC += -I$(TOP)/lib/tinyusb/src -MAKE_PIN_AF = boards/make-pin-af.py +MAKE_PIN_AF = boards/make-pin-table.py PIN_AF_TABLE_CSV = mcu/$(MCU_SERIES_LOWER)/pin-af-table.csv -GEN_PIN_AF = pin_af_table.c - -MAKE_PINS = boards/make-pins.py BOARD_PINS = $(BOARD_DIR)/pins.csv -GEN_PINS_SRC = $(BUILD)/pins.c -GEN_PINS_HDR = $(BUILD)/pins.h +GEN_PIN_AF = pin_af_table.c CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard @@ -150,7 +146,7 @@ DRIVERS_SRC_C += \ drivers/bus/softspi.c \ # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(SRC_CXX) $(GEN_PINS_SRC) +SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(SRC_CXX) OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) @@ -161,7 +157,6 @@ OBJ += $(addprefix $(BUILD)/, $(ASF4_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(LIBM_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o)) -OBJ += $(GEN_PINS_SRC:.c=.o) ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_MODULE_FROZEN_MPY @@ -182,19 +177,10 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin $(Q)$(PYTHON) $(UF2CONV) -b $(TEXT0) -c -o $@ $< -pin_af.c: $(BUILD)/$(GEN_PIN_AF) +pin_af.c: $(BUILD)/$(GEN_PIN_AF) | $(HEADER_BUILD) -$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) | $(HEADER_BUILD) +$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) $(BOARD_PINS) | $(HEADER_BUILD) $(ECHO) "Create $@" - $(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES) - -machine_led.c machine_pin.c modsamd.c: $(GEN_PINS_HDR) - -$(GEN_PINS_SRC) $(GEN_PINS_HDR): $(BOARD_PINS) | $(HEADER_BUILD) - $(ECHO) "Create $@" - $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --pins $(GEN_PINS_SRC) --inc $(GEN_PINS_HDR) - -$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC) - $(call compile_c) + $(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --board $(BOARD_PINS) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES) include $(TOP)/py/mkrules.mk diff --git a/ports/samd/boards/make-pin-af.py b/ports/samd/boards/make-pin-table.py similarity index 59% rename from ports/samd/boards/make-pin-af.py rename to ports/samd/boards/make-pin-table.py index d895ef9dd99a..327478568afa 100644 --- a/ports/samd/boards/make-pin-af.py +++ b/ports/samd/boards/make-pin-table.py @@ -16,6 +16,7 @@ class Pins: def __init__(self): self.board_pins = [] # list of pin objects + self.pin_names = {} def parse_csv_file(self, filename): with open(filename, "r") as csvfile: @@ -25,17 +26,43 @@ def parse_csv_file(self, filename): if len(row) > 0 and row[0].strip().upper()[:2] in ("PA", "PB", "PC", "PD"): self.board_pins.append(row) + def parse_pin_file(self, filename): + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile, skipinitialspace=True) + for row in rows: + # Pin numbers must start with "PIN_" + # LED numbers must start with "LED_" + if len(row) > 0: + # for compatibility, map LED_ to PIN_ + if row[0].startswith("LED_"): + row[0] = "PIN_" + row[0][4:] + if len(row) == 1: + self.pin_names[row[0]] = (row[0][4:], "{&machine_led_type}") + else: + self.pin_names[row[0]] = (row[1], "{&machine_led_type}") + elif row[0].startswith("PIN_"): + if len(row) == 1: + self.pin_names[row[0]] = (row[0][4:], "{&machine_pin_type}") + else: + self.pin_names[row[0]] = (row[1], "{&machine_pin_type}") + def print_table(self, table_filename, mcu_name): with open(table_filename, "wt") as table_file: table_file.write(table_header) - table_file.write("const pin_af_t pin_af_table[] = {\n") + table_file.write("const machine_pin_obj_t pin_af_table[] = {\n") if mcu_name == "SAMD21": for row in self.board_pins: pin = "PIN_" + row[0].upper() table_file.write(" #ifdef " + pin + "\n") eic = row[1] if row[1] else "0xff" adc = row[2] if row[2] else "0xff" - table_file.write(" {%s, %s, %s" % (pin, eic, adc)) + if pin in self.pin_names: + name = '"%s"' % self.pin_names[pin][0] + type = self.pin_names[pin][1] + else: + name = '"-"' + type = "{&machine_pin_type}" + table_file.write(" {%s, %s, %s, %s, %s" % (type, pin, name, eic, adc)) for cell in row[3:]: if cell: table_file.write( @@ -52,7 +79,15 @@ def print_table(self, table_filename, mcu_name): eic = row[1] if row[1] else "0xff" adc0 = row[2] if row[2] else "0xff" adc1 = row[3] if row[3] else "0xff" - table_file.write(" {%s, %s, %s, %s" % (pin, eic, adc0, adc1)) + if pin in self.pin_names: + name = '"%s"' % self.pin_names[pin][0] + type = self.pin_names[pin][1] + else: + name = '"-"' + type = "{&machine_pin_type}" + table_file.write( + " {%s, %s, %s, %s, %s, %s" % (type, pin, name, eic, adc0, adc1) + ) for cell in row[4:]: if cell: table_file.write( @@ -67,7 +102,7 @@ def print_table(self, table_filename, mcu_name): def main(): parser = argparse.ArgumentParser( - prog="make-pin-cap.py", + prog="make-pin-af.py", usage="%(prog)s [options] [command]", description="Generate MCU-specific pin cap table file", ) @@ -75,7 +110,13 @@ def main(): "-c", "--csv", dest="csv_filename", - help="Specifies the pin-mux-xxxx.csv filename", + help="Specifies the pin-af-table.csv filename", + ) + parser.add_argument( + "-b", + "--board", + dest="pin_filename", + help="Specifies the pins.csv filename", ) parser.add_argument( "-t", @@ -96,6 +137,9 @@ def main(): if args.csv_filename: pins.parse_csv_file(args.csv_filename) + if args.pin_filename: + pins.parse_pin_file(args.pin_filename) + if args.table_filename: pins.print_table(args.table_filename, args.mcu_name) diff --git a/ports/samd/boards/make-pins.py b/ports/samd/boards/make-pins.py deleted file mode 100644 index 679e2c9d192c..000000000000 --- a/ports/samd/boards/make-pins.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -"""Generates the pins file for the SAMD port.""" - -from __future__ import print_function - -import argparse -import sys -import csv - -pins_header_prefix = """// This file was automatically generated by make-pins.py -// -typedef struct _machine_pin_obj_t { - mp_obj_base_t base; - uint32_t id; - char *name; -} machine_pin_obj_t; - -int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size); - -""" - -led_header_prefix = """typedef struct _machine_led_obj_t { - mp_obj_base_t base; - uint32_t id; - char *name; -} machine_led_obj_t; - -""" - - -class Pins: - def __init__(self): - self.board_pins = [] # list of pin objects - self.board_leds = [] # list of led objects - - def parse_csv_file(self, filename): - with open(filename, "r") as csvfile: - rows = csv.reader(csvfile, skipinitialspace=True) - for row in rows: - # Pin numbers must start with "PIN_" - # LED numbers must start with "LED_" - if len(row) > 0: - if row[0].startswith("PIN_"): - if len(row) == 1: - self.board_pins.append([row[0], row[0][4:]]) - else: - self.board_pins.append([row[0], row[1]]) - elif row[0].startswith("LED_"): - self.board_leds.append(["PIN_" + row[0][4:], row[1]]) - elif row[0].startswith("-"): - self.board_pins.append(["-1", ""]) - - def print_pins(self, pins_filename): - with open(pins_filename, "wt") as pins_file: - pins_file.write("// This file was automatically generated by make-pins.py\n") - pins_file.write("//\n") - pins_file.write('#include "modmachine.h"\n') - pins_file.write('#include "sam.h"\n') - pins_file.write('#include "pins.h"\n\n') - - pins_file.write("const machine_pin_obj_t machine_pin_obj[] = {\n") - for pin in self.board_pins: - pins_file.write(" {{&machine_pin_type}, ") - pins_file.write(pin[0] + ', "' + pin[1]) - pins_file.write('"},\n') - pins_file.write("};\n") - - if self.board_leds: - pins_file.write("\nconst machine_led_obj_t machine_led_obj[] = {\n") - for pin in self.board_leds: - pins_file.write(" {{&machine_led_type}, ") - pins_file.write(pin[0] + ', "' + pin[1]) - pins_file.write('"},\n') - pins_file.write("};\n") - - def print_header(self, hdr_filename): - with open(hdr_filename, "wt") as hdr_file: - hdr_file.write(pins_header_prefix) - if self.board_leds: - hdr_file.write(led_header_prefix) - hdr_file.write( - "extern const machine_pin_obj_t machine_pin_obj[%d];\n" % len(self.board_pins) - ) - if self.board_leds: - hdr_file.write( - "extern const machine_led_obj_t machine_led_obj[%d];\n" % len(self.board_leds) - ) - - -def main(): - parser = argparse.ArgumentParser( - prog="make-pins.py", - usage="%(prog)s [options] [command]", - description="Generate board specific pin file", - ) - parser.add_argument( - "-b", - "--board", - dest="csv_filename", - help="Specifies the pins.csv filename", - ) - parser.add_argument( - "-p", - "--pins", - dest="pins_filename", - help="Specifies the name of the generated pins.c file", - ) - parser.add_argument( - "-i", - "--inc", - dest="hdr_filename", - help="Specifies name of generated pin header file", - ) - args = parser.parse_args(sys.argv[1:]) - - pins = Pins() - - if args.csv_filename: - pins.parse_csv_file(args.csv_filename) - - if args.pins_filename: - pins.print_pins(args.pins_filename) - - pins.print_header(args.hdr_filename) - - -if __name__ == "__main__": - main() diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c index 97b6a14f17a4..efe0f041cdfa 100644 --- a/ports/samd/machine_adc.c +++ b/ports/samd/machine_adc.c @@ -66,8 +66,8 @@ STATIC void adc_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t k (void)kind; machine_adc_obj_t *self = MP_OBJ_TO_PTR(o); - mp_printf(print, "ADC(P%c%02u, ADC%u, channel=%u, bits=%u, average=%u)", - "ABCD"[self->id / 32], self->id % 32, self->adc_config.device, + mp_printf(print, "ADC(%s, ADC%u, channel=%u, bits=%u, average=%u)", + pin_name(self->id), self->adc_config.device, self->adc_config.channel, self->bits, 1 << self->avg); } diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c index 54c2cb18bc86..c18bc052bd2f 100644 --- a/ports/samd/machine_led.c +++ b/ports/samd/machine_led.c @@ -30,7 +30,7 @@ #include "py/mphal.h" #include "extmod/virtpin.h" #include "modmachine.h" -#include "pins.h" +#include "pin_af.h" extern mp_obj_t machine_pin_low_obj; extern mp_obj_t machine_pin_high_obj; @@ -38,8 +38,10 @@ extern mp_obj_t machine_pin_toggle_obj; extern mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - machine_led_obj_t *self = self_in; - mp_printf(print, "LED(\"%s\")", self->name); + machine_pin_obj_t *self = self_in; + mp_printf(print, "LED(\"%s\", GPIO=P%c%02u)", + pin_name(self->pin_id), + "ABCD"[self->pin_id / 32], self->pin_id % 32); } // constructor(id, ...) @@ -47,23 +49,16 @@ mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); // get the wanted LED object - int wanted_led = pin_find(args[0], (const machine_pin_obj_t *)machine_led_obj, MP_ARRAY_SIZE(machine_led_obj)); - const machine_led_obj_t *self = NULL; - if (0 <= wanted_led && wanted_led < MP_ARRAY_SIZE(machine_led_obj)) { - self = (machine_led_obj_t *)&machine_led_obj[wanted_led]; - } - // the array could be padded with 'nulls' (see other Ports). - // Will also error if the asked for LED (index) is greater than the array row size. - if (self == NULL || self->base.type == NULL) { - mp_raise_ValueError(MP_ERROR_TEXT("invalid LED")); - } - mp_hal_pin_output(self->id); - mp_hal_pin_low(self->id); + const machine_pin_obj_t *self; + + self = pin_find(args[0], &machine_led_type); + + mp_hal_pin_output(self->pin_id); + mp_hal_pin_low(self->pin_id); return MP_OBJ_FROM_PTR(self); } - STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = { // instance methods { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) }, diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 2dc10f9b4634..a7cd86d386ed 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -34,7 +34,6 @@ #include "extmod/virtpin.h" #include "modmachine.h" #include "samd_soc.h" -#include "pins.h" #include "pin_af.h" #include "hal_gpio.h" @@ -68,17 +67,17 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin machine_pin_obj_t *self = self_in; char *mode_str; char *pull_str[] = {"PULL_OFF", "PULL_UP", "PULL_DOWN"}; - if (GPIO_IS_OPEN_DRAIN(self->id)) { + if (GPIO_IS_OPEN_DRAIN(self->pin_id)) { mode_str = "OPEN_DRAIN"; } else { - mode_str = (mp_hal_get_pin_direction(self->id) == GPIO_DIRECTION_OUT) ? "OUT" : "IN"; + mode_str = (mp_hal_get_pin_direction(self->pin_id) == GPIO_DIRECTION_OUT) ? "OUT" : "IN"; } mp_printf(print, "Pin(\"%s\", mode=%s, pull=%s, GPIO=P%c%02u)", - self->name, + pin_name(self->pin_id), mode_str, - pull_str[mp_hal_get_pull_mode(self->id)], - "ABCD"[self->id / 32], self->id % 32); + pull_str[mp_hal_get_pull_mode(self->pin_id)], + "ABCD"[self->pin_id / 32], self->pin_id % 32); } STATIC void pin_validate_drive(bool strength) { @@ -87,25 +86,6 @@ STATIC void pin_validate_drive(bool strength) { } } -int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size) { - int wanted_pin = -1; - if (mp_obj_is_small_int(pin)) { - // Pin defined by the index of pin table - wanted_pin = mp_obj_get_int(pin); - } else if (mp_obj_is_str(pin)) { - // Search by name - size_t slen; - const char *s = mp_obj_str_get_data(pin, &slen); - for (wanted_pin = 0; wanted_pin < table_size; wanted_pin++) { - if (slen == strlen(machine_pin_obj[wanted_pin].name) && - strncmp(s, machine_pin_obj[wanted_pin].name, slen) == 0) { - break; - } - } - } - return wanted_pin; -} - // Pin.init(mode, pull=None, *, value=None, drive=0). No 'alt' yet. STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt }; @@ -120,32 +100,34 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + // clear any existing mux setting + mp_hal_clr_pin_mux(self->pin_id); // set initial value (do this before configuring mode/pull) if (args[ARG_value].u_obj != mp_const_none) { - mp_hal_pin_write(self->id, mp_obj_is_true(args[ARG_value].u_obj)); + mp_hal_pin_write(self->pin_id, mp_obj_is_true(args[ARG_value].u_obj)); } // configure mode if (args[ARG_mode].u_obj != mp_const_none) { mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj); if (mode == GPIO_MODE_IN) { - mp_hal_pin_input(self->id); + mp_hal_pin_input(self->pin_id); } else if (mode == GPIO_MODE_OUT) { - mp_hal_pin_output(self->id); + mp_hal_pin_output(self->pin_id); } else if (mode == GPIO_MODE_OPEN_DRAIN) { - mp_hal_pin_open_drain(self->id); + mp_hal_pin_open_drain(self->pin_id); } else { - mp_hal_pin_input(self->id); // If no args are given, the Pin is 'input'. + mp_hal_pin_input(self->pin_id); // If no args are given, the Pin is 'input'. } } // configure pull. Only to be used with IN mode. The function sets the pin to INPUT. uint32_t pull = 0; - mp_int_t dir = mp_hal_get_pin_direction(self->id); + mp_int_t dir = mp_hal_get_pin_direction(self->pin_id); if (dir == GPIO_DIRECTION_OUT && args[ARG_pull].u_obj != mp_const_none) { mp_raise_ValueError(MP_ERROR_TEXT("OUT incompatible with pull")); } else if (args[ARG_pull].u_obj != mp_const_none) { pull = mp_obj_get_int(args[ARG_pull].u_obj); - gpio_set_pin_pull_mode(self->id, pull); // hal_gpio.h + gpio_set_pin_pull_mode(self->pin_id, pull); // hal_gpio.h } // get the strength @@ -158,18 +140,10 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ // constructor(id, ...) mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + const machine_pin_obj_t *self; // get the wanted pin object - int wanted_pin = pin_find(args[0], machine_pin_obj, MP_ARRAY_SIZE(machine_pin_obj)); - - const machine_pin_obj_t *self = NULL; - if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_obj)) { - self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin]; - } - - if (self == NULL || self->base.type == NULL) { - mp_raise_ValueError(MP_ERROR_TEXT("invalid pin")); - } + self = pin_find(args[0], &machine_pin_type); if (n_args > 1 || n_kw > 0) { // pin mode given, so configure this GPIO @@ -187,18 +161,18 @@ mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp machine_pin_obj_t *self = self_in; if (n_args == 0) { // get pin - return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self->id)); + return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self->pin_id)); } else { // set pin bool value = mp_obj_is_true(args[0]); - if (GPIO_IS_OPEN_DRAIN(self->id)) { + if (GPIO_IS_OPEN_DRAIN(self->pin_id)) { if (value == 0) { - mp_hal_pin_od_low(self->id); + mp_hal_pin_od_low(self->pin_id); } else { - mp_hal_pin_od_high(self->id); + mp_hal_pin_od_high(self->pin_id); } } else { - mp_hal_pin_write(self->id, value); + mp_hal_pin_write(self->pin_id, value); } return mp_const_none; } @@ -219,7 +193,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_ // Pin.disable(pin) STATIC mp_obj_t machine_pin_disable(mp_obj_t self_in) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - gpio_set_pin_direction(self->id, GPIO_DIRECTION_OFF); // Disables the pin (low power state) + gpio_set_pin_direction(self->pin_id, GPIO_DIRECTION_OFF); // Disables the pin (low power state) return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable); @@ -227,10 +201,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable); // Pin.low() Totem-pole (push-pull) STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (GPIO_IS_OPEN_DRAIN(self->id)) { - mp_hal_pin_od_low(self->id); + if (GPIO_IS_OPEN_DRAIN(self->pin_id)) { + mp_hal_pin_od_low(self->pin_id); } else { - mp_hal_pin_low(self->id); + mp_hal_pin_low(self->pin_id); } return mp_const_none; } @@ -239,10 +213,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low); // Pin.high() Totem-pole (push-pull) STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (GPIO_IS_OPEN_DRAIN(self->id)) { - mp_hal_pin_od_high(self->id); + if (GPIO_IS_OPEN_DRAIN(self->pin_id)) { + mp_hal_pin_od_high(self->pin_id); } else { - mp_hal_pin_high(self->id); + mp_hal_pin_high(self->pin_id); } return mp_const_none; } @@ -255,16 +229,16 @@ STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { // Determine DIRECTION of PIN. bool pin_dir; - if (GPIO_IS_OPEN_DRAIN(self->id)) { - pin_dir = mp_hal_get_pin_direction(self->id); + if (GPIO_IS_OPEN_DRAIN(self->pin_id)) { + pin_dir = mp_hal_get_pin_direction(self->pin_id); if (pin_dir) { // Pin is output, thus low, switch to high - mp_hal_pin_od_high(self->id); + mp_hal_pin_od_high(self->pin_id); } else { - mp_hal_pin_od_low(self->id); + mp_hal_pin_od_low(self->pin_id); } } else { - gpio_toggle_pin_level(self->id); + gpio_toggle_pin_level(self->pin_id); } return mp_const_none; } @@ -280,8 +254,8 @@ STATIC mp_obj_t machine_pin_drive(size_t n_args, const mp_obj_t *args) { pin_validate_drive(strength); // Set the DRVSTR bit (ASF hri/hri_port_dxx.h hri_port_write_PINCFG_DRVSTR_bit(PORT, - (enum gpio_port)GPIO_PORT(self->id), - GPIO_PIN(self->id), + (enum gpio_port)GPIO_PORT(self->pin_id), + GPIO_PIN(self->pin_id), strength); return mp_const_none; } @@ -301,9 +275,9 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // Get the IRQ object. - uint8_t eic_id = get_pin_af_info(self->id)->eic; + uint8_t eic_id = get_pin_obj_ptr(self->pin_id)->eic; machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); - if (irq != NULL && irq->pin_id != self->id) { + if (irq != NULL && irq->pin_id != self->pin_id) { mp_raise_ValueError(MP_ERROR_TEXT("IRQ already used")); } @@ -322,7 +296,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_ if (n_args > 1 || kw_args->used != 0) { // set the mux config of the pin. - mp_hal_set_pin_mux(self->id, ALT_FCT_EIC); + mp_hal_set_pin_mux(self->pin_id, ALT_FCT_EIC); // Configure IRQ. #if defined(MCU_SAMD21) @@ -362,7 +336,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_ irq->base.ishard = args[ARG_hard].u_bool; irq->flags = 0; irq->trigger = args[ARG_trigger].u_int; - irq->pin_id = self->id; + irq->pin_id = self->pin_id; // Enable IRQ if a handler is given. if (args[ARG_handler].u_obj != mp_const_none) { @@ -457,10 +431,10 @@ STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, i switch (request) { case MP_PIN_READ: { - return mp_hal_pin_read(self->id); + return mp_hal_pin_read(self->pin_id); } case MP_PIN_WRITE: { - mp_hal_pin_write(self->id, arg); + mp_hal_pin_write(self->pin_id, arg); return 0; } } @@ -494,7 +468,7 @@ static uint8_t find_eic_id(int pin) { STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint8_t eic_id = find_eic_id(self->id); + uint8_t eic_id = find_eic_id(self->pin_id); if (eic_id != 0xff) { machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); EIC->INTENCLR.reg |= (1 << eic_id); @@ -507,7 +481,7 @@ STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger STATIC mp_uint_t machine_pin_irq_info(mp_obj_t self_in, mp_uint_t info_type) { machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint8_t eic_id = find_eic_id(self->id); + uint8_t eic_id = find_eic_id(self->pin_id); if (eic_id != 0xff) { machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]); if (info_type == MP_IRQ_INFO_FLAGS) { @@ -525,11 +499,8 @@ STATIC const mp_irq_methods_t machine_pin_irq_methods = { }; mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) { - if (!mp_obj_is_type(obj, &machine_pin_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin")); - } - machine_pin_obj_t *pin = MP_OBJ_TO_PTR(obj); - return pin->id; + const machine_pin_obj_t *pin = pin_find(obj, &machine_pin_type); + return pin->pin_id; } MP_REGISTER_ROOT_POINTER(void *machine_pin_irq_objects[16]); diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c index d987927d310c..91982a6f74a8 100644 --- a/ports/samd/machine_pwm.c +++ b/ports/samd/machine_pwm.c @@ -107,8 +107,8 @@ STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "PWM P%c%02u device=%u channel=%u output=%u", - "ABCD"[self->pin_id / 32], self->pin_id % 32, self->device, self->channel, self->output); + mp_printf(print, "PWM %s device=%u channel=%u output=%u", + pin_name(self->pin_id), self->device, self->channel, self->output); } // PWM(pin) diff --git a/ports/samd/modsamd.c b/ports/samd/modsamd.c index 05ed69bad014..79e7b4cc35f1 100644 --- a/ports/samd/modsamd.c +++ b/ports/samd/modsamd.c @@ -30,42 +30,40 @@ #include "sam.h" #include "pin_af.h" -#include "pins.h" #include "samd_soc.h" extern const mp_obj_type_t samd_flash_type; STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) { - mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_obj); - const pin_af_t *pin_af = get_pin_af_info(pin); - const char *name = ((machine_pin_obj_t *)MP_OBJ_TO_PTR(pin_obj))->name; - if (pin_af) { - #if defined(MCU_SAMD21) - mp_obj_t tuple[7] = { - tuple[0] = mp_obj_new_str(name, strlen(name)), - tuple[1] = mp_obj_new_int(pin_af->eic), - tuple[2] = mp_obj_new_int(pin_af->adc0), - tuple[3] = mp_obj_new_int(pin_af->sercom1), - tuple[4] = mp_obj_new_int(pin_af->sercom2), - tuple[5] = mp_obj_new_int(pin_af->tcc1), - tuple[6] = mp_obj_new_int(pin_af->tcc2), - }; - return mp_obj_new_tuple(7, tuple); - #elif defined(MCU_SAMD51) - mp_obj_t tuple[9] = { - tuple[0] = mp_obj_new_str(name, strlen(name)), - tuple[1] = mp_obj_new_int(pin_af->eic), - tuple[2] = mp_obj_new_int(pin_af->adc0), - tuple[3] = mp_obj_new_int(pin_af->adc1), - tuple[4] = mp_obj_new_int(pin_af->sercom1), - tuple[5] = mp_obj_new_int(pin_af->sercom2), - tuple[6] = mp_obj_new_int(pin_af->tc), - tuple[7] = mp_obj_new_int(pin_af->tcc1), - tuple[8] = mp_obj_new_int(pin_af->tcc2), - }; - return mp_obj_new_tuple(9, tuple); - #endif - } + const machine_pin_obj_t *pin_af = pin_find(pin_obj, NULL); + // Get the name, now that it is not in the pin object + const char *name = pin_af->name; + + #if defined(MCU_SAMD21) + mp_obj_t tuple[7] = { + tuple[0] = mp_obj_new_str(name, strlen(name)), + tuple[1] = mp_obj_new_int(pin_af->eic), + tuple[2] = mp_obj_new_int(pin_af->adc0), + tuple[3] = mp_obj_new_int(pin_af->sercom1), + tuple[4] = mp_obj_new_int(pin_af->sercom2), + tuple[5] = mp_obj_new_int(pin_af->tcc1), + tuple[6] = mp_obj_new_int(pin_af->tcc2), + }; + return mp_obj_new_tuple(7, tuple); + #elif defined(MCU_SAMD51) + mp_obj_t tuple[9] = { + tuple[0] = mp_obj_new_str(name, strlen(name)), + tuple[1] = mp_obj_new_int(pin_af->eic), + tuple[2] = mp_obj_new_int(pin_af->adc0), + tuple[3] = mp_obj_new_int(pin_af->adc1), + tuple[4] = mp_obj_new_int(pin_af->sercom1), + tuple[5] = mp_obj_new_int(pin_af->sercom2), + tuple[6] = mp_obj_new_int(pin_af->tc), + tuple[7] = mp_obj_new_int(pin_af->tcc1), + tuple[8] = mp_obj_new_int(pin_af->tcc2), + }; + return mp_obj_new_tuple(9, tuple); + #endif return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(samd_pininfo_obj, samd_pininfo); diff --git a/ports/samd/pin_af.c b/ports/samd/pin_af.c index 926c4ae0c23a..fc2a0f3d54d9 100644 --- a/ports/samd/pin_af.c +++ b/ports/samd/pin_af.c @@ -29,7 +29,9 @@ */ #include +#include "string.h" +#include "modmachine.h" #include "py/runtime.h" #include "py/misc.h" #include "pin_af.h" @@ -43,13 +45,65 @@ extern const uint8_t tcc_channel_count[]; // Just look for an table entry for a given pin and raise an error // in case of no match (which should not happen). -const pin_af_t *get_pin_af_info(int pin_id) { +const machine_pin_obj_t *get_pin_obj_ptr(int pin_id) { for (int i = 0; i < MP_ARRAY_SIZE(pin_af_table); i++) { if (pin_af_table[i].pin_id == pin_id) { // Pin match return &pin_af_table[i]; } } - mp_raise_ValueError(MP_ERROR_TEXT("wrong pin")); + mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); +} + +const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type) { + const machine_pin_obj_t *self = NULL; + // Is already a object of the proper type + if (mp_obj_is_type(pin, type)) { + return pin; + } + if (mp_obj_is_small_int(pin)) { + // Pin defined by pin number for PAnn, PBnn, etc. + self = get_pin_obj_ptr(mp_obj_get_int(pin)); + } else if (mp_obj_is_str(pin)) { + // Search by name + size_t slen; + const char *s = mp_obj_str_get_data(pin, &slen); + // Check for a string like PA02 or PD12 + if (slen == 4 && s[0] == 'P' && strchr("ABCD", s[1]) != NULL && + strchr("0123456789", s[2]) != NULL && strchr("0123456789", s[2]) != NULL) { + int num = (s[1] - 'A') * 32 + (s[2] - '0') * 10 + (s[3] - '0'); + self = get_pin_obj_ptr(num); + } else { + for (int i = 0; i < MP_ARRAY_SIZE(pin_af_table); i++) { + if (slen == strlen(pin_af_table[i].name) && + strncmp(s, pin_af_table[i].name, slen) == 0) { + self = &pin_af_table[i]; + } + } + } + } + if (self != NULL && (type == NULL || mp_obj_is_type(self, type))) { + return self; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); + } +} + +const char *pin_name(int id) { + static char board_name[5] = "Pxnn"; + for (int i = 0; i < sizeof(pin_af_table); i++) { + if (pin_af_table[i].pin_id == id) { + if (pin_af_table[i].name[0] != '-') { + return pin_af_table[i].name; + } else { + board_name[1] = "ABCD"[id / 32]; + id %= 32; + board_name[2] = '0' + id / 10; + board_name[3] = '0' + id % 10; + return board_name; + } + } + } + return "-"; } // Test, wether the given pin is defined and has signals for sercom. @@ -57,7 +111,7 @@ const pin_af_t *get_pin_af_info(int pin_id) { // If not, an error will be raised. sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) { - const pin_af_t *pct_ptr = get_pin_af_info(pin_id); + const machine_pin_obj_t *pct_ptr = get_pin_obj_ptr(pin_id); if ((pct_ptr->sercom1 >> 4) == sercom_nr) { return (sercom_pad_config_t) {ALT_FCT_SERCOM1, pct_ptr->sercom1 & 0x0f}; } else if ((pct_ptr->sercom2 >> 4) == sercom_nr) { @@ -72,7 +126,12 @@ sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) { // If not, an error will be raised. adc_config_t get_adc_config(int pin_id, int32_t flag) { - const pin_af_t *pct_ptr = get_pin_af_info(pin_id); + const machine_pin_obj_t *pct_ptr = get_pin_obj_ptr(pin_id); + #if defined(MCU_SAMD51) + if (pct_ptr->adc1 != 0xff && (flag & (1 << (pct_ptr->adc1 + 16))) == 0) { + return (adc_config_t) {1, pct_ptr->adc1}; + } else + #endif if (pct_ptr->adc0 != 0xff && (flag & (1 << pct_ptr->adc0)) == 0) { return (adc_config_t) {0, pct_ptr->adc0}; #if defined(MUC_SAMD51) @@ -91,7 +150,7 @@ adc_config_t get_adc_config(int pin_id, int32_t flag) { // tries to provide an unused device, if available. pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t device_status[]) { - const pin_af_t *pct_ptr = get_pin_af_info(pin_id); + const machine_pin_obj_t *pct_ptr = get_pin_obj_ptr(pin_id); uint8_t tcc1 = pct_ptr->tcc1; uint8_t tcc2 = pct_ptr->tcc2; diff --git a/ports/samd/pin_af.h b/ports/samd/pin_af.h index b75f4ddd0256..5bb65a098a65 100644 --- a/ports/samd/pin_af.h +++ b/ports/samd/pin_af.h @@ -30,15 +30,17 @@ #if defined(MCU_SAMD21) -typedef struct { +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; uint8_t pin_id; + char *name; uint8_t eic; uint8_t adc0; uint8_t sercom1; uint8_t sercom2; uint8_t tcc1; uint8_t tcc2; -} pin_af_t; +} machine_pin_obj_t; #define ALT_FCT_TC 4 #define ALT_FCT_TCC1 4 @@ -46,8 +48,10 @@ typedef struct { #elif defined(MCU_SAMD51) -typedef struct { +typedef struct _machine_pin_obj_t { + mp_obj_base_t base; uint8_t pin_id; + char *name; uint8_t eic; uint8_t adc0; uint8_t adc1; @@ -56,7 +60,7 @@ typedef struct { uint8_t tc; uint8_t tcc1; uint8_t tcc2; -} pin_af_t; +} machine_pin_obj_t; #define ALT_FCT_TC 4 #define ALT_FCT_TCC1 5 @@ -85,7 +89,11 @@ typedef struct _pwm_config_t { #define ALT_FCT_SERCOM1 2 #define ALT_FCT_SERCOM2 3 +extern const machine_pin_obj_t pin_af_table[]; + sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom); adc_config_t get_adc_config(int pin_id, int32_t flag); pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t used_dev[]); -const pin_af_t *get_pin_af_info(int pin_id); +const machine_pin_obj_t *get_pin_obj_ptr(int pin_id); +const char *pin_name(int id); +const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type); From 4d38ab652ea57a60c6f2ff085547f72012ac7df6 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 7 Oct 2022 09:40:45 +0200 Subject: [PATCH 1906/4290] samd: Make ADC, DAC, PWM, SPI objects consistent in how they print out. All of ADC, DAC, Pin, PWM and SPI looked different before this change. --- ports/samd/machine_adc.c | 2 +- ports/samd/machine_dac.c | 2 +- ports/samd/machine_pwm.c | 2 +- ports/samd/machine_spi.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c index efe0f041cdfa..8fd3e3bf4e7f 100644 --- a/ports/samd/machine_adc.c +++ b/ports/samd/machine_adc.c @@ -66,7 +66,7 @@ STATIC void adc_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t k (void)kind; machine_adc_obj_t *self = MP_OBJ_TO_PTR(o); - mp_printf(print, "ADC(%s, ADC%u, channel=%u, bits=%u, average=%u)", + mp_printf(print, "ADC(%s, device=%u, channel=%u, bits=%u, average=%u)", pin_name(self->id), self->adc_config.device, self->adc_config.channel, self->bits, 1 << self->avg); } diff --git a/ports/samd/machine_dac.c b/ports/samd/machine_dac.c index 41c6784cceb8..53407c0d375a 100644 --- a/ports/samd/machine_dac.c +++ b/ports/samd/machine_dac.c @@ -126,7 +126,7 @@ STATIC mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ STATIC void dac_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { dac_obj_t *self = self_in; - mp_printf(print, "DAC(%u) PIN_PA%02u", self->id, self->gpio_id); + mp_printf(print, "DAC(%u, Pin=%s)", self->id, pin_name(self->gpio_id)); } STATIC mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) { diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c index 91982a6f74a8..2ae841a9743b 100644 --- a/ports/samd/machine_pwm.c +++ b/ports/samd/machine_pwm.c @@ -107,7 +107,7 @@ STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "PWM %s device=%u channel=%u output=%u", + mp_printf(print, "PWM(%s, device=%u, channel=%u, output=%u)", pin_name(self->pin_id), self->device, self->channel, self->output); } diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c index 8321f19cf0dd..43150f67f15a 100644 --- a/ports/samd/machine_spi.c +++ b/ports/samd/machine_spi.c @@ -82,7 +82,7 @@ void common_spi_irq_handler(int spi_id) { STATIC void machine_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "SPI(%u), baudrate=%u, firstbit=%u, polarity=%u, phase=%u, bits=8", + mp_printf(print, "SPI(%u, baudrate=%u, firstbit=%u, polarity=%u, phase=%u, bits=8)", self->id, self->baudrate, self->firstbit, self->polarity, self->phase); } From a6760bd4efa883ef463795036ff74d678ff65c7b Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 9 Oct 2022 10:56:29 +0200 Subject: [PATCH 1907/4290] samd/modmachine: Replace the LED class by the Signal class. It simplifies and improves the code. The LED_Pxxx lines of the board.csv lines can still be used, but will be taken as Pin definitions. --- ports/samd/Makefile | 1 - ports/samd/boards/make-pin-table.py | 6 +-- ports/samd/machine_led.c | 78 ----------------------------- ports/samd/machine_pin.c | 4 +- ports/samd/modmachine.c | 3 +- ports/samd/modmachine.h | 1 - ports/samd/modsamd.c | 2 +- ports/samd/mpconfigport.h | 1 + ports/samd/pin_af.c | 6 +-- ports/samd/pin_af.h | 2 +- 10 files changed, 11 insertions(+), 93 deletions(-) delete mode 100644 ports/samd/machine_led.c diff --git a/ports/samd/Makefile b/ports/samd/Makefile index f512fb0b2e33..b2e84460ea26 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -88,7 +88,6 @@ SRC_C += \ machine_bitstream.c \ machine_dac.c \ machine_i2c.c \ - machine_led.c \ machine_pin.c \ machine_rtc.c \ machine_spi.c \ diff --git a/ports/samd/boards/make-pin-table.py b/ports/samd/boards/make-pin-table.py index 327478568afa..40bcd166dd08 100644 --- a/ports/samd/boards/make-pin-table.py +++ b/ports/samd/boards/make-pin-table.py @@ -36,11 +36,7 @@ def parse_pin_file(self, filename): # for compatibility, map LED_ to PIN_ if row[0].startswith("LED_"): row[0] = "PIN_" + row[0][4:] - if len(row) == 1: - self.pin_names[row[0]] = (row[0][4:], "{&machine_led_type}") - else: - self.pin_names[row[0]] = (row[1], "{&machine_led_type}") - elif row[0].startswith("PIN_"): + if row[0].startswith("PIN_"): if len(row) == 1: self.pin_names[row[0]] = (row[0][4:], "{&machine_pin_type}") else: diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c deleted file mode 100644 index c18bc052bd2f..000000000000 --- a/ports/samd/machine_led.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016-2021 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Uses pins.h & pins.c to create board (MCU package) specific 'machine_led_obj' array. - */ - -#include "py/runtime.h" -#include "py/mphal.h" -#include "extmod/virtpin.h" -#include "modmachine.h" -#include "pin_af.h" - -extern mp_obj_t machine_pin_low_obj; -extern mp_obj_t machine_pin_high_obj; -extern mp_obj_t machine_pin_toggle_obj; -extern mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); - -STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - machine_pin_obj_t *self = self_in; - mp_printf(print, "LED(\"%s\", GPIO=P%c%02u)", - pin_name(self->pin_id), - "ABCD"[self->pin_id / 32], self->pin_id % 32); -} - -// constructor(id, ...) -mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - - // get the wanted LED object - const machine_pin_obj_t *self; - - self = pin_find(args[0], &machine_led_type); - - mp_hal_pin_output(self->pin_id); - mp_hal_pin_low(self->pin_id); - - return MP_OBJ_FROM_PTR(self); -} - -STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = { - // instance methods - { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) }, - { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_high_obj) }, - { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(machine_led_locals_dict, machine_led_locals_dict_table); - -MP_DEFINE_CONST_OBJ_TYPE( - machine_led_type, - MP_QSTR_LED, - MP_TYPE_FLAG_NONE, - make_new, mp_led_make_new, - print, machine_led_print, - call, machine_pin_call, - locals_dict, &machine_led_locals_dict - ); diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index a7cd86d386ed..87684858325f 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -143,7 +143,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const machine_pin_obj_t *self; // get the wanted pin object - self = pin_find(args[0], &machine_pin_type); + self = pin_find(args[0]); if (n_args > 1 || n_kw > 0) { // pin mode given, so configure this GPIO @@ -499,7 +499,7 @@ STATIC const mp_irq_methods_t machine_pin_irq_methods = { }; mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) { - const machine_pin_obj_t *pin = pin_find(obj, &machine_pin_type); + const machine_pin_obj_t *pin = pin_find(obj); return pin->pin_id; } diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 12e9f7c34134..47fc03d82410 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -29,6 +29,7 @@ #include "extmod/machine_mem.h" #include "extmod/machine_pulse.h" #include "extmod/machine_i2c.h" +#include "extmod/machine_signal.h" #include "extmod/machine_spi.h" #include "drivers/dht/dht.h" #include "modmachine.h" @@ -228,8 +229,8 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index 8f85e149896f..792fca1b9292 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -31,7 +31,6 @@ extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_dac_type; extern const mp_obj_type_t machine_i2c_type; -extern const mp_obj_type_t machine_led_type; extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_spi_type; diff --git a/ports/samd/modsamd.c b/ports/samd/modsamd.c index 79e7b4cc35f1..5a2cf4616d1d 100644 --- a/ports/samd/modsamd.c +++ b/ports/samd/modsamd.c @@ -35,7 +35,7 @@ extern const mp_obj_type_t samd_flash_type; STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) { - const machine_pin_obj_t *pin_af = pin_find(pin_obj, NULL); + const machine_pin_obj_t *pin_af = pin_find(pin_obj); // Get the name, now that it is not in the pin object const char *name = pin_af->name; diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 8b8305f0b47e..f03f8a11d764 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -100,6 +100,7 @@ #define MICROPY_PY_MACHINE_PWM_INIT (0) #define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1) #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/samd/machine_pwm.c" +#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 fc2a0f3d54d9..a7a72ac96abe 100644 --- a/ports/samd/pin_af.c +++ b/ports/samd/pin_af.c @@ -54,10 +54,10 @@ const machine_pin_obj_t *get_pin_obj_ptr(int pin_id) { mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); } -const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type) { +const machine_pin_obj_t *pin_find(mp_obj_t pin) { const machine_pin_obj_t *self = NULL; // Is already a object of the proper type - if (mp_obj_is_type(pin, type)) { + if (mp_obj_is_type(pin, &machine_pin_type)) { return pin; } if (mp_obj_is_small_int(pin)) { @@ -81,7 +81,7 @@ const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type) { } } } - if (self != NULL && (type == NULL || mp_obj_is_type(self, type))) { + if (self != NULL) { return self; } else { mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); diff --git a/ports/samd/pin_af.h b/ports/samd/pin_af.h index 5bb65a098a65..4b0c80250cd5 100644 --- a/ports/samd/pin_af.h +++ b/ports/samd/pin_af.h @@ -96,4 +96,4 @@ adc_config_t get_adc_config(int pin_id, int32_t flag); pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t used_dev[]); const machine_pin_obj_t *get_pin_obj_ptr(int pin_id); const char *pin_name(int id); -const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type); +const machine_pin_obj_t *pin_find(mp_obj_t pin); From ac1e31267b0bf21caa31b8136208c116b1612789 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 8 Oct 2022 21:12:50 +0200 Subject: [PATCH 1908/4290] samd/boards: Rework the pins.csv files. Changes are: - Remove the LED_Pxxx definitions from pins.csv, now that the LED class is gone. - Remove the '-' lines. - Add default lines for USB and SWCLK, SWDIO. --- .../boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv | 11 ++++++++--- .../boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv | 10 ++++++---- .../boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv | 8 +++++--- .../boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv | 9 ++++++--- ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv | 8 +++++++- ports/samd/boards/MINISAM_M4/pins.csv | 9 ++++++++- ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv | 15 +++++++-------- ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv | 11 +++++++++-- ports/samd/boards/SEEED_XIAO/pins.csv | 12 +++++++++--- .../boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv | 15 +++++++++------ 10 files changed, 74 insertions(+), 34 deletions(-) diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv index 0985ee1646d1..45b05c2694f5 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M0_EXPRESS/pins.csv @@ -5,6 +5,9 @@ # Rows for empty entries have to start with '-' # Empty lines and lines starting with # are ignored +PIN_PA27,LED_TX +PIN_PB03,LED_RX + PIN_PA11,D0 PIN_PA10,D1 PIN_PA14,D2 @@ -35,6 +38,8 @@ PIN_PB11,SCK PIN_PA06,NEOPIXEL PIN_PA13,FLASH_CS -LED_PA17,LED -LED_PA27,LED_TX -LED_PB03,LED_RX +PIN_PA24,USB_DM +PIN_PA25,USB_DP + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv index 32daac3d0f4c..ca58a4be79f6 100644 --- a/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_FEATHER_M4_EXPRESS/pins.csv @@ -7,12 +7,9 @@ PIN_PB17,D0 PIN_PB16,D1 -- -- PIN_PA14,D4 PIN_PA16,D5 PIN_PA18,D6 -- PIN_PB03,D8 PIN_PA19,D9 PIN_PA20,D10 @@ -40,4 +37,9 @@ PIN_PA09,FLASH_MISO PIN_PA10,FLASH_WP PIN_PA11,FLASH_HOLD -LED_PA17,LED +PIN_PA24,USB_DM +PIN_PA25,USB_DP +PIN_PA26,USB_SOF + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv index d7d59c23575d..e93e00ab9c94 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M0_EXPRESS/pins.csv @@ -11,9 +11,7 @@ PIN_PA14,D2 PIN_PA09,D3 PIN_PA08,D4 PIN_PA15,D5 -- PIN_PA21,D7 -- PIN_PA07,D9 PIN_PA18,D10 PIN_PA16,D11 @@ -37,4 +35,8 @@ PIN_PB03,FLASH_MISO PIN_PB23,FLASH_SCK PIN_PA27,FLASH_CS -LED_PA17,LED +PIN_PA24,USB_DM +PIN_PA25,USB_DP + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv index ce760a269c24..3dee9bf4c35d 100644 --- a/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv +++ b/ports/samd/boards/ADAFRUIT_ITSYBITSY_M4_EXPRESS/pins.csv @@ -11,9 +11,7 @@ PIN_PA07,D2 PIN_PB22,D3 PIN_PA14,D4 PIN_PA15,D5 -- PIN_PA18,D7 -- PIN_PA19,D9 PIN_PA20,D10 PIN_PA21,D11 @@ -39,4 +37,9 @@ PIN_PA09,FLASH_MISO PIN_PA10,FLASH_WP PIN_PA11,FLASH_HOLD -LED_PA22,LED +PIN_PA24,USB_DM +PIN_PA25,USB_DP +PIN_PA26,USB_SOF + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv index 797b3f70bb92..95f76815f980 100644 --- a/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv +++ b/ports/samd/boards/ADAFRUIT_TRINKET_M0/pins.csv @@ -13,4 +13,10 @@ PIN_PA06,D4 PIN_PA00,DOTSTAR_DATA PIN_PA01,DOTSTAR_CLK -LED_PA10,LED +PIN_PA10,LED + +PIN_PA24,USB_DM +PIN_PA25,USB_DP + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/MINISAM_M4/pins.csv b/ports/samd/boards/MINISAM_M4/pins.csv index cf9a3bd19b21..f6d0ab657fef 100644 --- a/ports/samd/boards/MINISAM_M4/pins.csv +++ b/ports/samd/boards/MINISAM_M4/pins.csv @@ -27,4 +27,11 @@ PIN_PA01,SCK PIN_PB03,DOTSTAR_DATA PIN_PB02,DOTSTAR_CLK -LED_PA15,LED +PIN_PA15,LED + +PIN_PA24,USB_DM +PIN_PA25,USB_DP +PIN_PA26,USB_SOF + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv index 438119d90c1a..bd0757d5647c 100644 --- a/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv +++ b/ports/samd/boards/SAMD21_XPLAINED_PRO/pins.csv @@ -32,8 +32,6 @@ PIN_PB12,EXT2_PIN7 PIN_PB13,EXT2_PIN8 PIN_PB14,EXT2_PIN9 PIN_PB15,EXT2_PIN10 -- -- PIN_PB11,EXT2_PIN13 PIN_PB10,EXT2_PIN14 PIN_PA17,EXT2_PIN15 @@ -44,20 +42,21 @@ PIN_PA19,EXT2_PIN18 # EXT3 PIN_PA02,EXT3_PIN3 PIN_PA03,EXT3_PIN4 -- PIN_PA15,EXT3_PIN6 PIN_PA12,EXT3_PIN7 PIN_PA13,EXT3_PIN8 PIN_PA28,EXT3_PIN9 PIN_PA27,EXT3_PIN10 -- -- -- -- PIN_PB17,EXT3_PIN15 PIN_PB22,EXT3_PIN16 PIN_PB16,EXT3_PIN17 PIN_PB23,EXT3_PIN18 -LED_PB30,LED +PIN_PB30,LED + +PIN_PA24,USB_DM +PIN_PA25,USB_DP + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv index 9bc57070d198..4a3d9e21aee0 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv @@ -60,5 +60,12 @@ PIN_PC13,LCD_YD PIN_PC30,MIC PIN_PD11,BUZZER -LED_PA15,LED_BLUE -LED_PC05,LED_LCD +PIN_PA15,LED_BLUE +PIN_PC05,LED_LCD + +PIN_PA24,USB_DM +PIN_PA25,USB_DP +PIN_PA26,USB_SOF + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/SEEED_XIAO/pins.csv b/ports/samd/boards/SEEED_XIAO/pins.csv index 8a70a7714563..a06d3ac6ac60 100644 --- a/ports/samd/boards/SEEED_XIAO/pins.csv +++ b/ports/samd/boards/SEEED_XIAO/pins.csv @@ -17,6 +17,12 @@ PIN_PA07,A8_D8 PIN_PA05,A9_D9 PIN_PA06,A10_D10 -LED_PA17,USER_LED -LED_PA18,RX_LED -LED_PA19,TX_LED +PIN_PA17,USER_LED +PIN_PA18,RX_LED +PIN_PA19,TX_LED + +PIN_PA24,USB_DM +PIN_PA25,USB_DP + +PIN_PA30,SWCLK +PIN_PA31,SWDIO diff --git a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv index b60fb909714e..dfd6641333fa 100644 --- a/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv +++ b/ports/samd/boards/SPARKFUN_SAMD51_THING_PLUS/pins.csv @@ -13,7 +13,6 @@ PIN_PA06,D4 PIN_PA15,D5 PIN_PA20,D6 PIN_PA21,D7 -- PIN_PA07,D9 PIN_PA18,D10 PIN_PA16,D11 @@ -34,9 +33,13 @@ PIN_PA08,FLASH_MOSI PIN_PA09,FLASH_SCK PIN_PA10,FLASH_CS PIN_PA11,FLASH_MISO -PIN_PA30,SWDCLK -PIN_PA31,SWDIO -LED_PA17,LED -LED_PB03,RXLED -LED_PA27,TXLED +PIN_PB03,RXLED +PIN_PA27,TXLED + +PIN_PA24,USB_DM +PIN_PA25,USB_DP +PIN_PA26,USB_SOF + +PIN_PA30,SWCLK +PIN_PA31,SWDIO From 474233c250536612a5245231aff1ef3ad74ccf20 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 11 Oct 2022 10:05:01 +0200 Subject: [PATCH 1909/4290] samd/machine_pwm: Serialize fast update of PWM settings. Any update of freq or duty_cycle requires the previous PWM cycle to be finished. Otherwise the new settings are not accepted. Other changes in this commit: - Report the set duty cycles even when the PWM is not yet started. - pwm.freq(0) stops the pwm device, instead of raising an expception. - Clear the duty cycle value cache on soft reset. --- ports/samd/machine_pwm.c | 51 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c index 2ae841a9743b..f6b417631e1d 100644 --- a/ports/samd/machine_pwm.c +++ b/ports/samd/machine_pwm.c @@ -25,6 +25,7 @@ * THE SOFTWARE. */ +#include #include "py/runtime.h" #include "py/mphal.h" #include "modmachine.h" @@ -46,6 +47,8 @@ typedef struct _machine_pwm_obj_t { uint8_t output; uint16_t prescaler; uint32_t period; // full period count ticks + uint32_t duty_ns; // just for reporting + uint16_t duty_u16; // just for reporting } machine_pwm_obj_t; #define PWM_NOT_INIT (0) @@ -53,6 +56,7 @@ typedef struct _machine_pwm_obj_t { #define PWM_TCC_ENABLED (2) #define PWM_MASTER_CLK (get_peripheral_freq()) #define PWM_FULL_SCALE (65536) +#define PWM_UPDATE_TIMEOUT (2000) static Tcc *tcc_instance[] = TCC_INSTS; @@ -148,6 +152,7 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args self->output = config.device_channel & 0x0f; self->prescaler = 1; self->period = 1; // Use an invalid but safe value + self->duty_u16 = self->duty_ns = 0; put_duty_value(self->device, self->channel, 0); Tcc *tcc = self->instance; @@ -240,6 +245,7 @@ void pwm_deinit_all(void) { device_status[i] = PWM_NOT_INIT; duty_type_flags[i] = 0; output_active[i] = 0; + memset(pwm_duty_values, 0, sizeof(pwm_duty_values)); } } @@ -256,8 +262,25 @@ STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { } } +STATIC void wait_for_register_update(Tcc *tcc) { + // Wait for a period's end (may be long) to have the change settled + // Each loop cycle takes at least 1 ms, giving an implicit timeout. + for (int i = 0; i < PWM_UPDATE_TIMEOUT; i++) { + if (tcc->INTFLAG.reg & TCC_INTFLAG_OVF) { + break; + } + MICROPY_EVENT_POLL_HOOK + } + // Clear the flag, telling that a cycle has been handled. + tcc->INTFLAG.reg = TCC_INTFLAG_OVF; +} + STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { - return MP_OBJ_NEW_SMALL_INT(PWM_MASTER_CLK / self->prescaler / self->period); + if (self->instance->CTRLA.reg & TCC_CTRLA_ENABLE) { + return MP_OBJ_NEW_SMALL_INT(PWM_MASTER_CLK / self->prescaler / self->period); + } else { + return MP_OBJ_NEW_SMALL_INT(0); + } } STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { @@ -267,7 +290,8 @@ STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { Tcc *tcc = self->instance; if (freq < 1) { - mp_raise_ValueError(MP_ERROR_TEXT("invalid freq")); + pwm_stop_device(self->device); + return; } // Get the actual settings of prescaler & period from the unit @@ -288,6 +312,11 @@ STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { if (period < 2) { mp_raise_ValueError(MP_ERROR_TEXT("freq too large")); } + // If the PWM is running, ensure that a cycle has passed since the + // previous setting before setting a new frequency/duty value + if (tcc->CTRLA.reg & TCC_CTRLA_ENABLE) { + wait_for_register_update(tcc); + } // Check, if the prescaler has to be changed and stop the device if so. if (index != tcc->CTRLA.bit.PRESCALER) { // stop the device @@ -339,25 +368,37 @@ STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { } STATIC mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) { - return MP_OBJ_NEW_SMALL_INT(self->instance->CC[self->channel].reg * PWM_FULL_SCALE / (self->instance->PER.reg + 1)); + return MP_OBJ_NEW_SMALL_INT(self->duty_u16); } STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16) { + // Remember the values for update & reporting put_duty_value(self->device, self->channel, duty_u16); + self->duty_u16 = duty_u16; + self->duty_ns = 0; // If the device is enabled, than the period is set and we get a reasonable value for // the duty cycle, set to the CCBUF register. Otherwise, PWM does not start. if (self->instance->CTRLA.reg & TCC_CTRLA_ENABLE) { - self->instance->CCBUF[self->channel].reg = (uint64_t)duty_u16 * (self->instance->PER.reg + 1) / PWM_FULL_SCALE; + // Ensure that a cycle has passed updating the registers + // since the previous setting before setting a new duty value + wait_for_register_update(self->instance); + self->instance->CCBUF[self->channel].reg = (uint64_t)duty_u16 * (self->period) / PWM_FULL_SCALE; } duty_type_flags[self->device] |= 1 << self->channel; } STATIC mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) { - return MP_OBJ_NEW_SMALL_INT(1000000000ULL * self->instance->CC[self->channel].reg * self->prescaler / PWM_MASTER_CLK); + return MP_OBJ_NEW_SMALL_INT(self->duty_ns); } STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) { + // Remember the values for update & reporting put_duty_value(self->device, self->channel, duty_ns); + self->duty_ns = duty_ns; + self->duty_u16 = 0; + // Ensure that a cycle has passed updating the registers + // since the previous setting before setting a new duty value + wait_for_register_update(self->instance); self->instance->CCBUF[self->channel].reg = (uint64_t)duty_ns * PWM_MASTER_CLK / self->prescaler / 1000000000ULL; duty_type_flags[self->device] &= ~(1 << self->channel); } From 9c2bc379f183ff9f3280842eb236e8f4b8635835 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 8 Oct 2022 12:32:55 +0200 Subject: [PATCH 1910/4290] samd/machine_uart: Use a finaliser to tidy up UART on soft reset. And use the common sercom_table, saving a few bytes of RAM. --- ports/samd/machine_uart.c | 22 ++++++++-------------- ports/samd/main.c | 2 -- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index 76b564e874a6..2526b450931b 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -59,7 +59,7 @@ typedef struct _machine_uart_obj_t { } machine_uart_obj_t; Sercom *sercom_instance[] = SERCOM_INSTS; -machine_uart_obj_t *uart_table[SERCOM_INST_NUM] = {}; +extern void *sercom_table[SERCOM_INST_NUM]; STATIC const char *_parity_name[] = {"None", "", "0", "1"}; // Is defined as 0, 2, 3 @@ -82,7 +82,7 @@ STATIC void uart_drain_rx_fifo(machine_uart_obj_t *self, Sercom *uart) { } void common_uart_irq_handler(int uart_id) { - machine_uart_obj_t *self = uart_table[uart_id]; + machine_uart_obj_t *self = sercom_table[uart_id]; // Handle IRQ if (self != NULL) { Sercom *uart = sercom_instance[self->id]; @@ -322,7 +322,8 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, } // Create the UART object and fill it with defaults. - machine_uart_obj_t *self = mp_obj_malloc(machine_uart_obj_t, &machine_uart_type); + machine_uart_obj_t *self = m_new_obj_with_finaliser(machine_uart_obj_t); + self->base.type = &machine_uart_type; self->id = uart_id; self->baudrate = DEFAULT_UART_BAUDRATE; self->bits = 8; @@ -332,7 +333,7 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, self->tx = 0xff; self->rx = 0xff; self->new = true; - uart_table[uart_id] = self; + sercom_table[uart_id] = self; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); @@ -348,10 +349,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init); STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); Sercom *uart = sercom_instance[self->id]; - // clear table entry of uart - uart_table[self->id] = NULL; // Disable interrupts uart->USART.INTENCLR.reg = 0xff; + // clear table entry of uart + sercom_table[self->id] = NULL; MP_STATE_PORT(samd_uart_rx_buffer[self->id]) = NULL; #if MICROPY_HW_UART_TXBUF MP_STATE_PORT(samd_uart_tx_buffer[self->id]) = NULL; @@ -409,14 +410,6 @@ STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone); -void uart_deinit_all(void) { - for (int i = 0; i < SERCOM_INST_NUM; i++) { - if (uart_table[i] != NULL) { - machine_uart_deinit((mp_obj_t)uart_table[i]); - } - } -} - STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) }, @@ -430,6 +423,7 @@ STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&machine_uart_deinit_obj) }, }; STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table); diff --git a/ports/samd/main.c b/ports/samd/main.c index 0f24e2382ee8..725fd651d02c 100644 --- a/ports/samd/main.c +++ b/ports/samd/main.c @@ -39,7 +39,6 @@ extern void adc_deinit_all(void); extern void pin_irq_deinit_all(void); extern void pwm_deinit_all(void); extern void sercom_deinit_all(void); -extern void uart_deinit_all(void); void samd_main(void) { mp_stack_set_top(&_estack); @@ -86,7 +85,6 @@ void samd_main(void) { pin_irq_deinit_all(); pwm_deinit_all(); sercom_deinit_all(); - uart_deinit_all(); soft_timer_deinit(); gc_sweep_all(); mp_deinit(); From d74215a3137da5e9001aed92c8c1b06d828ff9d2 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 8 Oct 2022 12:34:45 +0200 Subject: [PATCH 1911/4290] samd/machine_spi: Implement spi.deinit() and simplify sercom_deinit_all. The sercom_deinit_all() function does not need the object pointers. --- ports/samd/machine_spi.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c index 43150f67f15a..d4c7a05bb60f 100644 --- a/ports/samd/machine_spi.c +++ b/ports/samd/machine_spi.c @@ -254,17 +254,23 @@ STATIC mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, s return self; } +STATIC void machine_sercom_deinit(mp_obj_base_t *self_in) { + machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + Sercom *spi = sercom_instance[self->id]; + // Disable interrupts (if any) + spi->SPI.INTENCLR.reg = 0xff; + sercom_enable(spi, 0); + // clear table entry of spi + sercom_table[self->id] = NULL; +} + void sercom_deinit_all(void) { for (int i = 0; i < SERCOM_INST_NUM; i++) { - if (sercom_table[i] != NULL) { - machine_spi_obj_t *self = sercom_table[i]; - Sercom *spi = sercom_instance[self->id]; - // Disable interrupts (if any) - spi->SPI.INTENCLR.reg = 0xff; - // clear table entry of spi - sercom_table[i] = NULL; - sercom_enable(spi, 0); - } + Sercom *spi = sercom_instance[i]; + spi->SPI.INTENCLR.reg = 0xff; + sercom_register_irq(i, NULL); + sercom_enable(spi, 0); + sercom_table[i] = NULL; } } @@ -316,6 +322,7 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8 STATIC const mp_machine_spi_p_t machine_spi_p = { .init = machine_spi_init, + .deinit = machine_sercom_deinit, .transfer = machine_spi_transfer, }; From a1eebc507eda8f5ec052d0ef0450c52f2320e106 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 13 Oct 2022 19:04:37 +0200 Subject: [PATCH 1912/4290] samd/machine_spi: Register SerCom objects as root pointers. Protect SerCom (UART, SPI, I2C) objects from getting freed by the GC when they go out of scope without being deinitialized. Otherwise the ISR of a Sercom may access an invalid data structure. --- ports/samd/machine_i2c.c | 5 ++--- ports/samd/machine_spi.c | 10 +++++----- ports/samd/machine_uart.c | 7 +++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c index 0a8f5b94db08..d943b6b2f422 100644 --- a/ports/samd/machine_i2c.c +++ b/ports/samd/machine_i2c.c @@ -69,7 +69,6 @@ typedef struct _machine_i2c_obj_t { } machine_i2c_obj_t; extern Sercom *sercom_instance[]; -extern void *sercom_table[SERCOM_INST_NUM]; STATIC void i2c_send_command(Sercom *i2c, uint8_t command) { i2c->I2CM.CTRLB.bit.CMD = command; @@ -79,7 +78,7 @@ STATIC void i2c_send_command(Sercom *i2c, uint8_t command) { void common_i2c_irq_handler(int i2c_id) { // handle Sercom I2C IRQ - machine_i2c_obj_t *self = sercom_table[i2c_id]; + machine_i2c_obj_t *self = MP_STATE_PORT(sercom_table[i2c_id]); // Handle IRQ if (self != NULL) { Sercom *i2c = self->instance; @@ -159,7 +158,7 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n if (sda_pad_config.pad_nr != 0 || scl_pad_config.pad_nr != 1) { mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for sda or scl")); } - sercom_table[self->id] = self; + MP_STATE_PORT(sercom_table[self->id]) = self; self->freq = args[ARG_freq].u_int; // Configure the Pin mux. diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c index d4c7a05bb60f..4ffc7095cc2e 100644 --- a/ports/samd/machine_spi.c +++ b/ports/samd/machine_spi.c @@ -57,11 +57,11 @@ typedef struct _machine_spi_obj_t { } machine_spi_obj_t; extern Sercom *sercom_instance[]; -void *sercom_table[SERCOM_INST_NUM] = {}; +MP_REGISTER_ROOT_POINTER(void *sercom_table[SERCOM_INST_NUM]); void common_spi_irq_handler(int spi_id) { // handle Sercom IRQ RXC - machine_spi_obj_t *self = sercom_table[spi_id]; + machine_spi_obj_t *self = MP_STATE_PORT(sercom_table[spi_id]); // Handle IRQ if (self != NULL) { Sercom *spi = sercom_instance[self->id]; @@ -246,7 +246,7 @@ STATIC mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, s self->sck = 0xff; self->new = true; - sercom_table[spi_id] = self; + MP_STATE_PORT(sercom_table[spi_id]) = self; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); @@ -261,7 +261,7 @@ STATIC void machine_sercom_deinit(mp_obj_base_t *self_in) { spi->SPI.INTENCLR.reg = 0xff; sercom_enable(spi, 0); // clear table entry of spi - sercom_table[self->id] = NULL; + MP_STATE_PORT(sercom_table[self->id]) = NULL; } void sercom_deinit_all(void) { @@ -270,7 +270,7 @@ void sercom_deinit_all(void) { spi->SPI.INTENCLR.reg = 0xff; sercom_register_irq(i, NULL); sercom_enable(spi, 0); - sercom_table[i] = NULL; + MP_STATE_PORT(sercom_table[i]) = NULL; } } diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c index 2526b450931b..4b8fa3b60d8f 100644 --- a/ports/samd/machine_uart.c +++ b/ports/samd/machine_uart.c @@ -59,7 +59,6 @@ typedef struct _machine_uart_obj_t { } machine_uart_obj_t; Sercom *sercom_instance[] = SERCOM_INSTS; -extern void *sercom_table[SERCOM_INST_NUM]; STATIC const char *_parity_name[] = {"None", "", "0", "1"}; // Is defined as 0, 2, 3 @@ -82,7 +81,7 @@ STATIC void uart_drain_rx_fifo(machine_uart_obj_t *self, Sercom *uart) { } void common_uart_irq_handler(int uart_id) { - machine_uart_obj_t *self = sercom_table[uart_id]; + machine_uart_obj_t *self = MP_STATE_PORT(sercom_table[uart_id]); // Handle IRQ if (self != NULL) { Sercom *uart = sercom_instance[self->id]; @@ -333,7 +332,7 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, self->tx = 0xff; self->rx = 0xff; self->new = true; - sercom_table[uart_id] = self; + MP_STATE_PORT(sercom_table[uart_id]) = self; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); @@ -352,7 +351,7 @@ STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) { // Disable interrupts uart->USART.INTENCLR.reg = 0xff; // clear table entry of uart - sercom_table[self->id] = NULL; + MP_STATE_PORT(sercom_table[self->id]) = NULL; MP_STATE_PORT(samd_uart_rx_buffer[self->id]) = NULL; #if MICROPY_HW_UART_TXBUF MP_STATE_PORT(samd_uart_tx_buffer[self->id]) = NULL; From fcccfc176b225001b402ce2ced062344990789e0 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 17 Oct 2022 18:05:28 +0200 Subject: [PATCH 1913/4290] samd/modmachine: Add machine.softreset(). For consistency with other ports. --- ports/samd/modmachine.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 47fc03d82410..8adc06f52654 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -32,6 +32,7 @@ #include "extmod/machine_signal.h" #include "extmod/machine_spi.h" #include "drivers/dht/dht.h" +#include "shared/runtime/pyexec.h" #include "modmachine.h" #include "samd_soc.h" @@ -57,6 +58,12 @@ extern bool EIC_occured; extern uint32_t _dbl_tap_addr; +STATIC mp_obj_t machine_soft_reset(void) { + pyexec_system_exit = PYEXEC_FORCED_EXIT; + mp_raise_type(&mp_type_SystemExit); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_soft_reset_obj, machine_soft_reset); + STATIC mp_obj_t machine_reset(void) { *DBL_TAP_ADDR = DBL_TAP_MAGIC_RESET; #ifdef DBL_TAP_ADDR_ALT @@ -219,6 +226,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lightsleep_obj, 0, 1, machine STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, + { MP_ROM_QSTR(MP_QSTR_soft_reset), MP_ROM_PTR(&machine_soft_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_bootloader), MP_ROM_PTR(&machine_bootloader_obj) }, { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) }, From d75c7e822cbfe7014fede1420f996a0af04bb13c Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Wed, 21 Sep 2022 09:57:10 +1000 Subject: [PATCH 1914/4290] py/obj: Add comments explaining the slot index scheme. Signed-off-by: Jim Mussared --- py/obj.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/py/obj.h b/py/obj.h index 8d62dd4f3cf0..b5b855bad395 100644 --- a/py/obj.h +++ b/py/obj.h @@ -753,10 +753,16 @@ typedef struct _mp_obj_full_type_t { #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, } } #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slot_index_##f12 = 12, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, } } +// Because the mp_obj_type_t instances are in (zero-initialised) ROM, we take +// slot_index_foo=0 to mean that the slot is unset. This also simplifies checking +// if the slot is set. That means that we need to store index+1 in slot_index_foo +// though and then access it as slots[slot_index_foo - 1]. This is an implementation +// detail, the user of these macros doesn't need to be aware of it, and when using +// MP_OBJ_TYPE_OFFSETOF_SLOT you should use zero-based indexing. #define MP_OBJ_TYPE_HAS_SLOT(t, f) ((t)->slot_index_##f) #define MP_OBJ_TYPE_GET_SLOT(t, f) (_MP_OBJ_TYPE_SLOT_TYPE_##f(t)->slots[(t)->slot_index_##f - 1]) #define MP_OBJ_TYPE_GET_SLOT_OR_NULL(t, f) (_MP_OBJ_TYPE_SLOT_TYPE_##f(MP_OBJ_TYPE_HAS_SLOT(t, f) ? MP_OBJ_TYPE_GET_SLOT(t, f) : NULL)) -#define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->slot_index_##f = (n) + 1, (t)->slots[(t)->slot_index_##f - 1] = (void *)v) +#define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->slot_index_##f = (n) + 1, (t)->slots[(n)] = (void *)v) #define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, slot_index_##f)) #define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(uint8_t *)((char *)(t) + (offset)) != 0) From 64af916c111b61bce82c00f356a6b1cb81946d87 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 18 Oct 2022 16:24:33 +1100 Subject: [PATCH 1915/4290] docs/templates/layout.html: Indicate latest vs release docs. When looking at latest (the default for docs.micropython.org), make it clear that this isn't the release version. - Changes the version in the top-left to "latest". - Adds a message to the top of each page to explain. For future release versions, add a short message to link to the latest version. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared --- docs/conf.py | 3 ++- docs/templates/layout.html | 25 +++++++++++++++++++++++++ docs/templates/topindex.html | 3 +-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 5533bf01918a..ce5c037568ad 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -33,6 +33,7 @@ 'downloads':[ ('PDF', url_pattern % micropy_version + '/micropython-docs.pdf'), ], + 'is_release': micropy_version != 'latest', } @@ -74,7 +75,7 @@ # # We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags" # breakdown, so use the same version identifier for both to avoid confusion. -version = release = '1.19.1' +version = release = micropy_version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/templates/layout.html b/docs/templates/layout.html index a6caa0bc5a11..8563f02af00a 100644 --- a/docs/templates/layout.html +++ b/docs/templates/layout.html @@ -4,3 +4,28 @@ {# we change the master_doc variable so that links to the index page are to index.html instead of _index.html #} {% set master_doc = "index" %} + +{% block document %} + {% if is_release %} +
+

+ This is the v{{ release }} version of the MicroPython + documentation. The latest + development version of this page may be more current. +

+
+ {% else %} +
+

+ This is the documentation for the latest development branch of + MicroPython and may refer to features that are not available in released + versions. +

+

+ If you are looking for the documentation for a specific release, use + the drop-down menu on the left and select the desired version. +

+
+ {% endif %} + {{ super() }} +{% endblock %} diff --git a/docs/templates/topindex.html b/docs/templates/topindex.html index cfe3ad1516ac..4e163b6efe90 100644 --- a/docs/templates/topindex.html +++ b/docs/templates/topindex.html @@ -5,8 +5,7 @@

MicroPython documentation

- {{ _('Welcome! This is the documentation for MicroPython') }} - v{{ release|e }}{% if last_updated %}, {{ _('last updated') }} {{ last_updated|e }}{% endif %}. + {{ _('Welcome! This is the documentation for MicroPython') }}{% if last_updated %}, {{ _('last updated') }} {{ last_updated|e }}{% endif %}.

From 11910e2fa1c8f5dc76cbc90598ff81526d1f6312 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 20 Jun 2022 14:02:30 +0200 Subject: [PATCH 1916/4290] docs/samd: Add documentation for the samd port. Includes a general overview, a quickref, pinout tables, and the beginnings of a tutorial. --- docs/index.rst | 1 + docs/samd/general.rst | 88 +++ docs/samd/img/itsybitsy_m4_express.jpg | Bin 0 -> 151296 bytes docs/samd/pinout.rst | 850 +++++++++++++++++++++++++ docs/samd/quickref.rst | 469 ++++++++++++++ docs/samd/tutorial/intro.rst | 84 +++ docs/templates/topindex.html | 4 + 7 files changed, 1496 insertions(+) create mode 100644 docs/samd/general.rst create mode 100644 docs/samd/img/itsybitsy_m4_express.jpg create mode 100644 docs/samd/pinout.rst create mode 100644 docs/samd/quickref.rst create mode 100644 docs/samd/tutorial/intro.rst diff --git a/docs/index.rst b/docs/index.rst index 9a021b3906d4..64b83618da14 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,3 +17,4 @@ MicroPython documentation and references unix/quickref.rst zephyr/quickref.rst renesas-ra/quickref.rst + samd/quickref.rst diff --git a/docs/samd/general.rst b/docs/samd/general.rst new file mode 100644 index 000000000000..66e6d2a31f69 --- /dev/null +++ b/docs/samd/general.rst @@ -0,0 +1,88 @@ +.. _samd_general: + +General information about the SAMD port +======================================= + +The SAMD21/SAMD51 MCU family is a high performance family of devices made by MicroChip. +The SAMD21 devices are based on an ARM M0+ core, the SAMD51 device on ARM Cortex M4 core. +They provide many on-chip I/O units for building small to medium sized devices. + +Multitude of boards +------------------- + +There is a multitude of modules and boards from different sources which carry +an SAMD21/SAMD51 chip. MicroPython aims to provide a generic port which runs on +as many boards/modules as possible, but there may be limitations. The +Adafruit ItsyBitsy M0 Express, Adafruit Feather M4 Express and the Adafruit ItsyBitsy M4 Express +development boards are taken as reference for the port (for example, testing is performed on them). +For any board you are using please make sure you have a data sheet, schematics +and other reference materials so you can look up any board-specific functions. + +The following boards are at the moment supported by the port: + +- ADAFRUIT FEATHER M0 EXPRESS +- ADAFRUIT FEATHER M4 EXPRESS +- ADAFRUIT ITSYBITSY M0 EXPRESS +- ADAFRUIT ITSYBITSY M4 EXPRESS +- ADAFRUIT TRINKET M0 +- MINISAM M4 +- SAMD21 XPLAINED PRO +- SEEED WIO TERMINAL +- SEEED XIAO + +To make a generic SAMD port and support as many boards as possible the +following design and implementation decision were made: + +* GPIO pin numbering is based on the board numbering. + Please have the manual/pin diagram of your board at hand + to find correspondence between your board pins and actual SAMD21/SAMD51 pins. + For the boards listed above, the relation between the board pin number and + the GPIO number can be found at :ref:`samd_pinout`. +* The pins that can be used by MicroPython are limited to those listed + in the board definition files. + +Technical specifications and SoC data sheets +-------------------------------------------- + +The data sheets and other reference material for SAMD21/SAMD51 chip are available +from the vendor site: https://www.microchip.com/en-us/products/microcontrollers-and-microprocessors/32-bit-mcus/sam-32-bit-mcus +They are the primary reference for the chip technical specifications, capabilities, +operating modes, internal functioning, etc. + +For your convenience, a few technical specifications are provided below: + +SAMD21: + +* Architecture: ARM Cortex M0+ +* CPU frequency: up to 48MHz +* Total RAM available: up to 32 kB (see table) +* Internal FlashROM: up to 256 kB + Some boards provide additional external SPI flash. +* GPIO: up to 52 (GPIOs are multiplexed with other functions, including + external FlashROM, UART, etc.) +* UART: up to 6 serial devices, which can used for UART, SPI or I2C. +* I2S: 1 I2S interfaces +* ADC: One 12-bit SAR ADC converter with 16 channels. +* Programming: using BootROM bootloader from USB. + +SAMD51: + +* Architecture: ARM Cortex M4 +* CPU frequency: up to 120MHz +* Total RAM available: up to 256 kB +* Internal FlashROM: up to 1 MB + Some boards provide additional external SPI flash. +* GPIO: up to 99 (GPIOs are multiplexed with other functions, including + external FlashROM, UART, etc.) +* UART: up to 8 serial devices, which can used for UART, SPI or I2C. +* I2S: 1 I2S interfaces +* ADC: Dual 12-bit SAR ADC converter with 16 channels. +* Programming: using BootROM bootloader from USB. + + +For more information see the excellent SAMD21/SAMD51 data sheets or reference manuals. + +At the moment, the SAM21 port of MicroPython requires 256kB flash, of which 64kB is used +for a small file system. The SAM51 port requires 512 kB of flash, of which all flash beyond +384kB is used for a file system. Some boards have additional flash memory, which can be used +as additional file space. diff --git a/docs/samd/img/itsybitsy_m4_express.jpg b/docs/samd/img/itsybitsy_m4_express.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ea18b5c3899dee9a6668451c794d3d50ad0fa390 GIT binary patch literal 151296 zcmd42WmFtNxA!}^6WrY$26uO7a0@cHI{^Yg0>Rye06_;B+$FeMNC+;0;2wfITyoBH z*FEoD_rra^y){!a|LLl|yJ~l@Ro(m7^RoEz8-Sy#sGju34=zncw|Ix~?n*4ugmjCEi zQvfdW!JN>od!~eI>f3}XF5dX`6`K!Kut@e5jzOL3Zd|W^v7cYR9hnH8BM^KcP zhXx1~<>wIv0s+VXKr#vd@wM-3BM>g-zcm~@0sv6(pY1>%9=L-4XCLtY(f{Uv@E`qe z4*v==009o+zee!t_y5;S;Nbsz#PY8m;Qyly$^Xk4;N|}-!Ycr|*U|F0k- zAiyIaAtE6mAtE9oA)_E8A)z26A|j(9qoDpPNXTgDXsGD_e!RRo`RC!E)$1Ge)#|^x z{BM1{^a5~E0hWMJ1UNbXJT4ppF5Jr?fa+fq5dNJI|93%n9SkZO96Sm-;I&;G2LKO; z0RK8f1Y{({*C+#CV~vP}i;M!mqXnYk%jgi$S%vX>{zW4sqE9K5m8Z<&nH{hH~p7@ ze&b~sfQj&59dH3s0BH2jyzp(GvG?B3_$jk*+y-hbCL-8Xb}wS=&bQp+M|QV$_W7QI z+xRB3=OU;ISl+fv>0f=fx*Q3Kh`*Dx5P=&78Hxb>_Ys1>gJ)2}>H12_`!8Bqh2aeU zT5kIY9~_Mmkl?~u|*B9+?obHsqU0EpCChkRcw3J`iI-R(N1 z+^M5o^)*^oxLfawy?i}OQ>)9XJy0Afwn!Zr{VY=o#0!WlF}%tra5`~4wHVU__LcqP zvi>H0*;l4S*%^MU_!ncJkl6kJ!xn@hSn7=kjbt; zOlbdD#os7t(Y1k*+%@j;m!y&PQ+$gU%g6D@=)Z2CG090&*zc06Z60omE!u7U3|CMp zq~=P=UpJ!VlPW3-`N_sMAcCVLrUZIloKE{A_o`kU`g?%{a_{Cv1zYwp`>p1q6F_ea zkDM=U90FdaNi0TKC_h*!D?=_WyFeF8Cr^n%3ci@`>Jp7O?aNm*iK*BP`(0C-qs$D= z6ihUtR547LPUjW2gag4*w9)qLn zn%)ozFD-2piyz;Sf1(x-q^AN?NvM;-5&>Gb9f9%wQnrkd%Gzg2Gzdsp6^|Du3!$0B zT&dYMX&5u8n&b#G>r|iClXURX@{!)Yv$Nig?^dS&+$Nb9`rz3xLYB!nIbMhsc+O6w8>0~9$gh7{n0&gTGS$U*Z^B3AE3RL0^qVkv)L!)wo z-ref2P*U_@nM;HkF`J9VJl3oDP%o_fIuph)W*kBWQ3NP^tj~mXgy5b zDqmiq!U)}_CWu?J?fPWlP?#96J z2$P!u?qFHIA_)olWcOYt^R3ttHPUB&qJ|Y0^bn$e^@FBw5*~V>3THvD;Qu7Y;`H^+@yazwUz5sAd2CR;W#GZHDTZ(>~ z1nG?#>jYO6s!r(BWvhY~%$+icFPt&Hv4m|KZImi+@yN%o*?0yad=yp&fhUx`)p4Lv zFMwOKm4nhwkn8;R@o99|_MC5H&sjp$9m4|S>}Chs=LFY_vC2TFAfwU>mby}Ak#ukR za!{_}bLWqSeMf$gqB)|x4`o-BDYY$uIc%ci#?X?4HIco{a2Uy6EMaDTg@KaJR5HW^ zCiDAC=t=3XJfYY5dLG;eJW4qlowTCIF>N+O11nwcTaXk#X%07SjkX!gDgPjZs!&NP zBsXFH#^z$W*iiH8lyKGioafr;)^c|`az>T+3AFCo5wB+|fHfTWDb%>~@GVm&Y*~_y z#6CQC6Do~%`%cH~ob8j<=y9I7E*3K%DZ+UuvJROO(V?ZjBNr7(+mC<*712qUzQSmH z32c8KmF+0%ih*izME&Zdx00L=(Cx&E0I&-3V_xYg+Zjw=<;-zKbFZBdZ961CjX{5i ztm*jf-fDJ|QCS7*CeDGXss(ezUuNFR;j_)Fe1zduC11$HZDl)uLx2gMYBOcc8$j#V z7(zAF9tYnY6g_*U4xt(@(}@Hr+TTNS0MUxSw+qr4!)X=QYMT`4+m#l=3j^h!W~M-`VN7LPy33J~sAdt~=s z#p#=Vl>q08eQC3U$nnDEjES=u=wOs-1)WojZo1hO$;G1)eYtnY;c>APr&7L(4aDV0 zd0Ob3K(y&Tb$|PLjdOn{NNPiN`HCC+hp~$n|H``FBxB-*A{Pc`v$lW>+V*fLGvqsF zN%0uNC4OmZ_d*4isHt1!2~l3gY_s<4fzxMiIW2x-HNs%oG0#@V&%bo2;n_Y(IvjdD zPK~DVe#PdX?bJ*Fm-!%%9=YEK+05i9=}h-|%=+hug|G74@R`%cPRrR>er=q4KF<_} z#wsLB&b%AHNV~Zu2V+SvoJSd?itDHM^>4tK0V=;sj{qMR_+H&Rj|>tGl&VHsuCNh z-rrbhyEZg3--H&FEHoU<*T2`0tSk7)5Xb2XD|o|Jv1PQSy0L?VlCkCSS8uB@j%Blm2LUmMobP_dpL||ps7o1 zkm=za`0qi90AWblOpZZikZt|)ak1uHpRNW$W(S+7UZh(~n}G98mYl3meCL##fzThE3rxRH~I76B6ex;I|KLI{iap~M~qy2*X?Z@556TV zcHyf9&OXF62li;bt*E|tYpB@}@F*>8*ZabSdSD67EZed=*N|_dkBSwSwe*9{o2(D` zMXhNRuc&cVYecRMmv$NnVDEm3t7xP$npa_A;!sW~xW&8DLRYWY*%8^28;olCGhDl* z(LOIWvW2&wMgFI4`udj$wB>CoEby!AT6iW@<-oaex4g2PP=_T|G_odFeKNx(w)2Q= zz=-&pX@wBksakET$qPWY(k&`hG{_gTSyhrOhVY}+=f|9PQ{+(dB}jIb9cOnYS{3ZD zApbf?bIbIoXzEypKayp_Jb-dbfqg2s>)qS()r94>Uy_7(8&vtLe`=^=~L;4lZ1fe_^ zI8_9vA~LMcP&di|k78o-_`|C}$!F*PGMOoAI-&EtktLujc&%cq4yM;DZ6O+Y&w4|p* zg3d^giX8biAI~W1a7cIe3*fXjMfNuY{MIT|Wrta!=jP^jOqt(IOP-RPxkHa>IXBUr zUgdze)8Q6<;i!bD{d)W5#!z7^xwoL7Xkeh|iA62HzNnIx>ZLz~rI|B4PqjTNYO@9k z%i5-XWJ}fi?Imu5(AN@n_c8L5OB%D>KFa0elZ5b_jXX8p04NOts|1Nqw`gL|$;d}d z2lTcN7$I!@iC^af8-skYkJeg|A2YMdU0YP;%UVorssp3&f6mMPsCLaS>7$eR3)0}E z_^Ys^y9Lbtyi(l&_7Y5TJkb~9^H_RXpBHMcC8pGNnB3!l%Q{WNqcXV)i}D4LMYBmL_(7HILG~z# z8%2)_GS+3y({2iB@+b30rlUd*W=gD_0oX`c{=Z@_fhqloE>gTN!P%j}q=K&?e~2 zn~CqREj0etGDV#7Nx>k9KPZlt167>!D;hX zOP*nG88|p5!xIqa) zuQk`c0%}bc(;0)Okhn}TEdG~V3=EzU)UJ?j(gaW32)qrHQ+KBH^lIJ@?rB-8ZJzUD zq*v0={25UCOO_=;uTe;d1@L}qkqSZ-=e_)^_3uo*>6a4U=UFp>~wKj z4ig;B>?D z2SKV$s8a0}Qd5&AqsbGNa`NU%7(k&V$(Ah82A|Ryzp9)xeRrm)RpfDW#Q#u~bC)g=vrWc4w9>AxUD0rn;iOIX5&YN97je0qy%i+_J@ELkn~{fy^j z{4c3>X)}p>~6))D^2?PGVcnARee*{Y&HvR@qW(9>zEhf3|cd$APjwqz?xe< zaJU&67`kvdY;6cXo)5~HP+2=T_6_VmP9H<^rQoT00ib4hbcUG|6_!*Om-*Ql4LTil zhD_nx{++X3b;r9#PY~FOYT3@v`)--D_~D%{NQ=5(drc-?XTq3+C*3Y)PQKfOKZ(`@ z4qa=t2lM`Zp#A=5oV>%hYwm){)KR%plj6$y<+lEZ!5g-0T9b)6ecR3zNqLlV<)+fWPMW4u0-xP9(c!N*ZN%gnYp+XXacu*-3cCY~BP}ey=0~&> zVe$DcAL>q?RHhCNf9xSc$c?)}%`b`m!ugiI($)pd?@Ia|DT{xa^v?cJ#T6y1xoo#+ z&&&;(>R3iKh;|P<=Hz7ftCn0C1t1uZ z-TAWzWMd~4of;5x#qgRP(6mg{FER6@Nz$41dwyQ^Ct}FaMIdEUcCVnXqhFah7&ah8 z58HWb1_t<#SS_69=Tg{ENA|icaPW#A@*c5Q47vW5!@e0;xZNximu=s6wUx zV~wFw<#8bo{1zJSDFKuyG8Z%a8@4LDTfYg>qDd}o}r$(_#NG{{D*4$T}V|+ z0&=nWNwWxJlkIrjFiUcsy{Wz~%B?=5UNc7=BSTj{2gMm{OPcp(wT6P*3&3>>wp!i) zOH5;2bmA)0nGe?`X&~_3S(Gv}B{#J2v9Sb96YRACuBINqa%b{14 zN0gtFcj!2I`PK?U+<_EH*_oi`%lb~#KT|)3RYI5)*PQZ6}F50-eha;QqyAu3!G*n-iW zKSSWTEYE+Vn(b728~1H_clJ9@O@Y$qd}BNCH`-`h0oc#myp1+u$T&(5)agtk>95i8 z2j(TUuYz~2pMpb|BsPAU@YedA-s6q5zMkXNOnCH&PP0>F>Y~XS`W2VXY@_0uXtfF0i^zlM(R&%>^W^^cT+u9fs!<^v2 zIV)%)-?E}HuDqSGR{?`Tps=cnl!*x)9lq4_3Ho;XlrcLy#u(;EnG%GSA{B)%MIRMB2!a*-ubecp(P^DB=DH z_bTGnc}^87VtXg`)P8vTh)bv(0}$e^(_R-ci}w?j=(@e5VNzbgAnMbj?MO@Y;+vt= zLig+qK&5{(3CCPWwO(6GUMeLfVu``KcNp9Q?85^WUJ$Sqh_{ad0KYo?@9(d#e{)A9 zDjMABmg}U12Kqhse$Xnzh|&C=8!@FBAfh!X)BE@o{E0lf9S&(W5rVi?@B(l{%{kXj zj$|t1){01H6EV9_>^U3oo7O156sTz!D`7n$%W{S71pE<2z9+4^O5D0j11a}>YnkI= z#@9_odvv5Z7*Tb=GmF$WIEkV>mq>yWXunGp9#0ib&31$A^Cjlus)}@)ES-=kX}`hx z%319v_1>3qoPDZvl~YN{Szz92TKUq;aCryH;p}#b*eIRFIwwiWoUc4Hm0lN3^qH|% zbEV=q$B(J3wJ<=^-#)d-&ibvRjkSpiDFjmDrN&3Zkd{waTvD!wJ6uM6ohlj(xDscP zQLnd0YVVIo=223AbMl;PsF`L&8xEhAtCDKV9PLr4A7at3$4ar5_q>+t(lkNNsxuoO zip_WV-R)yYaM0g!9KO`8d_{`eDcK~bl+l)Ng0eKJu^|bfSLPLU?ca@NJ=0G_|(9O;DAIV%yD?~hLI7QJbg!B8r zKo5nNCBQ%Y^?wjUgG+`d_+J^MQyN8FO>GP&tz7(W6?DGx9FQz!W4d<1$L|m#Nkm^y4t(w!N(7E`KGQjWCGm_qPbiK zSCmMBGfdguP>r0lk#tc@29=R|lD^(i>>b>TiQ3Hb#ruFs_p^A+7PqG0flzMr?lYY7 zObsn(Mp~Q$J=K01BPP$LQwfFWnZ-^;h~r|L@Our6G$M|oJ}6hb5$a~II)#j=ou7bu z2t^dweG&b1=T~}9$gK5rmXoPj>UAy+?0$tuo!XiK?HnJOUM%?pAOC)T{C4LBz?kut zn93;Q>;WbhBgbXTT)jO-l<9#U^B6TItB4kL2Z7|*M7H<1gvS{N-s_a$#J3)@ekxB| zjiivxWVac0hnox?30QH6obw#3_lw@)oEcpT4A6M<;c1K)A5o2-JHiG-qVS^bJdCpK z5>CeJ54SF|YNC|RrVEqvZdGc3ACW9=ID%L@MInxjJ>i`@FX!!Ypc<}{U~Ci8;b`s< z5pN238MnWR91GU+wq3S3XA;DRD|YDtiqxA4bX#WA@!)aSAJ#Z4N3(?McU`VzrwM9V z{b=Whmnt01M38#A`Dg1~c%V_IMHji*#5LJ^s1nhgUhEi%1Ggw( zbKbJW_cro85y@`$N3DXL>mn_toYAmbC@QH)_Kp<26fPxa&kfP2m(d}Rgou2@(rOBd3y!}0_Od{*v;hA16=o8Kn*+C9HHcm)k8ESH9j(v})15wMh1*ZpO80W;Kzp zvCBtZqW&`4J~%RbZXiW^V=I5|>};%@p_h^Dxg_@7Jcg~nhPz#mD2Lk=vcUHM*+&>o zt9sj-K1$^cGSm3%Pl5#_Ol=)YG2;Il!NkGP7kNPIk)opcSX^Q_!diKj^R~kmIV9Ia zei}mqVw|j=^ShK?PrAAkUAyB$V>DmZAAdN*FUfY?T8Hj00N-ztqlR)+jpl+A0mStl ztR%X0@EF#lYxW_!-9Kz6DQppas&h3#7bHvI@e3!QGv&S@p)aYBC}(w|WT^$ogDQLL0p-Dny5u zq;$b;P-JoL@*wtZT*>JjQ?NR7O{a%33;P&m=o#?!#)DVkM>|4Kn&<+Is9>fY{CeAf z(?`+Hc;sF$@B*MhOTCttuCf#!bba1}&Q9iws#K6) z!{Z45=%T-gF5en3B5kUFCff4!xF+rW?yS(S3Ovl16blj7BgWRWbs*%WL+s+~jQ`I0 z0^q9Y&}tL)*0LqdEK(lXK0;rR>`x(PBbsH5i(w)s6KLfUlgIr2ke`}JEs`?%+c>`6 zlod>=XReF)NmZsc;Iyxrm4@VbL@0peQC$)23CZ?I=TvBxEXqoN5-ey~_`pD1_2>|W z0XeT!*2SmKf3)RZj~bk0p_$Ebc;oS$k?jMu>Q+_~c$JyeWD=j5b;lfAMV&kT(~bJz zA6?uF>f}MDD&21zhv41Mw1bbajD8FIN?eRQTwio;Ujv7Pi;E)`LWz1-zOC11!4X`Q zR6rN@YbnF2Fj0L`MK;dsjz~Q>{`7d+&Tp9#)@=4NLwZBq^L1D#nK3i{ z*Mc^@(cBxPu&xgODUaF{*sZ!h%}ZY2^&&A(vaNxtp{P$Kx*YB7G^ z*iiE4316EKo*=o!iKn{27|Jhwvq#yX$?a)f?e_)pw4q};)7hoUAAYe8 z!p_TZM79~Qo^Q^psFNq89*scB$eX4Nks*0E7fN7Di+NkvQiQ;9F0Vuh$ zpZbVa2;M76tEGHRAN}p2Iiopj&Epb8d+QQTH*Ma)gO_hTWsmL=L5?k@Mt@&CPlrKg z>(&B#iq$IBY>_)588p*%S~PzTk(7vSAi^{OAI2Dc*`-rx_gsal?HbV2x;firCkQ1} zJC11zG^8`#8JbA1-m!3I;8or7Ds7Wm|FfNDz>+XhD1!>eXh)IScJPYdiKT@YOXp4zwR|8WL#5( z06x-CHb&p6`R$e$YqY=BeY}r;2F^3E)dL!vrh7Gi=y+mttzkE#1UY&)eEjocna+}w zS6fHw$Sr4w1KlfoV_1mtbMW|dQYx9Pn~r|!d$bMKO?a_vwC7C}hui4=+&(MEhVxJK zm=GpVJXIvLDTbkwf> zQ?u3}=VWe7P<2T4c|Q{|V&IpxV1v#m)Y@i>{^>HOMbW|1v)RFVK}%z?neUSSi95#O!^Kom&c$3dgY*P1Z+f0mVSN--0X^$8|z@`{nrQwxt0|^7DQ4CYf zw>tO7h}*>MyA?c}cql*$oA3`-VrNN^WjgGPmBNUxpC@)tw%O8S6-%1^ew=zO++Z6Q zz@=DfjIA=i%cgz3V%X5(y84cmmaNK+!UdTo?nokiGLbC-Ws@UbiX2&vWMxrtK#N2-^B7}Zq zxNnj^>JnBVPcaD*OCd;C(VWJWm>$BWilg9y={Q>TdKSsXo|jIb6O2lNbji>6aHXiJ z$wvW89Yk*HtdlbwmF~Q6eI3-79f8R%VW}xhJT}t8W1j2j&!epm(XBC^T0=(tn)(Lh zV5aejfk=^uC8<_ZEVSzh%ji*5hTlT+TBv!uw!>EQ$DtNvOA{g(A-BaCt&F}JdmLG0 zP~|kfPNGd~KE7w5*yQ|p0)|h;kLKhF%aLDhp5+bSy|w1&RRW#AlX5#Pjv0R$bJHcy zJV*5LxKj(XAP;ZzakieNHs{IG+AJY%~o6i3P!$mN$mRF~k~7{rdEtSqShF1tUR|4?*^qEJ64AJideF zu)2!k7^3h%II`b%z4WBI{D?vd{|IYRAM=~|Ad;vwH_u3IXd+b#MwAlXT&h2nm`4g8 zCDeZ(DU+|A1O3FtB6B!X@`q7F2gw6ZlhE^TfaN@%RulmlnY_ZGJufL`FVw!-=Lcb0 z`q)n8qPBhoYaBYy$fEwc?InSNeq^TE(GpZ}%%CfN_s&Mmaw}wzNOH^3lFJB28(=i^ zNw{71=eYOD8(C!M>|8|YtTC-SEj8!qaW$4iA@yC4yX#U-FW`v*&jOGmWff};N}B9_ z-NGF2k-Z!e2pA{%r~>ZE3{j(a&6clujDn|}w!)%x1lybI#H4d6xRB{21(OmB2DW0C zJv$&%s_2n*nJ)mM!8)Ephiv03*?f*qF%9TM^nX!+_z%&gzTqeohG!6rVlU@!kyUeS zZA;wRbyc3$V`+RxOmC>4%Wsob^N*V>x#p*Yn9~bA*gr5$@Uv^!rgTeEwbPPju@p8k z;NpM=SnhZs@P2}iPs4d#DN{>*dDh`2oz5##4qK2ltk3Z!zi$Z77e%NC-Nj0JGMZ&e zS46{gOliV1Rv$1vVpk8AS}I|Pq%HBi6R9sFU4 zAqv&i)QO~C^b8X(T$ppT#D2pQCwAh@E8sZDL5yK+PjW>cev*asD`OQ)Dn4v9nei-p zOY8)fzDL?ZM94)O|YE6yB-b`?Gr8JOM#F zyCO3Fc;n@8PM_&_jLPA;WkQmj{qBoEUDIhV}J?dxqiegS1aOn&|P`A{_{BkJCd>j$8xj{m* z(HZKZTC`QYPyut?`SrehtDve^(%7oRO=jX6?H29##+#88Os(M`UwMt4_128*3uX>8QF7_+yte|>N@6^qaqLX7O{`H;_|g2 zZV|_+8HV?*>dT4?FIB0^wQUK%5%dK0)W%m>P)&33(gMi`ea+Dm+CDhVZC!}4qgQ=t zXXp0ZF$D0`+TIi~pu#yhqe|I$lTVIF*CbemxRYCNE~OZo2d_8<+b$IPDq&c=@arP9 zZbrhVQf!O3>7ukM*pX(%&AHkf9x~&5etAFBG}K@Eae$m0DH1ij2bb^@X?AErnQIXM zZ%7@=*7Buo??<8P(xSs+)dNP*pUFDQIqc}v*O>AO#;}ScK_Evb>#xveWQ%IN)kQy- z=PyNJ^t?JQE^#UB1%Moc&yg`0Vxz;@Gos;Q4vmjIW;?&3)~qIeYS0ZdIcn9wJw%VS zR1W%x*(yv+ve_-BeEL&8K}CZs%`cIeI8T2?1d*0-?30q?T2p@}sD*-IV2N{;rlcj| z1_H=w#dO)`%^GyHAxu=R&lq!QPr^5DBYqE{2}QRt!ovS$PosmQ)1wV)HH|XW0u5~( z@DVq3uTX|mfk6#kQbaX?U#+Ny^(l8ezgyScVq43AF946ehlNbeL<~V*Qo`fPF^38} zXmt?($7m=K_*NcDM<;wbyPPGMNd+2j^pWGuG^!Qya<)b1wdL|k_(quC$13pgqm-Qs z-WSMv0g@`}{^rSwe!^-W^NKd=gR~|CcH3g43BL@>yZh@zCrHeiB=!*aXfsPR6lVKm zbfnh3;%Xjvnr6iV_J10wBfgdIZ9w~a4&f}ZCgQ1U@e<%PYUZ3r)K~3tc5Mc^Wlu`i zQ0SoZCa2g;ChdH8{E|>GX^=Cap>9iPRViac%#{$Vq0LqkJqNBBosi)p;y zBrWn3pBIJW@G+A}H>pzeY4OaA(y|CSo!0iw!(!8H%ZqNW)16U@n*6(HHRg;)aeQm~ zk2|pdp#@?i2PZ@joyZ!4Iuf9fW|{EVf|kYT59s~C>@X84 z&S*3pJms_C;qqGrl1eh`j@m;^^Bgzw`e_hq8bm*^@L`{FEgvn_X8I z`f=F}i1K!azlmcpOW5D$qOLs6*@lBXCjD%g##)LB0=!!Ggrr=_x)QCCuF8+ZU-j8y0HdZ3%@V{F)V$)df0w@T z;FnNWZrh(cCym5Gg?xyRSoK@;ml$+5Icc8E0*Aj|bi7kfth6I+IQrO>YcD=ph_)pj zrSf?&@rP!Px&F=qXd9DAIdvm4xP-sOh6Uo2#_d9k8iT`mhZsNEJ0k71e5RilKLA$3 zu4<<6puIs}Oev5CM^BjJv56QBhEOj7+fJM0eFar|e^UIRYq-Mluj4YR_f#9 zSS8s*xbob#jcMq#Zw0Q84ejhYOG$;y>uqxRZx<#j=g`8gUb%?AetcbJivm=Tz|@uY z2ZD^$8%yMbptk-thSy9OQ@g1;1n{QDKbn*_m9xcoYMuO4LbyF)0IVO-bXa%v1Oe4F zPgmby(}Znn;8SsEu~_zMZQ+m)y7SHX8cy9>JM5h-3eF=&qF=2Q1-~=30qN2x4tlY; z3lcP7j($+X4v(oj;+pY0W7nI2<`$W4AO~77_jxTQWZ^0C0nd1qs4srJ;WBPECLOfl zj{L^Ll(9`#WQjuk-`IHQo;k0KffN(eYGoLKw~;hM8A34mg$sA`*T~L`@6RbLDWRBeg-thHSv~eO@1L$7mQ{y#VpWO(L!ljOj zW!aaj4Hdp$h1?RrCP*xac;Sl>s_zgu&URNZpSOxTYW>2)4JS`Pd5Egyonj=UaBV=P zO$v{30yWYepRY;t1yKEQEY4-!_HkE?t`#XSw<-$A5ulfIfnD}Qbs+ z92nTjSEk3#tD5Z4=;F`=bm00L$-VMx$fmy(O~|Npu(c>0*V--LE{J|>#k9mS#k3Nb z+T)^y-|6);Mjf1-jF9q-QN6q-O7)n-IY)si&=p(4FEJEa%T(e$q@uw+hG6V@akZ&5 zy9xpWh@(KVvxX00o#VyE@GW@7UXP=hUe!g+iR0?>A-Ht}taF!t@-V#`MZ>3<`klbM zJO(HyGDFRodXXY7L~L+#!KV68? z^#qe{e{N{5URys^7dric+ESHPi$ql>0tLw949U)phCp_HpnDml*zsOf*>XER7Su;3 zxZeL()ZgsxpMdvz-)7!$xl$g! z0DO`<FiWv7a=$2u&jADbR>8^UU3i_4n{f+iVhhPPoi_sE)#?J#LlIq3jH=311Y%slE2+XL?JQ3|HBMJR!EOcohB44DmmKZtxjxgNT#8 zf{hvd`SppVQyon{EUsE2u0C9vlN$N#VG2?NZN70Lju=bzFNaK`a3GkO%@S+~RPdk) zA{XSy=li1^j!v`>X2{mY9kf)oR7DOES~IKvYZFVGVY@=~O?a2<$#-Bl#RW~j*gPhA z3pL|ecT@=f_F8dkwJA3hRx|gIFdA6QE5_Afdj)M7MDi?V7T61)GQ`IjTV`U8_Zgsm z3~JEkF8wlOxj^LnG;lU&i=_qyq-J$?E3X_tgh?`DH?2b?0j*UCFq?BCFSPbg8oRvN z5qg#QnhIJtmmNknXlT~*>P7N7jcY?;CT=4Sdfp*o?=c+Q{O$RmY*u|O?#Q|T;bAMs$+>QF;qk88>I zo~qCm1IfDj)7W6}_?o^}dI(()NKXg<-1LLZWP`bB_G<7)+sOS5v$gw{10C3GVbXS; zN&Lnx4{}mJozeH>aMpw(WWF{%&&*T%ePfU_>ntzPam$<+Q~YFo&zzx4m!vHo*2tV{m#=(70?4`j0RCctvENLA?8G*bFi$_u+ZHwmGh=pU01Y z{;w%a{3L}m?LL0=cgg5T;i|OBbhvrHiL9Dl0OjNq#9Qpi({7C=U%q_4s)VMw%P~{q zv1MD;$%MNyauE;4z6*^H=^#678sFn5mqj8 zAmLBVmD|Lx`3r_NplgZ~0~J!QytPpF)$ocdC81~gm0mxzIkz;2xDqv%b(8#1-u2eg z$CJyN{!U*0^?{!clRmJ`{$@^YV`K5^RU$gV6i}A=SyEGB6>VJ;K{?Y{oPsLn?-Gpk z6W|X_mXWTkrn9$d=g}f~klMF9uYdJJW9<90ireoG7JLj@L;MirgEXy$VmrUfd*!HK zMt})2@NkM^8a`J!Ky{93_83{@%4!X_n*sZV#pXf%w+bTFp8Zd#9^kE9!Z7PE#yFzGBmG?_59Hl|q6v)$}l zV+E;dV%vtn`~4mm->J>345m- zsUYm=d9sOPZX$>?+fo`zmbDBxg`5;@Br(V!Vq#;Zi9)hEV=0L&tYzre_hKxrn~w8x z4{3Vghblec1zdehiJy^^5{Vhxrs#~-;m9{1me$e?bT|?tG+2q@B>L-644UkhC2|ul zh!8FJE|grywKei!LyC33dlZ+q7xw;&r+QXaPDDkaD=GBLVt+De&(9g?3y#}gi>*UD zmsQ#thUP%#t1DX&th%KHJNi~oL|=pqO9o_MLO0lAAsst7+;Xqi&AIflVj~vUZsfMn z2dTs+$Y8@66D9?`OoU8E-!VNdoQs+md-dIy!Qq`t?WT?^E|vye#byXn5i8;%FhsBH zo<#xkyi9d{P|7U*bG>f}f9{kSyET8@xW_ zQfA($M3h>hhtxYuG>nunb|zvyat5jOluV5Bo&NwYiELy7jf}M-xmxC@BD&zACQoEU z6fjUi25~D|dADI1SrbM!+-I(R)*7ZcKV;TaOKP2GaT5!9Z)Eyoi9r-X&QefoiGe5` zus3lYluwg)tk%K!)WpBNNN@5b5};Rbss1tWnbXX6oOvAw^Q5Y@r8OuWHL=%V-fe z8I6p{XXaz272T2$x1FPR8a5lf)Jqfv6I{k%8)-sNEMbd>k?*{ee8DWr_*2iDPT61A$0#b5n7L3G{oNv5O#Qrh+o^#MqUqkM(yeRks+r0pRb-^N%t*k# zUBuo-TagorCw@H#KWn8^Ljd4yTs@{AvEg!W+RB?b7%aH3Oau&Buz!f|Qy(QgFbm~h z3|Qn_zof8ewIaJ0T-qqd*d!O?liA+O0=P*_BaazAF%idkq^(ppl{{8$Rq?c}zRHt~ ztabrBBt_QkSTF-)B0U=jd~spz@8WvknYpG*L7AGl%x9?dn4mLr|5)bm3;$tx}yj6L5 z9BPj%I9qu7tFiaUNYrvd%!slHHQ^B~fg))Tvv~YY7q-ies;5&?+NJ2c$tF_$q#w)zePTRH1KQb%{=<%dj?Ej`x_Z3o>Gn=>ZmC&r$+9atzzJ{>reya# zmOt4%&SZ{4fAN9pXXDbWWz3a~vvOKlkz*Zv-&K_3Afg#2R~v&PxR<3z>jlY~ZzM$$ zFe15@boehJp1+dP=r&e;S4F44945c+1=p~(?1hLjN7PZsxl9zu@ra-P>DSv$d2LON zy^E_B(svtc-nnBWV9M0UgBvp~;;4;*W;<=lW1uO1M0FSOMUKv7KE*%-aj>44F3Q^PVqX>I~~CH4cx$Bz?_+n1Q1Nd@iDag(ycj8ir8$^nJl$X z$b=%0H7lY<$HIZc8x_A~6pYPPOaTgnrZ<`B2(IIBwBL9#C6jXMvVWHewPjAnwTy*U zVOektSSBc7*dr4g&+mQqk(fqhEvCL2mF#X3&A?bbrH@n?R5RjHY1@nxiEcv?5h6qX z05jD%huFh1m3#Q?;_RZ}+qR~TK*pVhL5RA;B{2}TLt%i4BI6JfKNA}}sV3~Y*)N=m z>^2V4mL&fGT}DX2kyrRw?knHoIYbuo`{)aL)vJS@sZz0yrKCh}xU6NOxAw+u<-gi| zEFyg&&KIyBDBdP!dV3ZsXAaG46|5dQqe|25*SwV2bt980TNMN+SOKsr6?}w%?Y7ak zR?`l{F=$qP#x*o7l`*SbqY#i&%midkQe-ebktsfLAKNjse9XJWEdgekRJdN{)%Lb( zG!> z3dv*rD-eO(=cjs!_b+30C1zK`VjX>zC{6r#{kXUUS}Gq|DhbmfL?pp35W(f}Qd2y` zzcq6og~n;jeoHft3bBwyOI9MZW9rG9j>IZSQgQvVo%WNGQBM0zZEa(MwLq(=Dr8ls zz-m5fs-Ej^DaPoKh+~%GASqmt0GP++6UH~*K!1+976xytF`Qlkr3(D56?Kb62Jqk8 zBFQN*PbnwF$M1INvHVl573_9$(;BfvuFj%~SY9F7)|4&chLEj_h*-n`hZrB2 zE|p^j=0eSPS*fLLSo^W|O~g#AA7IF&T(uc+G7%Y=hz>iLZSp?_6WHJ3bao!S7)rnH zD`TpvwmFJg>_HJ)VM4*vGSEL-qF8cF5-Es?fB{x!=1$(GqMbdMU$Q@tJa!(h@)mE> zG8tJBG@h24$#Cc;NU?mQ;sisYiw~Ncvx&~eQ#F!orYu>xWWt)0EeCrXm|n&ZDv>5H zU?v=l#E=xqJvxe?d0BUvZUt3hQ%cgFi3x)kf9J`gS_%$$Fd`WMBOeeW5cILh$mB0# zt>ISUdu?KIxcru2oRT>u!cMu`;8u_Vz;raCMqADzcM01mWE8r}tklL(jD{wq*Q;Tx zV=~JvqSdNe=mzl<7+|zFIsCbD8JXb`3$Kc)I4S$#Jd`pE6Pi(rBB|&rE4klB7Ms;J^ui*2;d`^ zIh#Kzma#_T%NviSR^BR`@zqM*^$fK{P$weOIARkqB_O%njRrH$s}z1MAwFxs`ISH>B%2O6udVY2}QB!05~xsG$xWWThrh{(GeUY)F!He495 zkCn+Vqz~E$WJicEi4-KjwplKDY;Yqu>b*6%*Gkn}8Wn|=4;M;SHZ0aCkp~B}`v!fJ z!Th3kSHwpMo{n92o7qnvU70ZTHoi))@q4O>zELwZ+_syX<|%L_L~#=z6CV@4BL=w& zUIAp+3Ru^xO5*aC;@29rpu*vak&Ty`lF?CeLL(rs`PwIW<+N2&op(8F$l{vUUYK!R zs$%x8VZ$VmQ41LOmNkG9CNQWOkcgR?n(?$M6dCF4HPqlvuoc!tQJNneDtWn{LJ z@# zf_l|IhO1)@WmKwUY||zprXeNny49=-NA7G45J%%A)Evy22QBA#+SkR`%n9alH5rXn z&sjU!L97Q8-6IAJhfJ3SMX_nMbN%xszyAP*)7662NN(vhVlU~)x|O+SGg_O(l%azv z^DeIr5IEa-g9A2B(aU+GQyzCqWN{3O*engY&oWzO2;PGteQKX^5JiBMM$<64_3+*c z=V$^)<7wru<<6UKnYHs4u+*wU@+;uTlC-sni&SOm30Xc&l%b9@128cii+I~ZlEE!` z+MxUAldEQpwwj(l5>K>o0Ma=rA(-AmMPau806iC99YZsvlaNoPnpp-*``D=~$72NI zRrfWHCz}FBxeP8p6DF6&#qu6U2;7dTt%%6|g{+j=#?bZI#>x!|c!UE@V!;U&sH+IX zM#~_bwwU+>=1V_}Oi*vqw!wDmW&cP=eO62zZw~}pTuhqn4 zX-2BaqaYS;*sPRWUP(~dXz+)9xjTspWhKPQ4mtj!CMHQW=WJL-yoN&xxqDXHwsM}9 zrWg?bwYEvKVo9;jW-O!prY3)VE2p2N<%+VF?^nyX?!C6C){tO|*f9#=qLxey!AGu3 zoD2zX`A0xZI5pbTDyHk2bvc^>73o>9R$Hik~l zDq0x|*GZPEBCOL&Yb9Z~gJ$|Oh`>WG)P*x&hurHnGmNdeu9XY=V`r?hQr#up zERH!C=hup;Fsd|N$e`uW$d=e#iE{n%k~8?;N@nO2r-lm%UZJg+w5Qiafqi*-VnnVq zWe}gnR#EuOj}ndNp7YD#LbCjZKR1uSXY*F_Rci&h)ddxw7F;l(VOU_SA)_K~DO))d zNI^``#=r_%dTf2Nms0?E62~s3+g0l_w-Shw2HI%>EYl`J9=)bxZT9@5p%I*|oCC<_ zUhI`h;M(<_ROOEQmWZy%wn;FaHM%;RPlGBJnvH2*+v-x9HhE~U~-0Rs0 ztk5L-%hpLgaw#KJluxXq{S}hw_PB#P76D^UG~c z8!!B}X4@%deIYSY!y3$$4oUg+DL_agDGB}lM=(ZP^WI~;0v6~_XmS}#PGka->V}nL zn8D=kPKhw$KwKuNPx!|vkL>xUB->@0(^Qd|$JGipjX>rSD*;_0{*9b&o^Sx=glrra z1iiN3Zh%#aRz99D5g&1W+`VEKau%K#=U!hKF>4G!Vp^z`04r(Q0KRsex_H_d3T}(I z+E+1JnJ;C#!H{Syh*-7pC)!x@4`h>B1fz~nX&H~kI&EcjahOTeSlhWO42ujvTddVq zLCFwvtUJdPSQv8$?o|+6M5C9?^$Kj)O0oG7z}W<)o|Qo&Z6xX{$a^lVgmykYs^b#b z0B5%^h@JM^p=O197HT^ihQ;Hu7ONI5 zCwVG(F{l^;2a;M0SVY*8FB432W&&RW;kJ7nAR-#qgc4s2_ zNo5$pO}5-gOveSw$%SE%78D}p&m_u!9z0{9U7SWkCXDti85CseDc29}h*mgU zy9FW(*x{sMC=n9$m#SxI;JN<*L$Nj2r(qeotj7uK1^vrrzB&n)oo+yXCIFoKTH^?k zU=Yjze17L}7L9z)XBBF$Ml!inS|?MQ>U)T9@Hh}+7Auc{;vgnd`<6t1zNeLXb+AY9 z(OXq2CdFfF4AWB6Vk9Tls`2*2T`dUQ4maZw{{W11$|*kHqP0rMB>@7}Tf|g3uZ^>1 zPm?Jck}|@D6@Z>R_c?%x_z~&~13HG4-6fNprMflRR4r4>T=csg0&pWRvIke0nU+te z%b0-%@ew1?2`}7s2HlM)tj!yFdX?T6ap{3`QB=w}*p6+6v)wTELpGD0w%_rMp8$m$ zv1+wVIU`}Qkrh&)+KmcSGOr#$j9S5bu8(unPn-j8;Qex;`ch!l1tRdr7d7K!1|3} z{bs=-t+x&lw12pO0?N}>dihM#F;p{nlNxC-vsyrs))c@f!U$G#AWUMl`7Ve? zEkxUOv1O*sm)vZ~9vRE_+CsSsYra6uD~M@(i}YnA1wZ)DMOJe%8LF8~HcJ(ev?p~{ z$nk-WTM8j^*8*PB-ngu0eQVjSP-ADUUrnMvGobr%de3{h8!OxmQ=H9M~~&!+nx5BQX&tx9)lp zu0pM>=~!Jh&Q3B0s{@^|!z$71#IfEbd%#EfjiATlbln@c``K&n#_B(L z9Yk7p+|xnTjw)z|>yaj#rpWmR^XDP%2Vt5*>Uj9dLU#`>ZdZ1t{WuJJxliy9qfCMB#Pf~;jC8a`l{7gSdX?#9PUCWC>OATV|~s_f6JyhoPKK=Ofg2c&P72r zD+prR$V4@#1tu$DL3-rIMf=9m;)saacV0Kn`>E2UO9*8*8tTf1Fd>Qs{{a3uICkU9 zYccDc;9x)Cx&f)vHYWB=v-nLrj|*nUxGC0a3CUn6)Z67F?Ng+H=W&uDA&HrY7>im? z=AdR7Ss>C8WLH|LKB|zKn~E)SJ20n7>RmcyLGKd<^AwWkVF>?lIlFBAFnBVNzc4%`Ws`2;lTq|J8 zjwjbiR#^d_v1U6rntoD`OA zhDgi-#c+-*6*di1EI>m^qRvM##v!Y!vf;%H@^cI*IYaGRtaPk%O@d%ULDDf|ISeeM z=6OcbGt$f@{{UURKbNPeGdBr=Ug9cE8C{dA;FYo$S`G+Sb6PnmQ5#5e{g+c>a6nmh zxbiJ8&)AZv#}MO%jDQq8tw@uUWakm7vQq>ro#$cL1HdwP3rV1=v88W=X7z$hBBk3F z1?M**(ATkMC(mhM%yW;&Z^xyWg1vH%7O+~cnaV_i>x*W^hgS!$*(UK4E-*Z1WCX+t z2!9{k%=I&MsbetIvDs6+ZQSyfT(~v1C5FKj4U0@C42(&ecG^#u#^b+2+^usZe#`O( zN^`DIsd;QAC9SI*5&{Oa5m~lEu`T70K$4B7AihAIRIq1MFgkYi#^*)VEb+FrSQCRL zk-#UPx0m(F2}#EhF^Guc)pK3is_jcRG|p{#D(Y@RjyoDHE0V>Dp5nn_jBEJW@xcj z>#GXE_T#H#rDVo0oD@ZrHce|OSxE7Z%Z~B-o`7Rg#!)vPk;mh373wo%w)I$#SP?#1 z66Mude?nFF0!x$R$v6@oA{|kcv1l>493ER6Lr-UC9EW{|P`yO}W+sLcB<4%p3zm_P z?-0&2`rE40Qm5VLbsk?jSZ7tJR%+ZDqPTpygey9f;Ko5i$JHzdf!~~e&pa!Lc#>m55Od;fOLjbji$$yFQ{YKpYRsbtTLiSG_)vTIBF1e4YR}j)e z50LuD*9!oZJdJ!N4kSusx7sVKp)|H2(PD7=Ck3bJ+%=~u_DD5d$Q5Rqz}XO}tj7C= zkiiLH$$Xs07!&^h>bG31j4CVYOd!;3I{0MlNm#1lSu1wIl*>rqfN=J+`i`CNky15v2KPQo~eC`~zKoXc3Lf0e2S@_2~O*iUT= zs!_m)tQsNiTTWKPk6Ol{4REhzi)e!BTB9ijW4S;uCCh-8k2L}M z)*H!=^E0$;%F3$cFJP$Mb?bM%w&bBQ@V}K%7&NVmfs(|qWip_HIGBhnqB&0Gp;`2X zR)#L@;Is1P*x_d*0##P+y|u%6nM-GnBI7?YTh8+{&I<)siMsQH`R}7(%96TUY^zDBdG|w&)E=o4i@6S zIhxj`fYGo-?oku-F){Ny?H;Yq{{W8WkD=V0)-P3e!?{|Mu(3)qSRg`ajqH9>95D#F zT!L3^8+w^0aU?`j6So+iv=QasgFXK74^nVaji3TBKyrS0{|J<;7ZG#d5~_CIE!pW_Dr=oJXvJe<_vB%zjZa zteH}%=!^v~>vhxPSCb6@WoaL+($*ia<>y}3niIaiV-n{xp{V}_t zD_HZoZsa-`JQ<*yYu_$A+RBjba>4r4BfR*|0Ga#jOpbMns|@KT-bx z_v_H7dpyYSKfvz?Gk;J20Hm9fh8BaLgH~4|; z(b6!hN)=^uEK+YUa+mY&d3DKBoTC~s{zaEk?iV|Cky^ca7WSq!sjaO{D20iG^bpJ_ zzZS9vSrZH3Qaf)w4yvB34Q-r7tes0XN~hjg#w@+b3HWjz!j*!!h!og>{>CWw{DXe8 zV_SVC{N>Ubb()7xcnSbAi5#78LFesbF@iToXy!8NiLo$o5m*+oIo>2nA|fI;xVdJo z*IjD&?G=^PWtk!}rqC9NIj~X^LZ4F^1S8H4PG{rdC#4QXD!xE&I-o`nm^T+&?%9u3 zxmt-}>b0dp=`mqX7esI=8JPUJPh4&`mOxg#s^apKHCd5kNhy!IQsx1s#v~WcWQTYm zBZC<^DU$feDpT>ZU2F?^-@ihbrDE$;2~#B&C4P$VErqzE2@NE=Hjz2_>ZUcg@*}Kl z7bdl^vYJ)GPO6tC#~S$&3b`<5A{8;hCSoE#+}eh7mYa*j7DkL=ODcx4jAUV~$=M)} zYu|AzkzvOnncwoC`Tcc5OH1U_R;E_9RAZ=HQDf+<6y!oD-bu6|4G38&p(8&VM3|Xv zyv)c1-@QPxxt7MAZ7jPkuCt}i6R+q9{?Oe;7C*@MIUU5NA}4ttg*5D2zgf8~ek)Mw zJTb}BUDlh;PU6AYfmno2XjdP3`e345!9t{Cz5DAKc+U7kcnw=Or| z+6!fIh6_I8!9He7h;bf8B|l+qipaB*JwKMKHE88|eVGNxsM|ob`k2;4aI|LD#K`eb z#Lm&Y^a9J06zbl>+rCT4Rk*ropel-Fg)eg}uK=+I4q#SPii#wHSW~{|JsWowm%2Er zH}s~x9AJu`RU(m%S|VW)E-PUK)TU-&SRh+E3yH+UbX`hW3+_5|doJut*Ynw=-8B6^7d&+~Zx!pphS67OY`n2nmA`u6ytOaX$hv3loleZ(^w{ z9fNjBZTnyqRU@$Il^iW^uC|zr!Zw2Zpae-##y)qV&NydT0VBJ*#1`tnjnq=lk0^}L(i8G&EK+vRDv}?17x0NGc!8+m* zT%}d(kRg?-D9AShy|Xj(gT@<(Da4;_pRvg0(lrw#oCKt}Nq8}GeWav1!6m{vnn&U)r7 z-o|Acp00G!_YSYIO_oW^+(Wvjf=7WwkNb((Tbg^8o61|u*4n%4HEDHqB&vc?z6!Hh z1th{%PIW-UBuGu3$cg>+UCL}uO?s8tD5Am{sxy#}yt1@R@nEU|#X~Ee5V?Vm#Qy+$ z$#esol`2pR6|>gqVV+-eBUYWaE6}J>$%2;K48MR&q5`h5fv!31t=4KG`Wx0gyPIzIUIQj+0PoahELJUPjqwBJyHv<7-N-{F5M$ zXof<#@;HzZh}@2L+{$E%m>ag+cRTl1@?y(O2x6opdN%IwS0N>olSMOL^X06lG71A-vA5yVf%-BUvWjD3uKWqUG6Kvt zfp9Q&*vR%sK@kMNaUaKMkBQt=DsesdAN;T3bs+|>+) z%oD7oAj_6v%gF#RA+1u+nM4dQKeP;awjDcfBt;!cf|$l-u4XG`ZB8UeB%9b3+!BSH^LyB zLbTn4DT%L;bGJ3$rT|{W`q2r68#}voauGYzyE*B8d|( zY;QYEbOd%Cl^ni59J{T>VeZx+v!hy(MbAJ8Po}iM{j5pzuMCFIIfYL1F$1(2TCPpp zJ|i|Wi6Co`WQs7PS5z9gFOtZT66Z0nF9?I)CMV!Wqb{bl0lC_^>w3cifLic_TOjlM zPrDLff|XsSB=Rw7k+7m-XX0jLW+IwaDrpK>&wuk+oiTj|N>LhCYOWC+!RwaD8dy>! z8%M!J?fQ;@<>%(*rA1jas_lBIv}m?g7&V%u#?Df`W(4%XbNonRWwKEaL~=pJo9fFm zA$t{+b~fbJb(;+1$@d_F5^DowK2;;k%!^>1`0e;~%%Cy$Ka#6~#5VCMVM$G^5eju-5yk?WF-!Vz`Ny6s*A4+tn@nFqfDXutPK50Q7n!({G*o96BD=2@+?tTvoVOvY8_LO!s9X2&fRK4HYS8g zn1YXh!6_sVfe{1zBxYtKmhvlU)Wy=Zl((s@;4IRKuqd^9QC_l&L>#g|WFcf?36WC@ zWY2Qr5?rJLG1`$gmsajXXl1BNCbLRTNpzABEB^qvgDuF3#v~*mF%nTRJMXa7(O)Fo zWl4jaoF!##^|EU*RY(*#{cUIngnMq3Nkn@O`vzuUVj#S&D_;ZPfo2}J2mIuSdA7ex+7s4&RFv` z*e`Nj4ie@Q%6Ey0=ml%3jK*WKj=>wW^jNF*`Fd|tM~g~TCh2T6WxR+XzVVIrARYez z2-y5KV7JGjf^%_zix7Cq*4Fo_6{p&XK4QXjK{2hE+@e1%_W7BZhM4+5@wf}O#@`DS zEl|jwJdjD|siLs5Q4dQMC^?XkDUjYjQPVn8cQQ6JH8q|gp4#>-lb?+mHC`)}GSgi8zj)iz6o+fTcCaWnu*f2gybL zqB<1fy=yE*+L$oCO5^j?(Od$-++%A*8|%1cMjZvlC9j?K1Bm|s-1O~O8ko^V?ACKK z=yjTyn*}UgRiOU>A8@8%%2+e)jpvW!6Z?*)%6f|dQk{zq#L&EChRYTU#^qu+nOf`f zf@2^VACbhzOuTe0i+rLr^ov|ocD#SyBiLG!mBF~TC zS8Z8tYVC}68wH8g8E~y~w{X8lrk1mQJlZ zxlBcuS7WVX8T@u3Bmmj4*qJqyE@D3zpYvo++x*Gla<)SO7Yi2pdVNBc6D_qa$62s2 zEE)7H2KOAz&kqb&rh^qy!he=D zeX@igy^;z{G_1plw+LBsi3y$ldMxZ)y4+4GDC6xSohxT*%+Wu!N{4A6H7LePCLjP{ zN7u+CqB%)*9Sl}SBm79*u@$o|=KN)3t;Jm>ArfwdECNZeB(KcMXW}D&j(`s#Tq(Zg zCx(4D6PA1l6f{_*J9uP|q89EG1WSdwOdwq#5$Tfy8&tn$VqQ&QmL1Q386+k8Yl*XUD`GD>- z9Jk(jk;z^notn8nZB(PxS$1)`FSAzf04#UfA%rosZ@=7N%WH5~|RR#sIFAME4@_&>QH~#EDjZ*XOY1IjAW;H;u9a^ z6VQ0}2lAKcRn2N`Eo!NK!f{om$=STtawdyxSRnzjGhmoZADM?o&+niUMug^$Bh}%y08IigA$C>8c}*)mHSrMTzGO8G^J5 zk6^#nQe#~_ibIf)%*x6(jiP0C9=2x-n$G0Q7CNTc%7$N$#wjhOU0@6R+zvO*frygk zGXpRqv~Lr<(`L>V-Ke*a$mOyJaa8hk*F_3#)sd8{%$%%Cav2z&Tg;G=OwTTWj+mn@ zj<$<+Fn23n`+>+N$UU_k1z~Fy?I6?>PA88dm@$Zn_=1U&XyZi&5}GvED@07wePvfH zbfz{7B`~=sgs_ZeV4_GquLcEaUANyrE$Rcgn1f5lwPW#I%?L_|MF7 z8UFx|y;OZLevS93Uc~u7=AMzm7FnhibjNSlxs+2NVG?ZRAb+i=$ALmjN&wwh&DK$3^np*WAGnnI4mUr_2zc?|*5zuL z%`Jnggwt4>I&%v}3!_Gr5EQC~b^ic@l(5)Ea6EX3#6%3lf3Aviq}UdW#gE*GP9yv$ zd5wmDaUUCh&q-dAdsKeb2mtUAiTID1pNRhe`}7A{*24MIw#3}P20?`X0kZU;AAvjtxb{3Y5R6cWPZuk5;6g}&lv{~>-RGg z5ddyy$&aKze0v1jJ=^+N_kT0k{ZgCF&9_aBgI$IZ2=b`6OGYIV1MyO0)I7>!H(_RBa<#z`Vnw`ASTB5Q;7otKohU6|qAz&>P75$LDU)d(Gf&5})QT}H6Ti{o2bT)?i zb9rTk*56SM>geq*#Oi+IW06L_OHXH5xNs70E&!_9KWOq4mg1vVIb_KXSaaU*8a}HZ zO5Wf1Lr(a^-)`h;zZr8CSxu|N^0Sc9wS#UaMQtfM=L04EspCJF{Eu1;!RjnVZiwJD zg?f{YZRT7?TCye@R#{`%=H$1CXf{cN!kzXl%4d0!p0MMdLgTUCH9JMwj75Ii*|v<1 zn$^`Z$+dFPQ4+}|$j|t|u04F`_EKdN`|Eq!*UFydcp>yW(q2IL^;bt^`kB(K>T~>#vguX;A_;|wFO0-a(bN9`PmiYdfY%+9(|%w1{{Wwy z_l_5>*TwetMy|+COSl$YJO)=}32qwhV!}~bOcs=>#LdHmb)A~8$d1l89pAAZbggqcB>tCGrXqE5LA1WHK#yF+ybpDXKiNp-3D?i*XsAqh&FL}I;)mpJ{KrW2RQ};@zP@DZ&{1tJ6Qb(K#`piBg z`E9>dJs+eiLhco+M`y#%Uu>_)v1?sPMyhI(SbwR7lyxLyRFCA@R^4VXPxmbSaxPFv z$FXw~aXT9$X#935{{WKTxv_a{UHe&k78Q-6%4l7+2_7~};;{O1OU9ZyJ#PgfTj@)={i_Q}M&kCyXm(5y&5-B^j>?@owgMm*0^?`2@ zw83?6YtN(Kj{W`Y_Nwo9)4R&eGvDht<@?JSX6-vN>EQ%uf>y$}NJx|ku1oX(04a%x ziw*Z&X|b;9)0Cclxc+1v9-g_KFN=;1DAviTw;6WDBCUtWAxpA?D&EVk1Fu<3mq7bM zCO$o=?7k0F zWN|rb)o@yd)26J_x_+QT0noE_C1MjMEs%}Bz>EI?a9vz$&)90KuC7l#Nww&NzaFay z2Gy=19K~XD=!)=X?374JY$f~JA}mmvlvJb2WJbpsH7@68VO4&zbgpXcTx)R^pD||B zD_O3`s$DIWBFHCmFLbF!8L&g_WS1O?X%XhAf(bDmTMR@ht6v)PtB|E-i^(x#kg3AOYPkk4d3$Hr z=1J95`a-d!i<2a$mhf>MGqYOWpU2Xtm3rGmZMjwxmQUCN+R1_Yt>oCxagd4bMX|ty z{{DK4H=f612U4?8UL3VKLK^uxsB%&km@-*R@3+7dT*lG4m!#8W zO&yQ8ue`+AdIRqBLsOE74hR~!k6f%EcZiY$`1zTZrpoHnxnaqjjPkCgS4jT=jD>qj z013@uIDK2FWqSw?+wUXuze{s1JUvONnaGYiC2|VFTasF0V#ypAs>)_r$!+Fr1TJ7> z;&zGNdODF@ub0eVsNNMy>>_KWllJpke-JAGu3S~bEH&~xW+&DKyv%$6)fcYjU8sqe z)m*7QyI#7G!TW&NzE^H$45M+Dl*I2OWgqLSNkcEWivbeK;aFndZLyK7ReUB(k+Nju zNVkaz{A8kMZRTgDkgK^SWX6B#{YO%z)vmqLyhLQ)V zSQXaK>J2_v+*OLo5dKfr)ZbsEL2|(~6dVbx_hRBAWTt=0N@NCsQ!+O$>O8#_E$o;| z7|V)6aw|2jnj_mVD;P@3WaDWem>KvOj-$s8HCP<3CnnLLt2H97GP1GrX0Q?+vf`{& zX+e7wO^;;EaoFc*<-Chy8IHj=&HTf%c691hUKNuob~Y8f*0W@rgpLJlY@{X!jIK?4 zZ4(`Gg`B>evvt@!J`*2r9|ZNS5zf`$YRKE@_d=A#@N7hY52TgBalEXC05c+Dh8{XH zjXYW#0cBOtwkU}^gb}pnBiS+jOW%FADWA`$831-xmMaf$4tWe>D<~CNbt}?c7@H74 z)IqtiSOAI&T!;c9`2PULC#y{>c45f>0H#YQ2UzOS^i{o54Tiy+5({6lJuxv1g5$Id ze15uw>foP|$o~KVPgB##Hn`g+uq*P&t#blGa&7*x_9(=pf64$Rf7d`#f=%JW!h!jjU*hRN0LWliA&}z+D}4%UT*-*~mn227%p43x;XMH)Gcu{k!G=FE zZo6)-#NEcGx@--ChKoUCB+-b7IEF!g`FwunSY@$zE-lk|=*NlKLdk3lywzBVkQ(5u z!9Yqt⋘EL=t5?>~Rq;L}|@jSXo`_AeupO*Rppe$h5>gvUV&meacYqYJhj&^M(Ha zh{Q+3s8+_k$~a-gV^vR+6K?VrF9(7ID&MgnMqp;KAq}QRQ9J&lU?j0^89P}$Lt`JC z$yT)QU1zz=G)sw$_lku;1f_&1HXw-Q``@UUl)rl3H0#bi*-I`Pva2|pEazFAtOKI5-lDv^R&bzvsWE; zVI;hsQ#D*r*&CIb`d9f6t+x27q5T82K&)fgJZ2_%z(fE=R9LLa1D%G1)PHHm-a$wgI$QZ&F42TFS zW*`6;5fKp`D!!`KG8$tR!N%dP-MR@ybwbmQ!^&X2PmF8>0vO3F5i-f=#hXvW{M<2? zrj1FKDtN|Wv+i^S>&}HbQ7n@_9)>PC3Bt&PL-B||kC~o;M`2V`Z4|QkFZzzv=04Ig z2*?te;$ujp!D0~r=@}9^=MsCy{{ZtZY0PQ(EI1giOprvb5OFi^AZGhczycv7w8Zo& zMmn)(a&>U3#A5MpCAzxW*jpkE_0P9OnwmoaXD6s%Mk-_zU5Th`qkEaC*;OPU5K^*CN9D9gg5&fN zwZzfNwacvR)yj=*mNK=>lrE^Iq3+U|SGrcoSFFDokIGy>`sf8YIeYBbW`4Bf*f_(@ zpb9}NWUdl29>`xWeTV|&Q4{|F)f2qW=p3SKUBueTzjped@=cR~c03jEZ$ z=kpu>Gray=%#`gqtJeM(7ke4^F{aX)F{ew2J0`J`DF!{HVOxMOW^(Ow_6We4vgtT ztX8LQB0E>B%s|B^iTLBjyTGJ2oxM@M&@mSKX}+FJa!++zSryTj4U}V;wn8MJ1WTOD zA|hf()>Avka{mC!sjb5OH>+fI4oYrKGfriRxL4@rtG&ONwir-*?L2*{CR*1TaM3R<|64XTnbIVLldoD@j@F){+hB43h=xI@ZkG`cJi zF)g8BT-PV^6A)O>v7W;?{HJY(K05lVO&hvaj1EsqsWRbu!jl4hL`3I$%|HT%!7*hc zzcC(r%)_QSX2ZS~sm5nbvp(vj_ZOP1vgM$7svP4@FM5NaUTtv(q#Qrl8)eREFP_b1GeuvYz&K2oJRl{viGn27oj15nOgz$j{ ztRagQ7v~UB5zAP`{q|cj%{P#1zS_PwA{STA#&uyL!iW{L3ag5E3^;!%g%I!Yw?#E} zF|NI*SB%GoaR`Zf>Y$RUX_6ptF}}hUL=hh3LQI({DVc(ffcWZJF}0ee{VkF~1FYSa zQ5zRhx`4naD6J$r3k>+5uz19(Cyw#dZ?8F9R;XuDjm2A4=xsP_cXi^h3=tKQObiny z2hH>OK}-(+0D$z*EF+V+%hc*-mqws)_acL?)>8KgF;LGElA zdoaVqB8ZiX!FMHOofgvusgke@f@zqN;y@V%JIDT`U@eRmpTg=2Q+rN#Ben5|70f{lQJS?q}f87EKxSVZ;AMb=>Gs#e&$(}lZ_l6 zl2Yv=08SBF`kZWHofce@Fj$v3h5q71r~d#hk{(8`0;~o*A%e)}j}*YHV`+xlEFj$3 zO-7y{;sXHBkIYYQfVf#kwS1*aOy=?8>glhPtwFZ!!|B#w66OB$Oj#X@S;V=@_mYjb z=ePiG({8ZJmMLRvGQvXrteaN1U#skh1~>45AW@48b;K~{#6cA88&^{n2apQ&>)v}Q zJY2YX5mahdV}w|?*pzUS00922zfwQ*(AdpIQmgFcPDU!sPw~J@iY?3&MnOm?r4a(B zF>^8@0&-Qrigtk52`YNW2!XXuu1^|+RjQbbo-gef#4ta&!||VFiOQTZWxqY=Xqexs ze$~}3F$u~(`{}NvF7QZ^-4!ZE1cZo%W-$>Hw%@3ox<4U5^!jqqk<(#TQjT|6{mFc;C*osnhr;9WwO^CV zswG> zQmxwiRhc0M(j|z%2*}6zMD9h=wd3t4DU8R^3-(&Cy=~yKvG6>cH|?>B4g$v zBxB+_0w_bB8BFY1W*w@$MtHi*GaITTyNf2l^86RFqi~KBGs|v7Q#bA}7pb)#tPD1h z!XrJX^UkYPRB5d4--q#l4ohq*M~T74@G}4~GX?XsO`!Wvt9zNOFukzt#*n?-ZCRL2 zVyCBJWX0M|m>G~Tk}wEd$0DDI^#c7*w`q-CV$Ff zc>e&7kyyCWINyFdelb7lKlRWRzQG$LjEKsAb3Z%vAFyC1c*K1F0LMWY$;?c|N5y<{; zOR3+H15!aF`<_ud@4U~){KU5zHX;n5f80d;bjN6kOCll|B?Kk@#((A~pe+vGcH6g| zsnaxcFKVwW>0QpBuDSHR{2#9I=v^oq!DEl)%7DOve)a%tUgT{{VBoCHZINmW=Tqx0UmG zJZ3|<;F>S*l=hhR4&sV^`j09FO~f_MCw;*J9YJ5MN>kTPZ1^kkO$76EodlxHAe z4TVPANlN6$c$oZuUpsZ8e?9()-HP&B)^A>RL3BGw-nJ?)SXCm5xNM-oL>q5aB9Pi3 z$|R%xOvc~6_G|S1@6Ua^`{L#!y53oKb4vCvxdVFjd$`PIRd*_~no1%p%SIwYa`vo( zf7)cfMICDg>QUzonC@-6o;hev;^y?GLuA5kvheLgiNBkA|&zm2_~^1)r0JYGvh*;f>fgU!SN9{$4)A4shVE9T$?5*;!c|h1GuaD90~V>73Rv^tFlmCc z*&v^WF|)q&9b~^_ygl!i)z`^CA$-r$I;B1`c)zH1qlXvV9JY;4ZzG(kUP858CYi&( z`s=E-WFL3emuwDoF+2V(6@IH9`PxKy{&FegxSyQ+Dp;ZyMdWzG) z1v76RDGOeGT24 zdbXA|{{UdsuIiwyQ<3{hYqPz0G5IBt#?iFI>2V*42MInIh_wflk2610AEpPHUSoNO zuKeWi%Kj6}4$C91a`0ve~*? znvG!bVI)8m1i9QDCoo(5?a~^*{{WH=jRSY@d};7!#*Gi-Wdo01BPT{_X7vU&X`XVw zSpB*g0%Ux6@*yaXpVv})hfv1PZM_I@Yw7!7@M(HITgNKBlJaX~xw=;|+HHNRJ87BK z{iyCB!&Z>Y=p9R2CxpsVH!dq&qi`gpkW%9x&SF&~BM}j{@nAK};ngVIRz}n6x=HK2 zr&zpcX`mA(06~P7nNu{~ zeN|?1c?xt;a}|d4gAIksMq(j`L;(vQ@d4^jr}c| z8saWtEZ(t%#{G<;$_N^Q{{Xp3)PXq-<-sFl6ibdZ;zf&+DJkJA>Wn^18+Mv;EXdf) zwbV++Ewut$0&bR$g6GH+rxfASV1%YH`fSH({06`$8dNNI+}Ik<9L{ zC%^VgM9Cf%V&oP>Pvf!IX(kM8fK{VdSPK!8hDy09gy>%F7?v^>yu=FNhDfdaJ*w82 z;>0mn>`Lj&g1zglsa3R%%k@-UHOyDfqQNGzvtdHL&({|oR-;`9? zuaP4v+b+Rcfi4PUv2bJYC;C1A066MvUw8Z~Gov<@i;gvyRZcHO&tv5a20Y{-1R;k1 z09<_Xj$7|P011*mutq-pHP;-%tnp>M)gl`h^$^0=s_uCRsgo=MAIEsyOP9{ja4jEp zc>=A7({_PEioX29Ui1MmTPThh$ewZxnUS5ikVpESp~hnIqghcyIb-bp_Qgw?YwKs) zvYLuTHERC=+?2pTK)hx+#F-StZxb>tmIVscomseFzprEtt=29<6Hm~{U6PZrJXl_$ z{RcQ9lHcc`CBi=uM<-g)ZRd{B%2?Y73}psbCa@PN3a_Z- z(Xma4_PHwGj>jCA#0n-O**j0=G19Dz3i2vOXWwTRkxe()q{-azKyWpeQ2zk1W(FYG z!2$S*Nl*It0hixt$gOu7a}}1-cV@a)$+e7B#h0n7*sQQvFysin1d1YH;vjxtHifu+ zE;|#HxqAq`4T;LiS@(}Ly@P!+xgxS=Y?Ukpkuofql9?$9{6KoD&NB~f>$nOK+P zF_-CIb`e!=D#J1Wx7r_Dn%g4+!5~ZRGK!b}7}Uxg<8L(`NCsxFthg6lsx1CKT|HnDvm!L`0VJ75iud zYf@RbMjr4(#wxAwcR0YiWw40cFd+jhCCtk|MFk%c<`;|&MOpaAzf0J1P%5i_wQA*U zX5jw#<+|bD)jO1okrwkMJM{>w7iP1wcQGi;P**6LGE;GYZzcO|k|0HbMX=1m{{XM! zm-!J-KpMnT%GtFWt*@YTXBVY%GX%m(Vq^2YUK)**FC%UBjZ0Gf5 z5=mK9iIWTDc4W-VOl=!+>he05=uV-`>A<>q&~kr~uAM-{6^h1j>=13Jh+^Q2etSt2 z{yY9L5CyG_&-*o9tw!90P}7W1&~5uwi}^dLkRtW9!bE#5p3xcQ5yA&(js9oAR?cHF zm9a*oX}Sxl#EdxK_FU|96q6#c?@OpeZtJDT_>k*Bs^|Wnr}P zFrUcI26*id0@^sq##gxv)cGu~E~{)tUH9f#@LU8j#|>myM<+=(R%#(G0zZsxyt@_Q z@%JYWf&T!b>7*jYJvVE?+O$oJONgI$Fp@7&)Q(Xf1Wft)o}vtu3|Z;yc4i%Yhy^7T zab}g@V>pZjk||iF3q)}lTt_ck84)`i$5JyOR<2;PkIkyCMh3q&KP<4W;cP>iblOwy zXFCAMh+ISt(GfiX7&7LO$K`3wn)UT8Dp_yS2{5A8O3GWgzDUG~%ukF@$d>;A@2axD z$6+!jiNnq$vQLgIe5-nv+_DD5*SEJ62JG4w8%z+C@AJ@0ubBHcQJTubGPR_-u2m$g zX%8y^r^P^QLkh_*&>vArRf2NathRU!cS@RUTzjAa^CZ?wCyB6!jDo>~F&w5NXxrt1R*$mA z*0W8qk4YP5qmo~I0`F9(gLV>OE7$Nl>@y`Xw8?c1X5?|1k@j2~b?a6K%Nap-SvICZ zWUbhi%os35Q|pc7WmKr& z$p=Y`;bn1f#BRwax#Ce3T^vOVQ9#7c<0ca`GFwbUIJB(JLm!B`b!nb* zgiU%OW7~C8=vdFE?i(^DW9*oTnA?m5N5pkid*IQ%iDj^T>UL#K3|JX9nx1e)HGxo5 zBvKNx_Lj>T-Ud0$$QO|Ev5&VEKFqAK^rO*M>d@a=ls?rp_MX>LO6P z&j!7>&NvHe6a?;5=@bVjo?gLZl>S{W2Sy($Q!!@|R^o8Zgx-C-1m>p8B>jjw;vz87 zlack57ZoTAeUE5%+(md@JZ-FYC~6IRG@0YKs;h z6K!q8GRhFpDVY4CsQSsGLSSd{BtTO?^E~JaK~&R;3_f;^qedSj_g6)l?Sqe6{j#fb zRl^c*mXc+1nS+?RWZxQvXzW=YSpq=Ode`JG3~oxz|{_w*qQW4z-<%p zB|UPt@wgheO;wK5tH%SCIU05Azk0Qnd{+yYv$KJQLnjLX_3T42^Ci&~#)VRaWikhS z#?UJhIFO&RnPavDN$>+HC@tbfeq(*-{Q*7vb}|juZU?9oHT^?k;{Msyl2zcjT!ljY zhD;_&&*WU=d7qA$V<-!2)hudiV=T6_Et1m^%Q;jic$&WIN>#rHOvdpAJb&YlNq{OU zDpkNW=%J8QQBhaBTIu9eUx`;Veo9Pj?>cVZ`_&>D{UFfd0G@E%kA*8 zDk9ooUnTj>>;VxYG7z>DPRGz6Y+-O1r3-NQ-B)svFZk@Mj;vOO0nhaj+Z7S*`sV_0 zGqg_I%*?vRB;8*3-DWA&!zGg@!B~}wibM?ZSuRFcGEDd~891N!v<}kPp+_5Tj#>3J zg0of4gHs_V?^78Jh+6*K<^pO28%hj9VE+JH&j^THlC2rF<+I4YZ!3;D$Wll0X)A~p zz(=s9fdFO71!O8M#v_bJ>u3Pmn2HN+NUNR6Y5SKfFVPhkoznsl1g8~{{ks1Et^?H^w~yTQ0Dv;Z z#?r}Czd(^{(5(2avPy{&KU{{&n2?c$Nkqg1PT!PIQ(U@NOYUR-_fXrdRajiBKP~nf2rrW z#POejj;P<=$Kw+vB!^C&%zj5C zbyU?>7_ut+XhQFR2i zyPwHk##05l6~YclQ({>J$%cUP9ik*=Hu#y4Hk1DV$NRf|fzci2)t$WVMjd#MA+=JI zPe)`~k6AXoTI=Ha%Z2ia>>)6dX7MI65MKa0dh~LNoC?!bi4j@Mp)f4r>te{VMw};eU4Z$8)sbbah90b+d75z+hXJO;J5FOr{FaRfUL*J={_R$k^aO zx0!>O>uVL_wWA8~0)hh=a#lQnq)m=oCO;t&GAQNx{r>>2fWe<7e6H=Eh}t%vcD#}9 zHC+*=a<@LiO=*mNIIQJ$9np!HO5{dP8eGSg^TGxPd5!*WuNi!}?BA96Jy&zK8Dpod zG{MxTt8|^#t(hG!YQjaTO_3Qbia>>tKk$G0+pKBwGwH70_W3c9^2WBb9Z9d}4^s<^ z#A@f8sOh@vS;-D26FgDuHp!WBgEA@RQye<-Yvs>zywdtp{Xz8?k{T-$sXG_0wQ_Ow zbrvviGm+E%%}sA&ld)G4gLLg6xS#BTiJjsmIs@N}gNYcXR@KA~#w9b$afzSb>*i)Q z{{YuO%82G<ut-#`C<)MoPn}wa}G3jOICi$3PAhVonc~j^F#}*FZw1MCW)C{{Vmg04|hj9R4Fo z;WPS^QaI@8%w9gmO6#FSQ|MT7J}^I#96;{^KQlA)@z$hp{{UFN!85+}J3HOJ+xH{K z96qEGXKy=!sck9RcT%*L5Eb%JsoxV|iK*EQ9f(+><@s^w4F3S~H@6+n?pB<`;yYE` zja{HK2*~@KtZ>$Ce9#g&eZD{)5_3`@*hDLs*rW|aGe4vKaerX~lOi0YgM91SD0j0klG(Xihy4`~B=Z`(G*8c#;_E%hES(Fa@ zYut^RV~?`eDqK2ZnhF>=m=Ks)F`!UqU|=C)xt9Ht`b1zcTC*+PKIr{GGF|1;f*i86 z^uKCqY5FWRM1c$P7cV|r&uNG#7~UdxkD1@OKC8c3KOg*L@#hn)bC^=qdgoNtKmPzt z`&&~dILw8WsLe5z%810BTzDO3a43P6h`?>cW3M_MCwWu#0P+UsXgq`Zk@u6!{@DFC zGI`vZ>9auL=MSduf|8~&j|zeo10JZfzx$`xY8fzN21K@O2e&^QHAii7_*v0?napPO z?jK4*@i@$lY&AS~KkU-6F~`&tEooa-2F_3;D}ats^26&Mexn~yZqa=;yHlqwXG)H| z@>f%nr?(mwjgnjP`30_EGI;_fY>aXw9&*ki4cm-F%uL3$e1-bPcp2gEZZTRfz3NyMj*NaxH}7?JGI`9+V^M6 z9`Sbq-;Lf6*3@?LTBo|RrN=Ll?hdE7WtK{wp2gbYrb!!C1h^Ri6fESXXJF_&_j0?f z-aP||?RRr~soyPe*lbHq#*xuFk1plIku5VEg^X(4bpp|Z%m_&O(*w9f5uDCO`K$Fi z@`K4P-1Z-`{lDxNj$S2pzqfh7&gfkmrs-L=Zlebu_D50fxMG*1*2cO*6}ZGN@+k<2 z!F@B`ZpZhBEpr=rIA0I@&QC4tv6dO5@{a!i@r~!%h$23Fao)b%V{h`^fMoAwyp!^? z#f>T5JrUxcfA!{s?e?q3v3cDsjIzr(>xyB48^*j0{e$2Gf!(XX%wdE2-+cJ`X=k)Q zkzQDK2eRG9(>L^OZ1wB&c8C2~+*Ut4k_I!`i?uK?a!hd)DZ|Z@J8wIV+Sbjhx;hUb zQxn|0GqF0d7&hv)#+IV-%Kc$=EKx0XM3%BxO4|z|35GA?WRmHe3j3LDi&3RV3^7fkpG^t{kzzP0EQEGQGh^%l+5IAVFj-7j<^xFCm_Dj2+ z#?YPX@)yl+(H;um7DKeztbKxo$#G~@EQLIC&c$|#gsq9NV=zS?&)i2*eKLIB@vp*e z-T7lzRQ9K|z5DNep0AD8U6jdcZ6brrBjydLpqv|5L?zA(* z#uY7Dox}C+*Se8=M zD$ngyzwRCqEv{1Nu~gVo44AC~QzH=_L)~rCt)oLvic+a3^)=_#OV`l!(388WqgRX_ z^WIOV$9?d=Heowqs=k*VHzPTwwC$Q$ZCl!2=DxP8r)2$bc5+H>d7Q%7!FMIGlQBEQ zM1Q>~hhqGNZ(?ls-&SZ%Z>YOAS-U!KC!4EsTsk);TZ}%QUb;u_RSwK@)=EE zid-_vX)JP8>AI+j;1>j>m2e}2ju8ZLGr0c%l4=j}3$M*U^+@vY(Ilk5aF@FS%!_rF-v|OUU6;^`ci|;6iOy3g*C=C5-JeADjy# z^Z6+KM092@!rPIrlcQrxUnH;s!);l!#%h!j;m|8+8I(sM+INATQ~u|r_;=x|7p0h* z4>wx-xy8`N*^$SaVmM!8h!^(X*td*xgEQeWMKLiD(rrp8R8~aUdbKvT)5VY?0EjMZ zY1>-Mn|G9KsQgF@Mq~HB4T-8d8g=U8A5$Q@3dxvJxeTx=Mc!%=Vw)bo_j=nS`Tl$l zX`VA3EPdj~Db2N6sJDw-gle=7IU820<#k}V0vRQ!6AlmY^vp!{bK0oPRXQhj=2>`5g+|=`EPV+^17hDuw*)C}N}2K^}k48hcDE;Dn&qG6c})`q+=-Bq9$ zU6)BIqXffLj9uBGXMb3Tflko_6UH}*k@2+IYW2NAmccr;7SSKOYhD$ZX=)J&8M7e* z1t;+aG0I^0@3+T5PkmLXyuXIP9xh1LQl&s8G*7sN_FPI?gt zw{GP&RKKZk#Mwe9O;Lso!vGQ$LK^v#mHR1BlXc~xr|`rt=PulhD#MhW7tao zOqxF=BH;f3;ROZAAbv}f&iuOI)zmDbmG$XbW`ea+u}x{2Uc&&%d`%NrnVoi6bEqlrSKO`4NnA{toa9jo=R_pXRQ84HfOEMkuh_>Xm`5FrT<;KsX;L++%Z%x0%{wW_e0@i*3c~yD>)6 z0?Ltbb-vQ#$uct}h=)2zTQb;akcQB4ynazVDKVvldh@ob*rAsDyEav4@7--CVXzq? z%xn(B5fQnMwsx43k>e1|G3^ zRqKd-W&>tMMODDXClaBO4lxB2&{$VwacIP@oojhIHy2YUMfOP)O3cb+`MvE8>=1*N zQUMXn8E17J7RAe2F5wTVI|B3 zM(@*_QzEjM+9UP=wdh@=kkhql;_YMcT*;_FW5v&@5$q3GDR2^PI|V=3UjQDhr~Vcz zIg_VGu1(f7mBmp86Oxn)+)QD&oY-@cTzE}`T(8*^5HmY$TgaSgIxyGU)jHYoW#{OgL zCVy%I2xEAd{qz8}*|iLf&102buBuz)&9)8&5co?LB%)hc2NASKDcGmxCL$s?4$w|U z#InA1mowzVG!>2-svL4_pTIyA46$Uj7{ozu{blj-)MG~n_jyd1(#GHymY=ug_8fXs zVW47hGrUV8B*$@$h9-aJdZ9MmF^jI|=WeNxPEgpkb|Rzg&L1HRi$wl6iJ2eM7LjWdYz&SC3x-)NbJAd?rgy4N zNpY~p%)RVXqb)vPraN<_#1${O$6Y4;um<*MI!Hrp{m; z(Z>7Cqv~IfN|tPzE=mA68mtVoL$f+BWaLz#4VE( zz{y3(n-dVwb0hLHnfRJDZN833+o?4LV&3pwo07P+u#;In889$p8%Uf)Y{-a@n2vzE zv1U}MsOe|%*d#nb(G@|ytDk_6+z6?g1e^>>48#{MQ!(?r^Q&tMrZ8C)+sb8oZBt!X zwP4;k3c&j?VLNRFHONI}@xQKPly4vEW3F@uTI4Rmarm5%-2VVEh&vG5mKTY<-*7Mb z!N+1rtM@O}UP1?9*oHQZzF%Xq+M0#S(~84gx15I#>bEt$b(qc)R(XjlgX5V=Dgt16 zMDm$3h!am?#~LS(3zt zbJb@XNG;4nwh7L#2_WDzESQ-h-F#$XBY2*G4w`NP&Ym|7BBRI_CZSkKF-WZ>WZ|*% zv@e-^1#$SnPbm4Bo`lHLxp{~JU~}Y6eLTNX^#A$Mp5w*w*5zuvyr=ChW@3>)v;;k zNOFh}$B3-Rq8gBaU_`=X6*D^-bN>L`ZUxPVO`5Kg(@b76gyki70ShI*5=2545OXIX z3tXp&1OmtBh{VZmsnl?n@}ZKwQ~5dxIHuUkHGmdMCD9feU3G-OMpgt;CA7;o{mjgy zdM@R$>BrcNrao6oA9Q}l8dr+8FxM>v%SBLjl2TK=9Lx(nk+r*ki;i-1xi{YF$aDGgKwdoR*k7Rq_;si2**Q2&`58oVf|l4g)h0 z`AY;C-R$NoJg%Vg=+`z+RWz5Hq2 zxhf;BO>52SPxLF)UeaQwNdEu{FIkj?Nd7y>9)~(%0RF`(xdcmbg8}9YZqvoE5%4kBsLc`H0n}A7Zp(< zAHsG356C|m+x~a!^O@4!l+~U_TZ&m&+aH+ zfBm3k#F)_q$ixJUaUmlqi$}*ltEbdk>2sFU{ww)6PrG`@8;PwLmT3)Q!~X!Pv@M}2 zbx@&k&{1NmVRN)Ab&}js9~JEojy|5z1O9+TAB@q)mN+M<>{{UNU8-MCQ&69u4i!}nVIJsOh*3z z^AjKIpc&b=zD9Q#Uu6X{<2dEd{vZZ_^51>u{x;|@wOqIE9~7!Iq)T%d{3N~xA_MZ; zcKv>%=6~N$Z7!XMteyw=QTYr<_>BJm%t!j@Tfo|DJ6`mtrVNU9nJ6Dw4?Vx~+E^ct z{!(1y+PnX8BmZ{dcYSt@N)0mqAOF!cqzVEipwh4)t zSHTzVHuJyTKGOI904?I5c6&9c`{kpxZ7Z}YVGmGhtZL6E6jKEh11WWX7TmYj1|m>1 zyCygMf@iNszF1}GJ3tP#?q06PXsjb4X~AQ`v;2v{>M$4|_bI)0j`KuXwd5Z2qL3kjdw5>OSD;cIR@KeBMsAaCpdBWqOSY%R{UB=9tV6 z+pQmr3nQv~-`sxY`H9>`_m8`p`?T1lyB?fwlhRs$5qR)=8&AUH?eMtD%UVN#1p5r) z1WbvW$HeuSr;5jYIJF0mo;Uq6yur=uPZxF4gCVI8BYM6*YUNAemFZqKEUT2F5VK;} z5@RqkGsYq{x2*L40C`iE(mHcPc<PpC{lvNX zEw`BXfHtl4y70%rk05k!k{$c5N+sAhUR^T;$hRbMeMH){&6mnT=!~|6AF@&eC(beH1 zV9)`4HRJ8viX&IGGgo^_uj=IcKis^=12%{!FC$MF+73a-$t~!Tj%z98GO{C%5F$U; zAR-5FBDiG1pz9dMGuC9#X_T?Z*o0IO`iP%t1dMGHFjFzPPWJAr?QW6RDU5ci!&iKb zeW|z`5oKQxJBY{jJ+NDVswM_`#Gdd2w`*yB=Js>Db`bqkdUvtC(4BvR7|j)>?Nn+y2&Kl~&$wSX!qiiUms+B2_J@ zxMVCoc|yP=c1*e*Bs)i0QpX^{%^$9Nwd2kxbe?Zd2asMfRxz`b!`-Pi+ox2=LRmF! z56w61iCmiGR73?5Gx<#A_PEv>GrS{$?T3jN{e7f+MU<_L%PSLZ{{Y-)^$uoH0}XKm z7qr#}wJb|;P{fe!EG^CNhNY!|?M`>Ly`s`qv|ndkj&to-%U)RI^z z3ns#0@U6rPW+=GG%yoqy-UoMT-=nvjz8v_$qPzEJLH4t``cpHeS5H~s4uH`cNmG8-`ro-r|Ki7ydvx_qh5;DS_e`2lWo}CFK#r`vsCKY$>#Dc8cJ=1 zF_9%%P))MYkoCwUcb|>p8hl9btF%5M_QMb4r7(>;@N-J& z8lA`QACg{1>#XsA7egDTvKFv9Zt;{l(=m0;aIjEIn!^0Hu<2x!Ov!KC-VZyr`lDI* zPf2(?tbFs)ZL>+*&sAr;p`e(a-Q}~cu`jb)Y2Qj2PTZ4J!(KE-v?zi^$&&86XS#Zy zTK8+Zc`oKoQ(froO-9Jn!&b&swMBYhP$e~MrpiZvHes%FN0dQB2Y8;X9{SMwy!m_D zTi8y@_p>8+waZ7?-ox0TTLX7l3TZfT)m(h7?y3 zf`W-a`%9Yc8aERND|Hr(C8m$e9>5$jc*mh>kl?&T%ud{jc(`#iQ?kfL>pB7tW5w zVbXaF*J8WXng0N(nfCSKTWY>G?V>A~EZ8JqtFR15^4Mp2Ih|a24fGW9L&?7PcMHl- zr&oWxdGkZFoyp8QRt8emtsHhs23A;46y1Pf!3ueZ#D}co{C#1@H`>>S{e$gC{{S8D z6Z_%Ze9mTXDi(xh^uNWa%Xycr?A`Z)dv+*&Drr)m}e&0zKXB*1Xe{dxMP8 zxnl-r^a`L3LcT@HlUo=qCn^k%8wRtPkI|P+VeMn}0FEA=n-A3{#$BsK%33!}MQ1h8 z!8v0YJfF%r4;h%4+DdoC%tb3HJGncxG4!)G>>an)ssqBSh@_8~0Es9AIoOEzoumCk zb)P;VcDuxm>S@m7Pm`WoYM&kQlf7*tR-bP&S&DZ}VkX>%Ledb#Dy*`29eFWi`iYb9 zLBH4()G5ZLStv?N%jfb%J;O6}$8h?jDvF^X0$!L?$za)|wg zP!^oB|fhtg+eGK@nHMSC&b|by8#MdjF%uW-(|!_ z@7$i#cOS7;sCQQ-tS}wh@!u(Kak_uGUADbnGo@n8Pcc!HkGB(VbB4-nhaiUp^O!h@ z>p{uTu$viHWv=0dl`=Knan>sIAz?gOVW{8(zWV@=_7^Eb>WVY8J5GUFn<{k{I;Fsq9w{Dm2S{E!|D}UxWQf8 z_)uJMVK!y}hnXn~14>F5F~&JEVj@VUN;P4|EZ5Vt%C;qDzqux|t)Yblr4s4Z6_J9F zP;4?EiH=_}@f|j+fLU5hUeWb%**c`(N~+nII&y@H%v|#sQ@yK!I7v?55j%YKlLG0x zIyS8vj2Oq?xoMW^%jeJ+GMuIl*dH=zo=g}p*<}hHqj8y^l^c?&XAzwoWn7i2b!~y% zYV6v$LTR-E9Dt%sB%r1_Z?NtDqB@fekb%qOY}BoZoW@306i z;#mr@$%z((!=e@-BfvI+lG;CeOhh%0wYKY&hbxB5&`ABf*yjpBANC2fMix*;rnEl; znV-*p_tJLTsZbKUjqG@5Dr4G*rBJujs>zsVt_TT44k#tg>j~o=VhiJ80-G+mZ_#nN ziKUgckgoiIS0=Q=NXkgfyYt)tHlOwWx{|$IRF*W7?%&E~m2Ejkkp@)&vH79L&KK&-`>+!x3CEdRm?_ zk5wX@ill{zCdW2B7h$TBVx$(xY{c?{h?x9hHkklhbTRW+BU2YR^-)SvU_QP8vl%-ztgBG!wVSAR?AvKx-N@N@$<$KIQL`?58KkjR-82$0X=gtz`km1OU`PE5A+vCQ8XP!U^pWGWm_jf7d`!mBf1mmA=ZN-gfz|lp(7fjX{kTuXz=wwQ(g$#2CV)_uGBrV(D-4 zvxcui+cRNexGgCA<`E^L!WbmB0M-$?5ttf4eSd@&`;m0vb2xjbp?3!Ru$L;sW>p}w zCd|Pf89#=MLkVqI{vSMMCTE}kxmk6aht1>iOSkun`{iCbgzEJM3RVLuSP+SC%V9X? zBpko|dN$5eEV7}PyOho3T9q>&TCJ-jqfJ#B=04kPn_=ccMoQtd2?W7R%)~9Lj>cok z7mC8U)UNw%)3o|c$12#Z^9wkSRIUO>fBOnKu>F%WJI74LYsnr!GP-XTR*_^Y9!}L# zhuxzOTUr3~AR^o4VH5HB94Ijma~?p5oOri1}__K!wR#?{e)V^3~p=P7LXF5 znQ_E|wl)-mNlXa9jgoEacxc2U6F3Zd%C*Zig25qFE6H<6ngq$7<_jl^;&=xGo-rhI zD(`18I$DadSMU}w*$4jsNJA8Xu;#4PWU`YYHWF9FQT2|kkM5feVaFH zpV&7fD}qHBV^}9U&4M>rHOk~z*^^(~97Mzy$OmMyF1=~FuYNw1pRnn-D%8_$=7~a- zEo#ViD1bSI98T*c&i??G(HvG?%v`>?f7A75P2bE^Sf=y1l*9i3wg|YyZ2~6~AB=6c z$5Ag6ZZZv>H(vg6q`}3y2BU8bs&mk9fZnING{!r^l}wk{9J)9Ld+Xh zP$wfXAJ-hF1} zlTKEev9wxpu}b(fNyN|!=94AQ9y^plPV*D+0aWW;Wvf;WrZ+!IrD?FbnI(!+q#qa_ zRhC3d8Cfc1H{;Kjzx3BR7V$T zh_f8ABDCv>J1|$RU$!!GyG|Ct2}-?7Ul){w19ljV%X4xV`*x~^Un7L2kir!;z}I!h zSzNU2l9g<$B<31099tt10TIF=V~0l89W_R6TD6+P0*e>+4(Hh5XbW-ysdf+1Eh4FsRQ>MDjV7bgOsd5Fu?>-pop(X@ZZzyam%u5#G# zeOq};tFXg0RhK%;R%TEU3k|2zOBI;&J>#5?(E}YUt!Ld@*wnLs4@~5fL@Xo;wFnkv z=>)Dxvt@s7qgj;f8;p+9JM_~XIM{YG6+-Ts3|gx_Vhds>^@st5i`qm@mvNQJ3GLZUbBwDP#y*$VlUn1SF-thn~X6tZW1=47P5+)q$&`>NEXRqnxAy48K+6CXVh zDhE1+Y8bVi4zduIRtpDN4zV#3wpU;rnTSI@&JvxNWwgY|@6ZcrN8VYO0{7laA4>EI$#Xm|~!dJ`EU3gM4h^<9tmzgAeW_-j% zE6kk70vY)ZUpvP@SjS#opstLQbsdIMl})N=aQ14>%tt?5l$ps2g`6gMaWVMbXL{)1 zGMbxEVzfqwz~*(9ztp#@N7!RRr}AvbxPrZTA}Ik7AT&gK4`7P&QMB#Tp9WO1$!s=X zOsL~>v}t7%khmDp8U{+o@rOou0HEXxtP2w=omj3|tOI5QJzTIPM+bOD=Se&|=R)MAKD6&k5ZzmK?$V%dKA)UyqtFfXzMJMO1l&w%vjSJGEB1hO{;JZ zC|YC)P$V!j8_32W_p<}s4A-1U^JldE^!jvo;oREV+1jriqxHR?yvM;Y3a-^;(M3%J zWM*r_PV`8+9M(qh#7ccB_6zC_qIMOLLb zY}S%vp)%DfAXn@I4Y=+hw*LU{tO)RH%g(~+uITw8;AXh)h8IkCOSf9?^y97E%a!X6 zr+YT#*Q@H7;E1gNP)G^lAZnS2gZbY?J0nvUWHU5vBQZ6my?mVtK&Qe8W@3KXts6>+y3HN64jF?9Ynyr@K*)w99!bT6SzsTiBVT@()FJCqriYp{??oivE^U)~a~?ZZ2=$w{A!T7hMaF?P)S(LU{_J z0EnaUlIzBI)EDavp8@;D+TR;{D8Aln>-e?P9{6f1Qrirq2FVh|C6)et)s|smNI6FC zf&Gl_nYx3^9^Cy!@ZJ{qXW@@>bT^Ql(#~od+Vi-2qLH|0Xe}R)uIjUEAhxY%7m1fE zg3~ZujtY1F$)14h9~3nvqx1XDjd9%$`qECj?ayi@`4h%_M$SBMw#x$@PmswA?F&KP z&9+cNcZi81BF2xZ-_@g2XPc}1Y4Dr9ou{$no>NqxZ#5>W4Cn)Nt(S)gr-Z4znZZeL zo1wUYiETW9y6rEkzPi&NMGvMlb{EH7mZsFcL3b-9lf{;y9DM!JS(?jT{Lx5!A+;(^ z6jqJkSM1n!*t+x0+7AdjXW&ke)7ooVVefa#>glRcM#hW5X)RXj)ckN4uu6tb{zjW+ zS2OP?AQPS>p&=H;y=b_aGSrLb*sg~Z-db4XVsf??rCe3x?SIGY1xhha;Ikc&SL_~=W#WNE#B^^Jxh<+~3 zdzzaah|)RyimRDmk!PA~Ta-k$SI?XZ34+OvXA%N%F%ciW=kjm88fP1)ZRj0grLnr> z%#3cPw%qq{0Zgd;Rxv~?99`H+i00nV^;u=t5uHDC045?f>f!811U!*zdlo?$|QPBdsDWaQ258KJ4KZ3caR!B&5s+j?kg8#7o+uFMw#ktS?t>O-=gw#D#b@*s({xo zw|}kC9HWfy6F4$?x7U6)+|hV!&b92GV&8K+XH{osP*Qam9OjlUXDMa8f50}b;9|S= zW6=;t%r_a{2eQppk&u6k&uyG zPSePvtTXcm=+&+>z1#19eHB9Aj{U8@rf+wHP8V*pHKb{ubuu`9F(+DmSca`&OVk|OoNhMIz1x&`m7mRQD z*M9NIj@(;2h|KX=b*SH}htm7Q?-zTQqw?Mo_|xQ0sn;62Jg{wyUF(P2p4keFUgj|? z0vB9=={06$Bx59Tyze_r@%zYcEHeHi;Ox7{g7MR~x}_CQ0jR8GV=FxdTx{{X3ushWpX#-01MgkF7oGH%O9obBCo^MlCOf|`TH1M+9cM)`}Zay^Ic z-nYZQAKH%iWL5m`KObt!CatQuB->LNUnariE5FPbn1Wakf`_j`SZ}FzXI=I;unMKv zc4%(wU=y6tmIp4~f`5+{S51UB^Y$&0hLBGvor`FQi221&B)*TBOs<&nlUVlCQRQ_v zd^J9MQac~piumaMJ(rE>`#QEP*mv94T{^_`TF{|%&4?a+cnIlhx_#IBfp*JDFSmIP z{de<3U^M1fvlaC2V%XS$G zT~W5Yg=*=vpJUVK)BgaGjEv0eW)r^u z0FTG&dfp#!`^~5ON0!jtj_ih*!rr}U^{{A77Cklb3m|DFNF|K(n2?e0`%TW1{;dukrf6j=0y2$6&PHHnuz2Wc2<=_{nRl|tp=T?tX#42U*aTsqg(mQxm2gbACE)L&aLe?hgy&7*XBN?`il1}9op>+rF8`A z3}&3l*L`E|m7t?ptpz$_BK0(iRzGX83;D=Q6b8eR{kHE=zGZZ5lcLtMgOn@0ExSK6Nwm&?0LakMoj%>{FL!0RO*}E zmGA?wJ)Y7y3ObH68uz+=x=`tywxq}e7&4wU`1PmnE3Qf*uVW=lYK&qgRU}#kJu#KU z=5hLlH9fB4QOFTh44vDJW@5OQ%x`s$_LY>Ete}nxB7aQ$?vDX2+Wt1xH=LhM5WbFKqoq>Pks4d-w1+pCh#{{Sg}CA7WW^p}U8GU&d? z8tJmOj*FbEs+jR7HXRHEOv>PPRH|kQN_YIWjj8zW*!C+}cjs96E8-4_$$cMnrUe>X zRN#A;+_p&_q>z@B#L1+-CSKL{3Lh@b+7*N_y_a=@pHYlaehhE`igd^ zTO|p~$6_){x09&qyvRgo*{Ftn-8eL~A+vp|XRP82;$l8~)K*n%Urtw1b6jDioGfy< z>|As^yBJYwuQKuXGq1h<#qo=`J)ZHy>jBwb)M7NRX8V~qdHT4r~FJ`)ZRZhi4 zxAiQuxj>SOkdLT%1^|ziYay%LGKG%+#E42OK`epbn-rm`1JX|a|D%iJP z7m;z#H=ScR2NNbHCT4olM|1p1&uN_w?;(2~Z&i6C;-()U+SfG^U>%IrS_1l$66|KD z!|wrAfel+BwZu~~u|#r{nU~YGt4qB6tyMI=4-I=-l%6LX9V1^emC9AaUzTJoV5;9> zCfv5UJLEoPDmfw{Siy zlG|pyaa)e6*Jx%b0v^IF+T+{+7J5rYYUCi00OpO~GxVUWt@$ZOkfQl@xUkc%#idK$TP zlHd^$_U25U1TCLqS<7}F(E%efCL<+M=(NC{*p79%x{{YwsrkW~O$l0$9{nf8C;B z;w4Vw3V?#1B;ws>dDSlIsj5t&Dg1ZY3;; zF*WT;%a?4?PZ&TCZ+od#GpgKRhr)tJHib{5fO)FQuh4&nei zPx|O=g2N>1K7nGWsHG^2mftF`O`H$h;FuCF1jY|Pn359Ppevv9i=0=$0ESf1TLusQSD&#R6jL+|u z{{X%Ex^crtBPgqnoQ>fzw_P@|wSj^hKtV50+i+!Yh*5+KCSc+wCMG&e>NeL^xa>YR zF?TIx)ki9%6C&NXiHTpaY2vs5fFdyxfgm6qw+ZMEnB*C|?$c1{wyl*W_wf{kSt(BO z5}M=dnS4(;iDZ_;5%ILd^n4sx$7BaNNA0letz=kFwsgzh4WOb(z%$3-+3oFU3F|*u6FT?)0f(+) zo%iXjX5}xp6>`W|t1)Rr;zeY*auN&LS?w8N9Em`aRm^1liJ6V|nI^TJLrgAT#8*zA z$yFseizPyZ3~MGn=hrMN4SDS4$Fq4{iEXzj+yzS(U(jb)pzVT3mgOoUaRSWRt|B5; z#KnXJGaJC1PbrevLYai6s8z)84B7H1y*LlVJ(+GBpM z!NVP~$Xr!h`7G3ue&DCtm$fj;^8&S3A^ww?WRMrZ@-5Vdo{R!=cgCyPzG6^2Nb z*_jw=3<}~PpwfW>;L4*Cz7R7z@|frYa+!-L`&#eC*s_X9S}UbiAm*Hr$EMi2%RXiy zU?*C4iHYCzdqV7*LACAG$uk|D$i=$~vI@luZQF4!8^NFbkoi}$@!RkLC=rO`Jszug z>QozwT9J~$z8z)@AuU`XrqXBqko~-Xi4lG=ylwmFU%a(zFHR`rkwwc&>9VoF-)^3R zddkN&Dn$PPwPz6p5w_-k@?8NYYH}3HaQ4w@R%>NM8aMs*(^X~dg^Xj;Ff4O2*v2 zIIA>qE;e6%u}MQ}3?;s`kNBVDD;bda_?X^jueB#TfJ9a!p^T(!`)RfJPWIa)XgrKm z*d@=YGw_p`h}&_9nVx`GZMAW?u29qk+{!r>5RAZJzT}%626?oKXJ$;y?lC)jZ~K|+ zon6?BY7ZQoeww4*+L&rAeMHVNv`Kb0ah$z{Wo|iRB>j`IK>l&C#P2iCfaNELFv(+auW2&O)%P z5W*OW;-&<}L)nH>Nr5AYWKYLHw#zEn#9RJ2G1+=ohP?oJFcnz>qcgm!s6RlIPdOlT zOiZ+AZTbeArS!4ZF^-Kxt1Z$jp$)(%#ygMY3|}wDoGpxrf!pNx#BUt{(N(bvJe*mv zhYWhJy{*MWwMxpS7_s+r<@lU%4nK^j*Bfo{T~!XuWW6`gjYmwtBO<4&@U4`1S5Xjs zz^qgQJMte^+X;+s@zj|nQNiW0v0ApM$K)8FWoA`Xkc2GP#eSOu644zJ8cz-#hVvvW$`t}#p4L8%G@rdMzF47h7jO@KZuSXLpw}N#QgOPebsjz<_Lwy zB5E0(B?_)EQLqfKR!}TT*s~KIq9^sV@7B8BInswVm*?78L4bmsb?3073yVThe4Z ze%f$dzv2(-qCH}m$~@I>ivnHp0JJ0Swc?+*=u&M>K)bpDF?AP?LrLZ{mNR+W9Y_-V7iRh(?$;koO2>&Bk@qC)|fp9^#Ssg z-I%wgYw5b$rpT3gmr}&pCYX`dQkMjuS+;D4=3EyMGXoM+GYO>X+LhhZtSY_vhVA%K z$Foa^_av^Yt*w-$6^t~o_x%rTy|(aw#opNH+(wMX_8+x9#;5jZZJf4W0vSuW_7nii z;f5q&4d)^w1;7Dev`1b@{zylQ+EWji-ATF?+S@BY z&mjY*UvA;E$C9SW#1w5kb?zJLpXR2O&{j0okj?iSAEWWfVi8*roVzvXE>1Y0UbFlZ zKZrr3f(9aD1|m0|?D!ktmtZuPd9)@6&fPnvyod8+xE-^~>y103?&;-ZG*+C!dr%f> z)^p*4%$p+Gy_TM1$!!6T@cg)Fy&tJix^?TzgEu;byQQ)BI{U*PCqAyfPK*9G_DkwC zU8wSt#T{deQQ*6*I^loFX(!;2nyNA`AK^=7MC4|u0E|_QheWh*{wWW z@LOFTpVQe)aZak#HL?R=DXQvwWSfe^*&T+GVoq4oiH1M!2qWSrebL4*!>-BplHZL! zQ})z6X7T?3R|{8<&|3b*Jf@hbYw{ybBKVzzSCN4CDx7eDA(8-zXI>&Z>6Yz}YijrV zG1y#=U%36B)2hqmv_4Nbgru_rTxKh=paTTOi8P>jf3!hu9~0Npw>FYxM=Ntnv4Hrm z2D{bd-;g>>#6KVVbD7t@>xdQ}4eC1U(DjDEkzLGh@l`M`A{B|r7x~O?$cgs3^ga4g zm(x$Xz1z=YwMIX=xAGc3h7&WYZ71z(WuNz=*FK{6_Z?_8nxYOTazRe}PTg$l>5t=2 zYCBi-{{Zoi51_IX^_CAYrEz+*P--!7+HSGR+(O*hbNLZC1)B#GnUVC2Ohk`a->C9> zSGJmOEvz-|yjCwrV{0<)`|nH|Xs9+JGl-6H^T}WVytKa!z9W1a7?a*#9(zl#Eo#kG z-%jDLIj6DsOqz3+uB{(qgT%JApL|1z1PTeSLp@~#Qb7eXI}Y9^{+eDA_kX?lEeC<| z`$puomu+!6hZ%ab@e^qYueNFq#sr*9i z*KIqa$^2MAy&L78i=(0ZXz@q79yNETDLC@(CvkQ5pQ(w?U;?2OhANbUi0!=Pg|P{G`0+3G z9BvP%_tpzL+gyf&?eBW@-;cej@l&^&XHaQGSg)l;RWpNE4BK~WKPbW|Je`|Mq}vNu z^)_CqE=MOlc~z_`Pv(2z^~&kehrq*4ng_+b%w$OlGV$`s)_aVePK#wZOjpvk}ep*twrsZ$F6yj?gjj6CG>w zw;p8c?Lnw>m9>_e$M+XZaeOj!zQUk>@sQ#>Cm3{#hIE{`!({DDmLWKHqs~+P>o-X*9RgOUM0J z-{aC%arjL?+-yEp-F;b#!K%v~IQ*KL-LqKUOmvVz`!<;p+yo*oKR5hK?aqHr_M^J~ zG3NW*<#v?r0nSf1t@MtNt%}isL=aUIfqDgua&t*=dy6LWKv!H=n3fjeI@rhFxu|nk z?H{MGx2)#w*o3B;l##`OB7r4;s_Tf6J$yzlmp$6@u(r>En_PR-fx zJ;1vIiq;9QNsu_WLkcUrz1$=3q)C7z&s@aB^~lM8{W|-}t~_1t?u+sV${cTC`}N~f zGI#r3ceu*dwL?}@vqGB=7nsBQ7*{L=goJxxWYC4W7ZAWR$$vk7qh0m-sOEIvhCT!7 zJyoZ>7pRu1uE^vm9VchY@tA#rAI7}}Zla3Cx7-jiHkcTQ)1Q(Z-_~8;)VOaQ^gfL2 z7B96rPdMD}oYB3m$5{*>CjFK2esbmOYKwV1q<}?VylF~+6#}@4_DOc%fgWa3`fhm> zpYELZBejM6QkJjKm1yJNUq5z{$yT{uEReM?s7*Rltk|Z)_C%1HI>Qh zSI92>d0*mRg}vPGUXn(a)%lGV+lL*T4x_5YTCJF^PyjM@=1ykC6ZN^Uoug>@h}t^x zTlDwsA9*#`a5WFqOUV4^k<`2Ws4_ugKxa!P+*KE0NC+?4wxO7`#YX5=JbK7N1!pB3 zN+Yex`LFem@H4&LlEmNbH(@mnt?%xm$=9ov$7;t2v`6_NBE3HM$r+~Yg*AN zTvKtP_R02S=7*`PR;MMDjYf6@x;@tH{;bI5G`f?l5u0pIrp8=*UuRKSo+TD6Gx9Y$ zBtQFyc^DB~PxbZNo@4gk!k;4hMXfD)58B;*rMtx#_T63lEy4a;g#jS3X3aa^ft#M8 z5-F)>3QT!N&nTGh?)iA_p!{eGdY?mOt!q5R!}e9utJ+R^e~p^Q6YSs-8%O2G;G!e< z){8u#^6w$r?5BK3vf67?c{k;*vBl%C_3*lX-fYr2Hr`cQD7Rd9l1rfOgsdib%yO9g z_nHq(UFtS>io&~cURz(>y=(T`Rpqn2wp)M6tPbe-gGa{AecImsc2m7Nhd-e;em1^u zw_VvCBXdmu062#!jf!?Hy?<-`kVR4>s{sQb2ru^=Y>%@409hY3J6G79bJ)!1b-Mwt z`?Y&0HT17?4+^|>igl!AOgj|Tp|6m=5IaLkAZAW?-*1dc^WVx}D7)*1@%vQy6XO?i zd?N7`L6F4uhe2d9&bKEji~N!9lW0_UxjY&c29lncRya_ z^BS92Yx2nVmi4-M432kF$Tr4W+C5;K7D-XYWJN&&xtZWG8*RTJIqbz}m{;bl#s# zd%fDe-uBNh>8g3XYhaGPotaOvMhz#h^PUkK$m~*6J8!>R(Co*9IbWv!s_o_ruo_W5 zPyIrBtBtplcX{rs)uOvcq3f^;{hFCZ!Ga~JIDlsvYYov8JYoc}Wb+5A^bWt#nzJ{c z^*3#G1`l0g?2+emKA^2 zx!Oxjc(LI&h0)QIF3{s`q_N%3)Ya@L7f&$gN_NMrEFGA}NW!eRNSsdMAUgN&zj5z< zT6=e=^Bsch2CB|^W7>^*V@c=q?Y!lUbFDRYloY{M%MNB%h0({wmtHWg$UalZgr*KU z)IPadbmqFqcH6wE)IGfJ=A5*;k^H3#Sd7M>f2)@51_+si#LPoribh*I7Sj<2&v1Kq z?zRITmen5nCTe))H={Q2_dU3c3xe>dAkH57FIp6$-9lmao>M8Po&iz|;>?J>42wn}&27$RTe z)-GyYL#uUuTNiJ-Izj0~i9jxjOwzgyw@pm%4!-a36P{+V;&N0Faa&2sZq@qA=KF!c!e~}X64rT;**gw+0>HVX;c=3z6eol95 z#a&h951blDKYVnjZ1Yr-8GRig3RNnIMb0%=%P`NoW=?m3Qv-o>QO8}k=8t;2r}U}u zFSi}?ua4~(ZoIcwTg$_ZfBsLlg+5fleg zY3}!AqO#-b+5O3V6H#`xJ|pgVMfxT8ht5qw=hu%tv++Y)cc)W!>dvOeSl75~IXkb@ zzx4O8qTT$3X0+4yDM-ht<6@SE@ep4nwy&%wlDf0Ber|bx*^e9htCG$Ll~+b;h2o85*T1R)N=KfGyT}>AlOul$b2z-7!vtJ&ih8w^ByjJG5(y^bgnn*8|Bw| zvVKrphznY8v{o-xZkJP6Ji&#JNmwMrq`x9$4F3S2_}+6L3)HkfsPD%IooXe3B+$Ezw|g52csnP1?*W$Yi}|)r?1Mm9>1;$n2oy|lk|`-J zoL02FMXVM*)+dR$^eu89a6` z8=ES=h^brdjZz-TC>_m0hzKH*fc4CYNf!SAKNfXUdvfsm5Uwprrd*ifv1%+08?|YK zTNT}$g~gj}+B%`@3f|R{=12O0zd=>1S8*^8&@N1JDJQ-xD^}kt!YPce%)3U z;aEn>*^DUSsDXC!G7&$nJ62w`+r37zvl>q)yesbPI%Mh(s74(4G|HGH69dE}@faBY z09`h(S?bAHN*AcDSvNMS-IK?>M>Hl2V=TJc5LxN$nZHSb!uDh3E*ebN3?GrT|?U3X3DINOD&^Xxlb z);VfhzU0S*O|D2Jz%n8YP%{&>0e)YU#8p`|Cr(~V5r?pxVkN!sQiq-B=UP9iUPF9?P=qL&~{rk6pT2hky6#)Xm zCd5RX#`F5=wm#MAsgK8|uCl9c)8igBe$uPmQN)H31;DEyNdkabZ?ut5XF zs}oIO?=VZZA!H?s0fB-j8Dz+U_LUTKmlWI@@%i^;j^j>cpcaVjGQy9YyOo#fu-OD| zX4w*0x>!bkrA7~g%PU^oYgyPCt!U24ivuH?RLHs~_C z+Oi++g{4y~O5N>LiGF1p@3_eI_O055S=BW@r6y%2xALI3EhG|$ek?k^*oL}5$L1RZ zz8jSy<;TYe4^%S4C|3f%aoe)Sf!PSK2+00t%>+t&!hFkhJJZ` zToxbvj%4X%&aI728_(I-x}j+R%##rgBlRTa3IwCoClVheF)*UH!mV0uuVuo)a96BS z*UtqH6PT6Al)wyrfOdk??cuKEis!1)(4vGlaesd#)YAaP_rb!Q>$IrX+fj16lO zxVg|ji4x#O3P>aTW@bwl;}(}@GEc~R?pKz5v!m=UTyVhx>^iV#DP-%trqJhR_AUSGVcZj=!F@ht|t|#xBpV7xxaXpfs$4 z1fkP0JR~MyzG7x$ZMN&3eaGXn7i)hfRXAsjrZL3xze;}Qd64rMu-R-5!x0c)@z**7 zuEgr)Q;CQ+W?M4O6yk~5ganBCL5qNgFg`+e`3NDIkC>j5<{~Q4xjK&XZU?DqSq@*= zkjMkX+SiFD8}A6=FjEB~yli{?L&~_9KOL4&>Pl!~~hh8RDD zZ?^M0{PY!T56xw6{{SC{##zTo`9(_$QkOLf85RnV3c!PYDK0aUU?4oNX+X>U7nKuU3sn3V`bC zl+u})l32MgFwh<3cH7|LgZhZ;;>6CbHJFoo;i4w$HCiCr01HsVIF7?#_P`+xkKm?f zVvefI4mR`bShY_}tqRC4y6Y~zs+G}KXc=M4g`VJvo#IDff{Bpt ztwxZ!maK`BM#k(hfQYbMLM9?2I7}AN{{S0w4NOgW$P4V(t!P6Y%d9F7Y_sj+83L89 zp7o3u;7ZZYul*m*h!d!&!BwOsskN487 zgyHDrb7f+!}b4((wtE+AqGf~OF|=oDkeT-dGu4`r<`6geM5VDlhf6$WM?-45uDLl zqP1%oOe&n5Dv-cx{_D{sd{cyRkrE?#LS}IH2>qexa^B03!{#pHTex;rD z#pio_l)t6CW77hH2d_k9%@-sNc931?LrxONA`;+nynf^7dAI(X-%o7kl%3GT;c<8@ zMpISTtj$Al`M6!`S~7&SllSgJq5~mr!$IH+coM^alzho`-M&V6OgaMfoS$c|J6UKz zCQ9*^p0&FiX9dIf>#T{F0Z4I_JLF_Oe;zw_C(|>@PSSSAxE@OQ&)*EzsqA)+?=FlD z6&nTYGVXFdC!=$#S}wG{ zlRP`ahWaXat*YsEN6J4SJNJ~=jHIUB%LZ2K@z_sr6dIlUU`1Lihz?$#n1D6!@wZg> z>%+d#c2^bKZ#%nxuXXBt#nr=SX)j*iMoIcs*5HbN%v5NVyd2s9Ced!{_7CJA zjBTjgZ~p)r@2P$dR34M<;=FF|Uv3TV9A9veto?MHt_2IY`tSteV2qUT6NsJTedO|UQF+fpu|5`fk>c*P(Or?z*%xFq z)`zd2wVu6h)EP{7-hV$5Ai988Q+voUWU9S`kv?x-T1?+yDjEVk)7C1rnix^mZz(1W=|+N znyhHUu@tYI4AhbkAM7~buzB&AnJ&J^I%_WyPF|T`-Jd(elgv9E9gXvIPW?N3$KL+V zcn?F!M)Tudkg>60Pmqo6L=pZE{{SJF ziSnpTEHilFa{HN=^wz`UypOltZzFr*-JNZzbge6Nu4(Ai*;?5O*&0i(Ufb4w*hEHE z2vj5yvXYNLw^6NzRgI)Mdt+b`?(OkkS50~s5;;Q2HS8TCCT*B5d7{($c$x~op zTC(8pbN(cxLNaW*R`*q7|^oqF6_H>Jv&KCR~KK3J_|cpc;VacC-eC2F_-P@^F77J(^_LwV(k9_ z7m&tNGl7-cy|?s%1T;j>NvZ>gT#qihkLsC@>@S0!D0uDIzZ1K4g6)5EGl6b&MxM`h z)mpa?Qo2RukmQSiN%mShfO6A`Hb?_Y{{R{5Xx+B0*uN5V4Rfohmz&SUf4+*DE-1(y zs5l2$wj~qnkHAEBo;wcFAHKZteQP|A$@f1^c;Auk0(F%gIU3VYV&^7>#d@@+)mqS> z?>&SVP`!j^VkcqSsm_(r>)BeyH6@nFuBg^1-dyjc93*O6wjL{Z1Kpn0=ua9v)T^t$ zp5Aw|+m)w$fUlM;rUPH(EU>J~^#bMJ_O?CKE06INgf3vCX^yuu^n?0K_Qy%-{{T9* zXVfn_+79??Zr&K+akFwP9*5d4A*__oi7nJTscROg6V=sBYF<=`NrXUiU{8GB;8G#ZmGqF!rYpMJ=sZHS! zG@#`qk>fWP-Ok2$LqThP>gnKDW&0^#Cv}#y)_ESJ%Hd}q@uiML4)AZXBC-44B&_%dIqrlRkR(^BJY|jyXY{?H`Vh^&jx{=U`TQRMm}^`^@?EDT|Oy zE0k<YwXV|Z$ZXd|r?RWdaUmA5Ub9{@y(6f~7w_~*~ulsE;V^E-om46oOfC53s z1YWhiW>p~)90;Jg+Aq;Fy8cFYuPgNs%6V~@)Y>!8td66qfXC`QbksdNf}C7M3b@)c zF+XEg+pWtH^{J&n3!UWPj!2J@?E)i;UDo*J_}i7@qO#p9l?EyIXbHQ_sgA%dlpPmn;clCNRmaS@{iAy_0m2W`7PyNo4woc z{{X`R!)p%sSL{!B4_WGOBF8v+DmluS#kva{IRUCku-hY$Qs!Z+I5k_rIvKn}mTVbjiZ!txqYh0Y>y!Alz?uaSn5 zx7Z+h^<1wB^)Hgz7g^;s4kx-jf$y#-Qe^Gm?dCyMs%7b-_oki4Cal7jHYry~kZr#x zVNbzNUUvS!{oT@fzv`dcp7!|N+>YI7Zu$0e7lgpl)f9C)U2gVZEwdnW3W_X49)v3L z*5%Ab@nNAcv`lrl52vrz559hG*30%6%U`GOa5YX^l`55W7P9St{{SPV-(ki-ZSCge zvXcyf^DCJmQ1G4hK8{!h7=3Fz!N+(LA&zl~9c!8{YyQl2xJa2HcXLYm{ROI`ojk8^- zn3b}%fMrcM14x-Qw&rYQxiOJq`p>*S)7!L~m%EkzslQWwABXKGzRo7@pV6JN)EaS@ z^p|YYL2X7n^Xr3W+)G78W?;5d!-78<{ac?uPjwaSLPq9L{BT8&MP&tbu57VDBD6Wi3}G#C#yLmK%*^%L z{%-lz+@CwO_6ptX9wW5ETbVG&KB#x0ZY>^p?$VLF5Mo3~z=kkc1{{Y|4Q|AYrj1dXRo9JGrOrCOdq3A?J z)gC)ZM)Dw2BQqOJ{=fcxW)F;BZg*qFVbyvjt|LSFLD@X+ogFOgA>2m)04q&+h-~{Q z)=9mJsF5a{j-WuT)5DO=j7(zI4?*Ph0p#uIy-TLGbu3%zCnlO!9kb%l%Q4gY4(rQ>&D2OBvFX|BzAIQkQ;Gjx(jkoI{_P^R6H#|A= zCqe4HSE4(|*iOUtYR7Mn72NqBevH?8a#LK_Ld6$XXpmD_0g6O+fZ%cyJcuI)bDg{F z7uDy*jXmC58pFKa$A2_ls$BkjKB@B)?S5$H`3f zr4JH(=k8aBQ{5~beH+`p^LArg)QnEJ(mC5xMl+-9a#l;pM9EfxO8`9}JR|a$`8n$` z^#1_WBfVYq)V-zgLj~Qr`eFEOV-Va#YA)8`X4`bH5D}(`$yyj-2{bHoa<={NzWekC zR^Ivtd52fY>)nQq;`Ue7XG&ys9-P(57hIvKEY+})Z5Gv624k&BIHFr-PO(5pEJ%Q& zbq(CF7W}*MC&*dtex%ctdnw$Eb&PJWW^*}!MWDvor*TfLdl8r&rpzCY6OHos=PMDX**4O`@Yja}Wuq( zkcdPVE&5Np-Zl8!^&#>1P59A6xZX&IivB%!954l}?p{`7Q}>S0<93XG4?k&~=4H2( z62ae`*HnB!M;1Y^Y;V_Jx7zbFj`Ckr_%Dgn9!y{~wS6xg*1fKqS5I81vTG;TjR76i zEwJ;N@-zN>@3igKlRSy?L%Kd+_ai0cCzX25wvp|MxPeOKN9~7s8rZ~4{{TfHpIONa zM7Bw=Tk-3%{L=8}UU-Mx4Lb2o2zGAWFYgLa@Qe414 zsJXb*@HmkH>khI%$S&SDxqZZ=Sh5?$X`M3__yXM|d~H}j{0hP${EeK8RQzWTWFSH-^d`Ay&L zE!#~8O9he)>u53Mr{9&2f`N=UiH^4d67r%t3DHnEd1 zmdCjmE9S@1AIQ%%{FCnQnBDrDtLNWKFRTX}sI-IFfP=^6QvPr&RB!zzjcx~HEqThQ@ zTDVD5?Ox=U96S8ycCpLS#o(^-MpIGX>+gj zmJf0}ORxI{r|`YO)ftT;-|oY=FC(VAkK63P<#fe}-BTzV110<$xRS{0FaV8b5>i5O z5n@hKxXrB9d$?rl0i|6VR8)*3ir4OWTK@p+aFLW0K*r=FG5Q$mexa=UO|QIC@xSX2 z;`fhq`+Y}UX0ZBuyd9RSQ8R?@t}f14u??);bc|MgwAke8_8PMx2L2`S)`0wi$Z6~^ zke%n!_}?9McZs-EXFlT>p)+qQ7WAkuiq^pPC1*KYPkxQMil(|YWg4n}hm>3w3 z!g{saG<|PeXH2hTl60-S#7actoJ@W}1;ipz{(Hp1#Bctim>m8y8Vnq3bh&5jwl7($ zR+p~18kzwDV+AntBRBGio%n+OHW=#Wh{v*qI@NlbwsAR?s2=_LzK)D1Waua(JrfJCQDm%=pix>u19|zW%j|~ zK>`O{rfad%B$yU_KmhJLOqTOhn|3DdTLiY`bEoYFDOH9N#{r7i*+CIRknq@l+(3@e z5w_qdXujT8DV(EUBbsAt)g;D5CKQ{8C{nj#)dWB%7H64m&Mf0I#v(eY?8~tQiTmo= za&nB;x}ZT)ZHz<|St5}#s|O5`kRD`YaWgRy5k^G?PGRb@+@_Pq+lqB9WYqPNSu+Mp zXXPX#CkYi0`~>@U+m!F|QCkOszk$b&GKZ$XjqH2WN_ny(2HB9#>Uw3H!1CYxcmDu= z08N^;^7N-THj#unz!ia{n_Tfu4ie9{s7zZGCC}q;#ztf2cbI{xR2a?M_2lw4EFqyY z?X@+?5^}}^SPPaBoRwn)hBpc8K_x+ir_K%?Q8&%CCCP|jfR8^`HTda?Ip{2 znfxPZOCN}={GDZE!x~mBv8`&>o+?ubg1KupDJAT=f-nh)g4_K}bOjahR0_>(P_FT2 zM(k7j2??~-t_)RaW<>sWQ!6EeaxYnNA=~15gzGEq>Lr&)H<2MAu~N->uJ^tmR-_`B ziyCN+-Y3FmDsiEJ`O5&r;e!sqVx!N44HkMo%w zhwq{f5Rq-1a3Th|HoNW>pTFY^1qy;#Ek{35`v|61b2A0M&p@inY$cE~;jy3i~+>BtokJa43Tx$z=n=LN?wfds?Du zYbeX!vl^kGwGF$`_W@;z4pHcfKJbQuec-u*{D*iy_@02cav0qVGgBjw?beyqcW!Pw8Td`sk9ijq4HjTRHKv=ad&9cT*RjRL`yFq2uXyUEWe+Y?-YyLrFC|EJD6EHCnQgai$ zZP6J>ER`41y^G0v24%M7@5+~nf|4(YKU};976ZQfavAB<+UqK-OmH?aY*8+?y0!>Q z_@VX-9B-}*YFcnd7CuYhTpL74?>4>Aq&T`XZ0B*A`(z?)wsw_fEfj#V7H?usSkr;1Xc+H4sBr(#8oH(i7A<{DG$T8ja<%ZlwG=&O)#?4 zHSrntjFQ-rQkIp0j3^*RcMYTCqcV%RQH*70w&vkjTa;>?B%RENWMP{~&+Lt;fn;)# z-}9L01r{yf={CNoQ=WQ#b!Al_S#R}17|4&h18DldT`MEmbG(d?&f7#4l&aU@?qlrP z%W51|_;YPU33J@(~4P-YqE9+BdKxO2ANQ6!zJtra!pD>CYs6FmKZYGgJDU4%zmS7 z!0OEIl}@LtZ!edZ;`JF@DvU}BVKvmLh5Hg>N^2mIDw31k5-<@FxEEMi+}_G%@Y&op zv+c&A$!R@zfOJ{K+0$8t6|6$Vhr(;xTSV4!J3E&ACR-yBxX)V`p-^pMvLjPb)XRV^ z*00-(r3{77Ax8zFa}4z-j7r(O%#h6g0IrKIB8kD*TvZXLD5z{jFq;QE+EXphGYcdJ_^eJ06G0n z`0qP6?yrnpqVi8dVf9`j_MO!D3-ti;daF*}uE@Tx%Zfmq1@{6|Cj^#kaTCAlW3NB` z*X(61qOz3TR>oBofWfis0W*AXh4NfR)3nLSpX{PwW@n6b(Y=oEXOi9mYjewXBT>#{ zw@t}&&1o!>8tfiju@Z1cUT69wq)mR+#C!n!{B?xXc?Q9IjoRM!c1>9wCxhIjO&O5G>P&!Z%!2dSn~zg+GMiFGk^qQj z$(Q6~u*`2W{>DGoTT|>uoBlfak%#_29Jh9#ypE=GkgoPTXQFj^X&>V;^HKp4Yb>mBUHBWr(tI2(iEIR9|8wmQltxT>k*XM0|1EYFid| zq@S^^Otpq=#QT-wZ_=B?j~+bU@-wp4{D$&-x=BOy9+fCkak^TAP`6X6l{82Z0FzOh z6#_&|nEwFAI_iHL{{ZwUA{8!L_PQR-MZoAYPOGn*V=sx6WFd56>ghF^F@ZvU~ ztO;x8wa9vbK^yw^i`TF{w*LU*&EU6j^uK>FUDWb_&W`hAUaX#y#$@!n=Dr&uke&?t zNvBr3Eeyn;z2<(hg^+ARzh5oB>H4#+C3go_PEQ!&f7N?q%VplvP_l)e!)xm{EA=(b#Jh6N$y(zWOXL3x)>CsV#Yq($=x;bL2OZHfA#o4c;%}6vedng$Z8)iyN8E7KWy~&12bz0 zO9zTjkE0`c!iXVLCp(e9mdfC@M18|~VDFGP-E;Kf*PbNy>q_^_wz`M8di3%XdxxC7 zR?A2;JxBPot|;YlaM@LY+?>dQ6^y%xz{G9V$$RtUho3!`)19xpdOfZVo|t z-2VV%Eec<%>;i--BPnT5T;lPfTqWL+*oGr{nA#&@{%LA&r~Zua>lxh-F*{q?Uh?QW zdSI|RcShrF#$O9@a@j9V8B-FZykpfYyr35R3`y*@#Cqx0qjmLL&N7PhM=3^hp4PBp zw|n#5#maW0w7ye!-$&}v?X^l`8j6o^sMXZDeP>}7+O$>2SEk70Rnrh`E#eP(XTx22_IZcPSYJl z=Z}|t)$?myBe~t^v5~Q+ai#&IG+sIzZyBe9gu|a*V6!`y-z4aZ6A;*d7~UX9Z$#kQ zNgPwdM`PLW{-4yt%I@)bD~jx1it)$6y*FmD-Nb3Sg_pIHvsZ&Fv`~VT*UVW{)BS3Q z5KPxE^I^>TckQ=%>1$0RjlJ8Pu0J#w%E3|kOH!1W=_=LcA|oSc;#ixKCp)Wo8G;St z_tusEn%-mfN5bCSYEH-Z`qz8>FYX?o)|o9)qSdanCPN>jvz66eve8XfTrv!@!4WxT z!!gKqoyTssF{trz-5%d#^j?4ts`8zr+Eq%$+wc*f1%l^&Td&)I(y9DtiFis#=bt&`I+?o?5~#kj;1>u zl*Z;r5Sc|QK`m0Oih^R`wHF_6xKg9#`(RsqL4M`fs>2 zb2{-Fr%YO={I(XY_e+BnX8f64zfm!~Cd-ykyC-Z!q6cW#6^lKR)5+9_+xtD0!|P$B z`z*udwG*xCNLUGx&mf4bla;K7Mj{y-!T$i|9e$dm-o)qlkCE1=7{8;jbm@I%jnx|I zNzk39(cSd#9!oB)ap%{HuFSSuGiJh-xTb7KS#cZ0*zJpXou+0(uU9?@cC+dc^wGq3 zvtQ@@Tg3Stqjd>m3qRZb-)lT`GMG%l$WCsuq^Lw4D{_RA1v^5-xBQ}dQQXZ9^wRBT zjNeR7;`uk&>G4ln1w2ly?T>YPQ;KD({j{(%R?63y%X68!wi}78i%VjpjNoIONp-Vs z^7%UN4SaCz&wc!l?sF$EI-!}0Z0%JHbwzjPELAh8R+hk$Lj7e}p3vB$0AxyIXpN3X zUH59vAH=;|to;4%r;}az?f(Fd`p%V@)%}O=7929J)VUd|0Ge3PGcl^T85PU`$nhB& zou}i;*OcB%>OUxZ#c#U0pGxQs*y!4{=NG0l=9tAQm0Tti2a;+wQn7~G-OPzS{sVyg zKty#1l|EH>m(C9L=6l`VYx4Wmt+O46rKjth*3%WGto2i%OrKel%M6)d$Jxk=d2J)s zHCD-_{>7fElEj>_MiF3#)>ed|Rxl)>-`yc45fd{7{(xByh|GyYOhx5rmzneC>w*Urjf^jB}0oXw)GaJOo%>QE(wqGY>rfCD)Z zfr8v;)?XjKj>7i8SnAy=8r^p^)m<}>QyS^Dm<2`^>*cx}qfnbn;KZOJCMIS+f8!%{ zK4(T%(RA?`jUSBE9y;D;IgGoctTMKCwsKG__u2_DlCdWN0TTqCA;uyI&u}kX27=PK zOddZMOGfCr)t6lti!*k88N5Y^^cF)SYbh=U0|o_PHPIfnti*nID2!XyUFg*MpCNA< zs5KTm^qIJFb-#$ITqh#H5`? zmrEWa>vWl#Qn?WriGlR*w-(RF#q#wUS1)Akgc?5A*X(3Z zBPf`jBM}1;96AHLJYn)9yZ$5V9@zf?`ah_39v`xLdd1the$_hbs%gDYqFk;~cBr^P z#C)1WMg%9sB6s7~{X0$OH;W!)X-XZ!(Kfq7;m)A#jui^*-)MWAk)uaPVsm9^rTVJA zCmuYq7DL;@k{J?0^*F#nTP%+`T8Ba0(>YAe8ir>Zn8gBO%v7sd!cK%pkJ~ozY$mlF zLxHVo*qD{b?-LU< zJpt=Sy`C74b8$J{J@ppv{&VV8tF$Rq);beFX}oqnM{25gD@2r7%;hUVEZ9nH+SxE( zp;8n0^D>UKVdX#57hZNOyQSpUh}yRy=XZ~EG7iE}%;A7+UC=KA-PJEu36rzv_6I8q z+judF5s}-h9{gJImqB?GuKVHNO#sJgom-=OM}E1ZSLUrg8Fjjo zGAlZWtdjePDzI?VfLzG@k3e}$##y(E&S5cHHz{{fciz*A%;zcEl-Sd=5;AjIz!1Kt z9$dfCZzc2kh|KR8{5=@TxP3mL@pOt zK}wHoDgd0;mpPr|tUm3|sq()WOTw`E*S#K+{*AjMv$?(w(fkY+@qC z7~U0z1i`{RQOfo=Z(GG!ms|Q@#hh#ry%?`oM1cDwPfwFlVaGz+J+{`02vgI zvLFYJ5L^0O{{Zp*)V=$}X-V$qmtC&zwY^G=Gy4f{$EAgLm@;uY-KNHhJ_T}Wx$7|v zgtm^mcd(u_V}70mqJE@)S@vSiu<~J{)u6C~>WtZ_;wz35^^1hEq{jGp71Lw>+ z9>ygxBi1W+`?Q_Z`rQ3MyOpnpxY{GPb#l~aRON1piS{&>3Y4auA)x`mcAdnP5>q>a zIZr5=->AF2B9&RXu1#mY4|S#edNJDudPML33$y)|?VoNti{vJl$9T)(k8AQ+eM5lJ zbfp#UYRu&$hGOa}m2)JjqFilkrX~%qpJ9v$f%WCLzrEq}C+lP6@#TAE*({yN!{eDt zPhjg*gdkW}3nBQgo8$@jr*K>VHJYnwU6UIKk`B{te<52nY;+CJi zV?}A)j-tnwFC(I@d)$d^1ByxKHfhabVF$m~06e8)y@~QuxP9UAQ|LkBhP?0+)$Bei zxY?UlJJZ~aFIvpyv5k_IoW+Eny1a~s+iwyx3rNI3#@$2THKtIEEaIN$-d&S^S=QPz zx~!DsX7qR)-JKufj*INidp?gHyVhDi4B)oyVcMSTEW3&p&0=;hguc8L*H0gs&1`|h z2<<P-Un8k_unt<&WjSD#kV4X!_K zTkit}44J?$rPq_bb!i_jyE&lzJ?>|Cb@nGy>nu&JS)~<~Jf#e-ENz5Zv3S@=_IoKz zB7Y%qK}gTQ#{QOmvc5rg6T&|4rBZq&Il` zy`tiV(L^=}c!`LgnEgMfZe83cTqw09`(-rOs_lYPRMBbMtf!ZQM>=~sjm%ocuNzHy zRo=&jO0+?|YuFZ3Nyo+vfEyp&{nBK_M#aJYTJYOKRW$jR^ zuoHv?7ZWq=mGYS~jrNF$$9+F{DUxmX0O%H^}ZvwzD#JY>2_yP-9TPW8r}tUzml&56X~Z3n3u4*GkvBu zB^LY4Pgl1nq>^3==5rLt?$@U4Id|mfe+CuO%0^KOuj~}?CW9)iMIOC^0178~BW~Zh z-K`YS&ZeS1%7mD+WYvLXh1WzXedbdt_Cb#n3_2%&jvx4R9x>NOYvn6t0?m6C%vRIL ztzhJvSGd232?M1t&DcNW&xx6lo{ME$bnnc+3~j~w)b2R~TUfg5i3pNVjLY0+D`O5% zb{jbqNkq)x)Q3)ED(Wi~kt$W|Mj;_mx+Gg;b|yE5@QH=Y!+@4iGFu+|!EMy0yK`Xi z*_&A>Vyf6{fQRl7nQ2TJ1R^WIt#c3}L^Jtun4i~Q8k`)CKE6Jct5_epmm+ex6unGR zECqjbp5{>IelFT)lu5@)@f7P-qLtOTcA=uE)T+W^y_N-SXEJG~MaBL_6Uerhh>n0~ zVL054yS0jf=O=MxoM5LCRwe}{AB{p7l@Kl(w!pk*CSdlDj*;bZ40^0iTK0X`f+r!2 zviS!Ig4nnw6hJS5yz7y{aFA4_2xpW|*JbQNLM(9pCY~XI7Hwr6hi{{GaW%q$Wd^<@ z4;ftl0GF_L-+qa`TFokhXDLMK;T&sC2tGHxrc6rbl>Y$yHu^pxOo=7_Q@+KwKwD3v zcq&$5zdKynOsmziSR61g1p@ZP@5h`F&;I~y#`3~+?>o;`i*aTS$BIFQ50@Cj?ElZPNL6zlbZ>wmRnxtoGiJg!4 z^V1{4=j~1%rG&)|V=y|k#f1@3Cb>8`m@U)8efN#0efj}M+1z73!MKcCa@<_kSoAZC zp4%cawN|jL zTMB*(C#RHX(9P2nQonO5x0I#PiS)?DIB=n>fMBp}gqvVw}#ejFZF;s42UaxH$HU8Q? zEorP+-bAKLK*~l4B|Jt4*Z$^uyK)zD4$R9+&2}P;u#{Go+;y~s89*VD;FVWIOiVy= zmKM@dQw0$PqOmHIiu}>QV6v21Mn=2?APP+jU3IzxoTdN^dEzijWJevoI$wVDQ>S{J zikeR$r|eYSa>(@6u*I%8rI6~|M9WUJC>AhVn?Eg&pgQY0kJ9;Z!#@2jABVOS;YTm3 z=o?!w<`}7OtCHd-0tg3&>zIl7n2vSan0+;F&1P4}BQ21rRg+v96lOovAIBaW$M$a% zF*C+v=lw@I1FJFAYh&Ky#KtCt$FJ4tve{jlbfDN#3o&4UnD5Vo#K-3!@$pSrOs^!7 z$S)U-4@G7@HrCjLeY0oPe31?Q;$)&hkiTN!ra8n!L^j4_*H)@sq+-gb6UQA=)o1{v zNvs&*Xc+_T2###rcK-mvC;jvb2DUkv!^pQLwO6TWB{;Op8Ipyv6xXQaR$^ragWHV5 z221jvn1DWDzSA1IMUh^X(Pe#7yt=H{KX$^-2H#_h_h2z=fRO=`Sxjva`=MCr%-YCR zW3S>Ty~L18ARyso0#a+< zW(W^`_xA7mnVBq842D}L{Cl6B#Gve%jf-G1z=N1*tZJHxL>|5&?BpCEXa4{x=mwv4 zV;f@}7)!^FkF^0s++twC>e@L~8wpvg9xy8@11LBWT+hUhOJx^tVro;UL1Ng}u`Z`> zpr|WBIvT@cVUWUj$f>2kBw6hrnV6W0s@Qfps>?=Ftqn}20|5fsrUONcfSUfV$#O<5 z35Jj5xF7!jj{QrFE&l-N>e*`9#?w-2yPb>T~O!mEetqg&&d3NG5Qi=;Zc7$3(m1nd-iti5oJD8mCF_?|we{($ntd8n-3WD$B z9f^Jq6{($Cs*LhhT~2Gtpht@$QaUb{gs}$K@QRI=|f%%}iMf)Iix_2!`?#J3x#? zbC~}CbI~AgKV4}a%6UQC94@}o7qr%}(-|~N@H&$STiLGBkA=F(PxO}_6DT zwWk?wK(Axs37E|MOm1NM{{RaG?Z!pCdBn+l{<_|ujXzMH!g*Cfk8bte0*7aN?E1vI zcnrg(HL}i+f{J-U{82qJ3pPss0226_0iX39D*DoWK)m3y=Wl*{8{A&x_kYL!+i47= zaoP__>FmYa1zS{i*fK@-LZuqk3O*)HR0z*b5I zAV-`V7R581EM{K4y_;=6BQw=+sWhthH6vO$l8W==+@H`jUz5z|9HTEk`0aPE%ReQ& zaq=q{=AKJb_ix4I%}h>^)!P040CG93b4Bx(qT7y+SsK-q_T>(2NUY6*Gx%*9%<*Ty zUn)GqU0Lz}0JnMU{{Uz4t;pl>8m~}f+l|5F@yBhk{{Zdw4hgbS5(ZGQ*x=%Rck6FH zBl$Drf7Tzo7Cd~`+GDop+cY?z0s06Ttp6z^|q7xK2Yy9eKFq;tNy?4Czfk$ z;*V3C8-9u{GGYp--t;~KSvw4e+>B2cKCf8Ib6OzmM6!|0|9y`O$~xsQ)I!!WiBQ+ z72c5CLSi^2V7U#5&w1HXl#`6oe}C$E9Od-Ro9FAQZlzVc>e;%92^!H}%(IY$ZeEdzSU9Cm5omxkX}A0V~wYdo{; ze|r0&+56ZWQ}J{=g{!PD(cC;*C5KZTmV$|~n6553Qr%(>7Cy)rh>71^9p>-Ge_MCY zxVq1}x|heE;`bLZs4^7tI`$7 zFI0Q$>Q(ATWS<91WAuiIr-H@dGzPU4mR_`@FVIW;}UfL0F#~z_{lx{?S7h04_GHBpp}0mX8~PN%OQxrSs!!3townKsho+D z*(lkO6Xk-&snc4j<8j&A_=Cuh#082qRgbc%jiN#s06xL|W8!D^5g(|IvV+6!@9U2k zyphoz=umR zUD5JGT(ih7`D;wiclFjyCe&MFMRh`~85C2cN7hXW=q611B%^tq;y+W>?b?h-j@B`m zi+$y}o?XS+l;YER)xFtBk^RR=YlJpz6MaH4Zb}sZTz2I>0gu-GN`6KwgHxzXDw!s^ znX<~k69&2WG7e-RV1C%1GrUB6g!Fb6&{otq%>5+e+?C|icCAYmURY$0D9< z7gH@$9g9LN8C$n`5H}-fOfc6RnIH{_DEW!~d`B3bfXxkc++=B<<7Cy9*4a%?Kgqq7 za@uyuD*gl62E^B8Q(%rjW0%MjPXQ>}f7EnUZDX&yr;)LzuP;jyaiRQ+>FNADRGQ&C z`&bCCFl@5PS`C9GJ4h_2^%K&qNtnp$&0C+;nuKurXD(i*sL)UqO`rs&EioY_U^WqH z$rjTM5!>+Vv2@n9{{W%S0L)@24fl#1TXTUZ8RG#l_;dn* z&uRQFHlblg?uc28(`?eWYNeuh2fAw-M52AACoVQ``Fr-6nThMGbq1@->I%v&MvTpy zkxh=PR25;6p=>X4I3tiKk=kUZ=6BkET^Xx&7NFHxq-AwwgQsYbEUk`1mW*Z{kP!_~ zizL9efhqlR*#7|c)sITPJQr%Ro}5lNm^D!|TWMgfHIs*2_ z==|nrYgNNzk(6T=^wTPDQWro(Mq4hEF&X0%UIB13v>P^`%44qZO0(E3Y}T)hR*%h0 zhEC;&9a`mzwmZ$7imk2)?N@BJMT&DcL=15a`AqedTDbiio71_?F`dI26}`NDi!~t+ zL$;A9_><&Y#K?~E$CmLCzVh!6k;kqoWRZc=`hrnp^42hFN7y>)Zzn8sY!O9<#Hh*! z20}O7eEXp|R`*lBUU749Dn+tT6^4)Flwbr+DEL69O_@&8La6 zbW?WC%b7;u?b{w=U}zB%EzOhoku%w_42*0)hWl^4&uRB==8M0nE??7_{Y|HV4whus zmwT5q8pfCg#T;b05EKvx;l>7k-1XC!H2U9lc5#@fc>ze*$Z>Azj%)Tvn`UIT39wMX z*p&mg%x};PZsU_^{{Xigjm~|s@hV`1fMdjF2nMh_p0LPiy#tfKjLlq@87~t2vOlL9oBbV;aZhJ?O)wzJv^)KoGYVq@J!Z1{lYEikq!xCILwkRTJu;e&IWS@ET z=bkVW4QLq9?gw#nF1=0sw{zD@-O0pbG|Q2R=bN5} zM6E#*2UmSbbdHSe7j)=$>$V-1*PXuc{{UO#XEM!N?9cM~-E}oDGMcO|!-gePkk88A zIa>o}6xoU9J7I<$7>iac>blyEIjkEDNl&QrZF|gc`=UvcyeeXMVFMygIYdnHfQZ@` zk+{8WqU!jA*srTkcy+&u-TKF9`#H|ocLta6+07e@v3oDItg?KBMn8ghp2#b4KP<6ma@7);7$P(oqRSOVwG@<*H%>lm7r6q{@29 zKc}B%d>`{a1N8>co!-}Yy*uSjgkT;QQDdw)V?}BI0JK?ExsIeI2y6wfXd0p*OOVFV zGxO0O{A;^A*iR?)51DMcTw{nSrp9P&|W9Mnv zyx{lv09qaV1>@Si308;OxqWoFb-b82g*Zn!JGZl13x5sB^DML~%XI~_x->$O; zPol+>;p{2lAQC%FM_sqr-t2dWz<)M80qn1wRJ(2CJn5Y?sjxNk+7AO=VcZ-e%^7QPak(76oYPRHSFd9|6xFqQu_sZjCZ<95ohJn)u=UoOn_Ot08oW)@zfum~cke~` z%UfG%bmaBcgVbHRx}7!L?NDif{{XYo{{V2C*zApl^8;;TAvghJR9l&rmb_8_0OV2R zcVM;tgwlRXUDN&B@!J@L;xf%$`u6p9BA=~eUAAm0Al}gdQ8SrIn;_(i<|nJS>V=!` zN1i@R_B&Vj%jI`(eB{vj)y$!yJ5xCl|Us#zp@C$OF5YA5G-Z*&hUaR_wmB$$?nQW$C?+OI;$k87g$^RU(Kf zJ<07TncN6w1CeQ8x?SAWec{&n(fVqUrxUs`)}dDdbQ_tJTKB7QF)7{^;59g>(r^c1U_eaE>bF|-a2esD%+cVi|uaK7H zD&lHch&BKrYIN7KT%e4_akmKSJLD+Prz(`And5`AtvR%+b}`?zKTh7%c(0(eN0Yx% z&p8?4HlqZmJ*PCbmbo=`UJxW_)hA>|EF#P-rZ_Gp26;~Vkw;qy#`boHmEDcWWc)Yt z`w{h4?I4n^G<_J+$mrgz~eqoy^G6>}GpXJ4og?Qp*>%-a{oqWJ5#h2jE8%So2=Rs^PS*}ac zYvidd$Vk{TGaJV#%Ff638@hi~FQ_ki`{US56@J}zy3cSf>$}>=QBqs6T5B0LA)C2O zGFi63B3Z_EjszRTK=0OFd7s>m1ANQ#BMaK@$Lh}>d`r_>TODb7)4f@+j71%7d^o~W zQy7p6%z<&sBGHr-^5g#i@W+3nSXF-l5~#Mz%JH9ORBFOInu)7rA(b-inNymiZVmlhn7{{Xao$O8y`%3Q%44=9k75G6|>--_k{q9c@b zA-XMab5ihI_XdnuU8`Y0Eu6a4CnW?Eki85cK-Ym;?-4d4dCt+Ymm5c}IyT-i&}Ao4 zS*P}mvR`pv_=mDA5lnjm)K}zgl7cxIFVRH*0Od0z1MSchUBy+@ly5q}+0C@USW65@ zWWcQ-vcbS_#$C=iapSk)yp4DGYBs23veRJkRBc2y+-cUSb=MGLuu%~K!eq*0oDb}0 z=i}o*E`5r1Xpip?ig1ZL#YnuN6uy`?YBkNg=f&4^4{{Zi4j;o_b3c_pg7_4{l z7xD#NSt3M&?w-XgG6lrM@c|fuk=uBkzu!;kV;<_Z=L|Uex6q_lTp@~o;Br&$B*{s$ zX(Rstx#i9$@&5qAI{1t|6AXebrkt;m@wJAH=_{*ndl@T#u_i=6oSAOV>;^zgY!T1^ z1k|?~`;_is@02PlO+?wW>MRBbgsUSKfK*7Bm^nlN2H*wrKcv|DH3ir)w~x7$surzF zL+vhBR#E(6a&Yj87MVcC(tr5vAFiggh{DyJb~4^3{lZ;Eoy>I=v4egMp~XuTHGgao zuyG)W;U3tHx1O7n*~{dzc}!9)=e268%O6FQh(QH5tXEP}p=_DJgg1*zc^L)FeutnT z$;D;5+V3w9lCracSUqxoe{G~3k|wl&m;!^D7x_etO#E#hGI;8=n5?yIUE3JDga|9S z7Dyt48E!u{l<<#o;cyc>d?|q&?K^bm4MAvIZfQ4W@mNqW8a3&Q5Nxhq!gRbzezSlQ z2{fEckx3uSpGzPyKX0cQg{6q7!>2T^+^Oh}v=eR7lX@*ZEwBiY^|*xMTG(lGm5gwhf`-7z>^~-rv}1EuYgrtX7B11;unV^e zyKCVTDBh>YLggCfUvSoGN}NY948v-Xu%+Chc|b%)(J{9`L-vS70*0+= z#y|vP%{p?^0P8@+2HWw7+i4krjysIc`<}Veyk+Z@XjdE%WGuruGUbaEUedE`l);<~ z@g+yZ53IMCk(u9Oh>mmzS;{g^vy#kKPx7j=ixA1r)%&(q{$vbhXqaF*KJ3d*?z*J)1G#Z8Um&)**5Ap;IEw(wIT zt=Wu)``2t|v5U2_4Ty_%0INV$zp2JLpnx(y{QaabFeLq$&SewBgbc>>_R4FfY+Szl zYw8lt6@6DhV3~vBYxce;+NFC6PPxR$`+(Q6OwUabcHL|BKH6ODEnjEYsI8S-HPEpU zHdPlkETrN9b|@{}xhdXYraAx?-l>>|*|f>jw3?O?qQ!y+sW1RFi+Fdk7w9F=B}@zX zloWgyUoTBY(Onz4Csfmi6K(a(Vw_6VxX47*E^-qD5eSLqdu&^b4^*Qwi_>jIY@TNI zHq>J>MJO4H>X6_c*Cs~AvQLrn34w_?+Be>1o8;YQi|u1?P)&na0F*)KO(Tv zD3{L`PQ^Qn98dmT0G24Cjvp9{C=N9B;vtU-=kh@t0V!OT`zY*P_11IkPD`Iw1a{8XIBc?mh?w3dsm^HQ#*MoR)0Wp3iO++mxdkd%3*UPwkqDilHi_l< z@4w7+0Fv5Np)kgMwE#`F-E>N3y$FU0JdY1h+1-nAt78y|hX{_-$Ts+h-=G1Qs*mA~ zH!EW>^ehya=7sGXQ1Xd$0#X7FIEzXiCG#P?PsDA|HuTjy>9}<=nOcQzs@rjxl9*C` zV4`b%9HdGcBD0A90LB}(-5ZXm!LByJH#F^lvNV;CqE49}5Fo=YKt9Qxlyk_o+D~tp zo|}`V`zz3Xpu1C3jekNARpAH}@?!U3RcGsXQ98zoJa#YXX2sKl#wS3D2O1stK&R-kb z?;^3fi^z`B(*qUfYeSDw=|u0w0oDozZ`FYzm=^Lcf*tk{h}||o{C4vrJ+s#d* z`-`C83K+=af+$HqphY$~gAVhMQ{ zIfgoY{6-id3-y!^`^4;D@rhM*{{VRWc-L8e;P~;X^SB*m$Qw*$Rs@czqXazDW~7v@ z=NwF?XJU?XG5g=FVH+&I4?~@X@28gk089M0b+spAbjNNrew^18>SLc{H;!wWii(qB zQu_Y40kQ^c6zoGI1v5Xnp1U{cgPgD5ZySE3z7tUIMjy0ZPxo0L&S||%V#s6u`qKts zhy#d&0+x&8*Syab%>45C!LJg&sGX?pZTx>|{Di<)?H6{O=1@xSu>Syn%S#F;jTSka zYrkeMl1?BunA(3Sh|G@ocpauSy$RR)2KGxw>dbk=hAAMI37Pqa`q0Ug%*P-5n#4b^ z)J#mzmitfnntuy+4X9O>396Cj2B@^h{{S8T0IRlNS5IYcc*TIiQ%KD#8p9*0sKx|p z@|Zg?BG_|ChCllF$o?Zgxt_gKC&ygxXS`(bW9YxzO=CmIp6h2R(W~5@MRu&+si*XK zUuCE!ZDFdw&@wB~O`c|lB!Lqv?qMt%k-uSQ+#@(agL0=}1h!ScJre%Ii1b`vwFD&{oG ze~9CMQDmROy-S&AK2F7_fC|lywI6w~h{%Z?PUA8$zJokP z?ibP*$HU9_uelN3-yl2Fjnug;Rwqnd!30sYj4MzTavx$l*MI%Ef%}=eJ)YQ@{ZCdu zceTHaKTFQi_NU0dIQv_f^N;Eq-dc>+7`z6iZ{1@t$}>q5FEO6kV2qh?Y>7m#g5n|< z9Zli))qCmh=ihL9f8t-4Ur&C`_D8sy!Lf_N>ODABryr5awc83|)vG4mCKwoO!Xh4H zJI?bxd36q^QAtLVlp^1^-wVmD4GOHODR}igBzYC(){F7y$BVvcr(J6t-Xk}qsbhOr zpjSw7&2~o8(br7 z(HC`}kNM42s8LiqXN$IGyH>7Uum>doY6=r-cWMwz6bwt51*8u=dxPb^wDQxq#pVsF z`p>&Ktb#Pr=;5pPk*5$sED9L9h?Ya^8mv~a?NCeK4+b~(Jy`56<8w+is4PX173n%M z*(Z}4t#?l+m)3bs-FIINp>5Nw(ri|vs6#Cn(Ld~6c3nY}1-_|T{n0%AfX(M^y4{b` z%gQeWJZ{7Hd$gVM?PZ?J>n`Eav4<}1w%v@iXX7m{6d3CxY6$V@f?<(Lb_Ps|6z?3O z9~gd)8m|T04A*%4jH9H!pT0Iy^jOMMuY!vjhd*58V3gX#O*(+@V1TZDZd~qOk>>V>MH(JYMg?nN9pV(=iF|k#;??NU6)gse4VBx7zp zdy`nllY(APJYD1LTl;;kyr;|f>30FH{4ecYyjGsh_YwK@7MRo*;VNX}>D+raw`?ZL ziV}_5KQqsX4&57y&Qa8r^A|%Ij>aysmloG)AvIP_DdS>gjh4ZFi`TsJf(f7BS%KXT z6#MDh-7DCS6+EczpMEP~AFp%EWh*>E>vN$LQgp9`+ z+oL;}oi*Ja+xeUI3houH8RHj?I%`=EXZtDHy&sOP{O(I7Q7D?#3{|i&6;}0o7Hqeh zT;{SQqE;OYmc^#&>esCTBOJB?Ap&n^(z%jcak9cA2FoP(gvR0{A@S7p8AZ-pZv~5Y zZ9XNhxm}UMeNhL`)DmqOG35s{#%4C#ao?&nrj_pxj=HZwX&(M*JYI#(WVGHdR$y^& zyqDd=V(-B=t6f;w;jHm$nX)bJ$Re5iMpxBe%GbzNX;c-elo=x_aZIr-bK4Nf6XHKwLLGn0jildvJAOdd^`{Ru?>0KTn+T#EupDpQriSO?gwk*vd1 z?y-j$AX*X-sUSERiRCl?_UXuGtsXA3u2rJOopP4hpjG3QW8OfNz01`+Vs{<)i8B8H zpO6`48=K4`&3vv3lCZ0Fd1gihiaN3EV&v*ATbT@$5EO($%s_r8=XH4uUMi7AwM}%; zO3U40myOSwLPD~XEs(Fba~J>+BqSgra})WLbsSv2M}n`6b1Pi9(6L>05H=^%5yWb} zWU>K+h#8Xq0Ky_BI=T-Zhqe~(BK}T=fd-P;-cG3H2$&pKDOj*u4KN*wV?V2~Ut#x;W5pS%PTRym35psbvzZ}K#7C?8qvLs=t=(aPsiv9(i?%9Rs!Gb( z^uSV>-}>9?nFD76f|DJhVVh6PPWSG2ESyc-l<`>~}@i)Huyo3?`~X8&*dcx4Lh*pHKe)E;NsBe9Y}9bM$qN z<#?stuH56n`h!a58pn+|h5-$~XDV<{uBSKzQ^sV#xQ_RJlU^cr15M;HzEAfbzdg3| zlgr$oVQMnv{LtlHr9ny+S4uJ$LVcO^&1n9Xv1L{S)UaGkn=oU+j0TDNC3!`oJ16BY zZaWmr{md;qhCf`ZR9m#(++rGsebzk~=}DWdv5Vn05Xggu4)H&iEv{X zVf!E5?$!A1q`&DcL6NVC$ zrwfs9il0;N$m*PLYIS3+KSXQW8208dFKmPpn_BOxY~eC1IA`=k&jH~eat0$FQG2i5 zZ422u`jfH$080!`W4S&A1`6H_ROoK!WiRRqTJIpyWV29WYFh?IF3JV<#2r`C))jf@ z8wk%?E9J-3-^iaUJ73uj&1!v3qI+MZbiNB3TA9B4w=z1vHl-vY?W~(ph_6|YY9dDx zBPl5(C@2xup;*Kn^)oj~nj=@jk?FrrVW*RP3``ScdkM!WBaQz6P*Knu5dQ$z z+Z@-H-Hh(ozhPn-OC2Kr2|K#%2TrZ z%T(#RT93USO1kguhnTvlH8RJF(dny_c)eySi-Co)CL*8{_7g4=!PuhDB#VW?;H`?Q|6 z)7XsWpT3{5xr)oBcBooWPv$KNi35*_pP1Wu`HlDKehV3f(sb~;BT4C8ewx!5dR*#K zt5Ha)K_XKEq=@i^{<%bs(>wnF>!3e9533K;%g4{9$8kFWV+D-Q`B&cV>eI04!D0xo z@3on(Yk*>gxqGIgO@uHJ6B8*dbH~1pM zoKChpB|NGx-?-2>i>k!AlU5X(>k}x66J?E}B&4Su{9XF4`1$6)Yx}+957Z|>_ov5B z@Z85){#3MvS?a@Ubj{JT_BgVJjH%qEU;f-t=&%IE%ueMU0h!)1eO0>~*uNolwvE?) zvDTf}?bfZdtZt$5_dxd2Yhks{tHmt|$QD5~QpNqPSvtxaz%scH^~61swap*cF8KG~ z$t*9HzDVlrGfzZl>vxse9SPh0S8^IQ=J4*)P3EZz}pLg4!sn6}jA7s8%jF{(8)^16E+ zc2u*Fw_ccis$L@H8A8>#3j^nEqBhItXVi z=5)LDZ*VZ(x5{2B+M=Q?DGFVeSS6@K*ujZ(544AHnc^c6b?d*a57WcNyTRHY1iqKO zitl%9aCRpH8rNRtDjls&Dk)Q2MMk>~^&hBAUF;Y#BG@Bs%YArX5j&aKPV{)G^$_qo z!(5J$)Y{`tT1R{PGgneo$I_>Zwv<@sKx{(RoPu8he{L`!*pG-3f+^A7ulhZGAv}=R z+M8SW>Ge?3UMcCzSsN3P?WU=ziu=7cbXrkjkj0y6a4lpcAQGm)Z7>HR0wYV-=*iUm zs``DsKO%oh`BcAZXRl-RH;?{gcv;-9sBhD|witgK`_ZGm={?Wv)vRy7M(fnnP+hr% z%390HzPmnn5r<9*hzSw7UZ;DyG1u(?oyOEZP#i??Z zo$RrW(-mw7w#_IQ1cL0$LA7t%BxGiLCsB9f>BIEi@TVvA`|z8(nuouZ^;Pz(xEjX} zp|vz=+=M4Dlx3NTuG>XTYpj)TCb1IYQ3vyxn&-;zr=BZW=&vKSCy_dL%(O9bE77d{kkc%}Qf?vFO38dW5n zGSy<2P^@ zp39^{wInVUye$>S6x2%B13NA^+@>UrlEayvU12?~Dcv0fggani3_#dTX`p5|KHg7#53~jU0A-M6Ux;7|mY-V+PFW&A&FAsnW_OLQBW-N4TDLTAQWbj2@&$ZN zlM0Ab{xU&agWEhx3JiCj)NQ}ff7!04YSiSiRv|*=GSy#51L0g53P8^jiI;zYMDjIH z?~H7)EUO!NxOHN2@XG@v`ojZWM{h&m2-Oi1ZBYb|?}rvdZM^j$aZfy>;&Fu?dDK35$u?aw;1VV*4VKPZO7ERiyVh5N&6r{#Hoe?F)3=@Vh(0L4hScV7tGA{ zRZJEnY0}1)BRO;1U|Do2s6erU_W?5xU>r;t$cV&oA_$rJ{PySrs^gUGi|Jmj+rf^C zOvo)+IoVj=EFfi-`e19gSjBEXEg_i_nHU&~Dpku3%1W*(P31TPD?;tUIO7o{78mMR z2}HJk$A5uZqyGRA+L+9vA^d$?HLl%INxH)f6=5~bW=bR~H-kzQ0MVG8!U_d{mESCS(X!7;KU6AgnXFUxu3KLRlTLZ=l|u|mD;)Q%#ZaYf^r zmB^TKuxKDiiGlo8mhGpwRlIGeeime9#$ubcYi_}oKOvFJ(@=l-qb#7zv%sQ0u zc|2=ZsVQ-7i%KQF&M8dfQe|XfAy$cUgw2`U!Xt+JM%@4Y>EhyzT0g-bhD}VXO{mpAA1DF;B zOz@eKf|)7bXy-sD3KNtn_GqEjs->zHQU*l6#LGW5iZ_XZGi0(X48%YgM11nzoA}B! zYmvC_SGQ*I)W_9WHOFmNQ zHe;Y2(yfxSmyxS-?b5AgCexngHh`&QR0<}4?k!su zEFjECg<>3`ez~8S=qv2Bwv`oT^K^46uBEEOE^x*zk|J;mw94=%Mlk~`5#hW{{>pj* z(ye4OCN?oMgTIYA`wDohVr-D94q);jut|bZ@kvhWIE{{CBlo&2g}|+ru*`LbWiHk> zJ*#uT5mY_X#DYkKAxQv9Lgamfa(_E<*vk@(qH}7@{eV`Y#b!2iyCmADxa}!m$SB`4 zB?7-(@QtP?^4c9@*=6}f*9Pi~^y7O<_g6Nic$~~I<{$-Z7+}N((<3py{{WZ30UgRz za!Xc2F{Cqkg8h%bY0g)qa|=kB%%WN|6FhfOPVvSjM`DSasTS%AY}2^7!Q?@f`7Zj@GA-u>3Q7lwEH(g zTVaYQC`DL0fEFc^g{DJ{n$|-QdlU=>VQis$Bb>XO&p54DTuoL|6*2aP0v&CJCQKCw z408OxBAAJf$Dr$0pfQk)eOsmXjgp8!mQuA=k;H*lkX%PLuh;E{G9`YXDgDIs0d{QF zU7XGjCUcIY7dssG9Bm!-)-+W1J z>;9RY;si<}AfjXlNU1fbrtUj24rI%%@?+O47O-IDDHW8qBxE9gLLfVSx&gf*s(8#> zvKEt--+$K-5OoR&h$ z#EGk-y1~Y5E<|VBAAujUoH954&i!2%@@%C~5k|P#!dEodZ??^&tka)Uwg_ZQkgWI= zOz+BLai55eplsz!{_3_NxSFvf+-lJ#xLM6|g?+SGQzezvCPWhkAqGw2BRq(J!T#g+ zFA1u!?2HaaN$Tu2M!k8(RdvFus|zNm4A;2)gqXXB>LYm=h}-9|d}#CM%0C41*i9R# z>*o96*vfpYr%&V?Gn&)!G70C6y)!1jA79ORm|Vu+AC&c$`8YpK!L~Z5DrWGEnOUUE z%gVxH1`Gu@0%`0~8b2%W3uG?ew!d{{G@RRMT8L%b&^%VR z494Un&r=uanI3%RTaxZ)YkV7Z)1A`shtAz6sQZPXH6|ZBZd1=KO4U%Qk;d3jPbFGN z#1(eTkntt%6Y)R3T{H3XxjKWxN}bQ`M{~P*s63MKCs}FRI$tG-qmw4*^mZ1?**0fS zuERdXh7!PeDgY$qQ?&2DUTkdWJxSZGbEf;T+Kp+S?WVk}`xa?sXtYoJM95Mm!8bs` zOBhC&Fc^p*!arrS9~M5S`d;Qo726*xa2U?hYL=UEi`3P{hl9`L1|Vdti4nzX4uj-m z96*GEcHT;7XE@7@C-*g0?>sykSnf}a9y5Ja{AcWz1HC=g?jDEM-Jiw(0MXh<$SoPB zo2Yc|r@*dY5*d0yKFU{;Dp)$TgAxY8x(kEDtCPY%rnl2az`pz7d%3N=#npaxd1-+^ zztOr=NNA?D_=hsP7Q3T@pcfd+yKpr+(-M^wLHtNbO|z-{RhR9?wxQ%_iT&5g_G7%w zRd$wNOp|y-iF#8}cEh-xvF#4A?v2c@ zQzlyLQw`zBW!%>OEx3xqAabOV5U82pDN0l^0v1UuPn8;e)?InIF z5?JpXPp>(CKkC1zw{g6#?mwPBF?M6T57(K!L6XWk+O(SPV#bYwg~m0Eu?s}*w54Cv z$ZQJ0zr=&9%e5MJ%0H;rm)-~KkEniQS>?MIueAZH4~;M_({|r}d8U zi^?AreBAB!jP6E*)99&$Zn;)Ay+!I*+FPV%P(08%I^Lx)n5l`_mU~3cBGq=4`keV2 zqx@m+hl5?)$@aU*UfxLE(VBlN+!YPnrkP@GO)+(6u;v$?< zc{y8LMMk_idsoua?9=f5QRCEfg>3gJen#Uw=kqhLYVeo19v5k!DRpPm1Gze;`mgE@ zdzG}0x53QYNs!Yz!V9en6#gkxY!JzqFVAT6af|Lgi^%s^v>LToe23WST~mwH8Y>)( zJ8st0d8&4n;izgI##ZSWHtZX-f6hua+b;YT@GHJPb(O2#sJWx`uVC@HFW~h~yUXUP znsAB$1~GN%je%pV3ar(cHjJ)He|yC3>aW5-q<@OO1ZVqy+)lyhYaQe74oacX$aiB} zWk&6cE+tbWOU73sBvTV3Wd8t2!Eq)*5k$a^iE>3oSv*?nzVl}^COhgq-#+H{i&XcE z>Tlir<~K^Y^&fdWR%dB^n8A2u z+6_sl{F(9}O!n@Uf4liS79m4{(>V#KPqKvC-W3Q1MOkB+GLs|V0xc8Y(Fd2EtL@j- zJIGG+_hzSh{891W$Bh$WG!OFG`qJF*a4Z3X8*fa*cr6B~SOwD0pfUlp-1Pq~a7bE;(6sh_q{ z1b}e}mBQnZ0>q+sBMpe=N+rZ2iGndSO+8&fp;hAh3oA^@|PdCU;Nx-P#{2r&VI|J%`nm(Q8E2&eCNp zhIQj$Q+Bm+B7!ri5ClwI5@eWMN`86**2X@{L!Mgy0P>GIj2mTPFSxdBqksy)0!0!f zv~ih%jsrV&K2sr3#>E;~ym{iQUm9fmi-ro+ixP6RETRoX$`5#fnD~#GpNO>S1${w` zTkzL&*@~fHjkUHRe$yZ@3|TANx$IxsGqA+(`!CZQceE2nOPaZG|0A%$^v&O z+i1P}Y1!+ZS!=|2`PmI$pzyupW|YY0v3hS*0`x_%Vfh_#elN|LKD0x?p|q{cQV0fJ=h z9FAuvwfAWJgYI@N_tNve{e{!|yXrOCZA+)E_8Yw&tTf{va{^?$9-CPdv2B{dmvaWp zZi6C$m>`+x1)Zn8VO_)QpK*LV>`!z2Ec)4Y!&Xx5hj9CIg;d+acS9VSye`{ZNH&-p zF?3?!^MDy*-L#uv=YIXH?3ZXhkoBtfce_2V?$>j>*WN+Y*==F2yK#&xly=p;Me~co z)~=pY4m&nMj)@j~6$QM&FOF{ae_!?owtCyOzAfc@tK1(A{K(YWP%)Zcy7hF&^4Pog z@-|T0b!+8vYp{!V-s%gMwDxK6RFTgBh}YMC{;2)u`epVjR(OTqk0|tCe?Fr3a(1#9 z?DbU@v}o)Ffe5Q_GLu-QZAY!;6+$F7CCo?9$QvQo9kB6>$bSU^{rAwzi#Ms0lCZPXIUYh^caX=V;VhUV_=19w4l(|sI-|3F&F{~Ln)f5!j}yC#f$iR> z%HLi_>?;}<^xm@}mMTX%jUg#Wk1~<4BP0aFnA&%l19qN9_DjIOr8kV)lS(tS*v~Qi z%I@wk9}U&E-D4G|=?urOApDeUR7^lcV&ssygpdL*3K;85SPI%dxHxL~ZrxsdYH?9N zDcY?^ZC}i%fD9eHBaNP%ok4+y5GnJJ2$>^PgsMw?U8MS@_|N4=gR3kDj|1updrO0z78#Li~ry>h*brZb=!g z(P-;9V|6T9?zvW4)XYlZswPNBG3F8zF+Z2U9(1%VjcaQ&r|=!5%AT`~&OsQ=ektx> zy>^(vO36lH5Nei5M3DgS^~`O`B#YfY)3@ofg7C{tR@FVgZ65G>A(8pJ1YtYG?Y~(+n!S#~WAl0aK)QHpbfE0svt(MquC$4AvnFE!!Ub_L z0~-$Wx6IF80e+mHR1W!grRGhX*1e^vyQ|wwr62lxRaLEyD|t5rnL4lW@_(DJIlk4Y z5W!sR(r({@b+qiq)d$G`048f|4JX`vci7I(>Fl0n&ANI6M{2YyJ69Rs>jK&)x3yp0B-|Q{Zl@k+CxtcyUBTT*@k0n0oIAe*k(oc7*Hj`YAAP)fti@w z{m=aM;_cd%MGn%XpdF+@_X`DYETdmAj0JSd5Lyo>g5(64r|tP)7M=@P$a6 zL`Nt-yIafe33TQM#+^;xj>KxR(Ov%l()MmP_L0u%M`d*8u%hcT73Ujbu#JopD=46g znaCKB%KrogO z`4n~RQ|Tq2&Kih~LTRbqtc9(X0rr5&mXidAOo+ZBS@G6x{UEf@Vle*z zQ|`}qUtHvLH)p$#r}3E_t|tpu0dpag)b<`Fk5zJAc=S>N`=Vf+#1Rl}KLR^-sl_~v z`*}T0YySYJr(`^X?w+6WU&wXnzTNlB8>){#p|AGn*`u%Hxq^Tdk;v9@KQWRt)#6Sv z6`**CEH)x6PmiWQkbWrV{GswM!%re|_>TA$o4Ms))sXDf)?$mz%pMmJb153;?Rv$F)09$htFELG;!(B~tGS*`{ZTwl?`CVjuKadO$6mqejBZOwX>CW4z+~U7G5G{qYF^83`+==h zHWBvBOu$PZ90k1c7>KJ%Rc74ZW6NuO8qQJk9uGD@QV*$qs``N7yHDHgM~K(jTAqZ% zzY(vncuh~W9Nwr^s>5>d*rY(KRp11;7TPp5B|J_+`NRpIrAjXlbZ z0i=*s^IFT(Ud9^JED!@PzS8$H7BRqE$#R09pY=1iY%kW8wX}cI`JKPSc?E~c_PFWd z`-z3V)ls3`Y+>NpMT((VEE6xV9~7RZJ$nhs%ug-nuWNDr>@0a_vJh{GqcS`b@OSBh z=2P)@wAYVV4Kb^G39qvHM_FOx4{daH(~<12jZgDJ=?N=(7qk zM9S2D)hHI&ApwYk)os=F2~wcrC+WM;_1gZ*YIP&QtlA%6KdSDL*O^}+hs%d*Yb~u0 zc9d>DrL8>`%EI_o3Z8%zmmW%oE+L$tqn6PfdVllrxGyGtpS~w~v#q;jW3#>a)|jkr zH!F>yXCFfS+-693w~zbmfU$C^6djWGN47zHBlbOOYeV_#^fJAxt9Oq~{Tn&=%?ym6 z*w?K=ntvaAesg98h7~|YU`w3UR}%Pz#E&A|XN_7fzn@p_XNU4r$_yr-?6-*Z_Q&YX z*RK{CCF;&ov$D6WxMmh$r3G}jA|_yn26+5+S6T(*sZMH^#TjQQuHKw-SnqXfdWmgV z;PYdIEXF(dyryFws%k7%eN6SfPMk4V?OncZV0+^{%c55v26K zo6f4ChpMIMrC^0%KC^-f=`45>)i7N7349E7uj^R~mNNPE;j#Y!$KSsR$F+e>t{cb= zLd9BGlD%BwTqIKkKBEAVkr){IJgRP+Y^LpMPmTiZ-+7aA6w|0GHMW#X`zBO44TM(- zstk9m*$NOTYl43vou_#CUg|2TW~IA`wUK3id!pYO%dpi8M|Mew?CTr)j#x7T%050u zXQCHA`d9Kf2j9U~w^5hi!RD0X-VB9$%FF{}+8*#|EQ_28PSFuDyvwFp3c0uA5NyWH z(n*+II}{ol4<;0d$2GJ?W$KNfXXkI8hQ%&^M$5GxKPH^9<)vQBHY{1Jy9Z$5qJ#Nt zL7R9C1T;-v#T>@R%6fLS*~(fg*yJ|;k7dYm)m++5tl4wkxa=ff;S(-xy>O%?uc6NG{5xee*EEE^t#5GZVBd&Hn%c=%rgRozFnzDU}q0 z6<(_|m7?rSl9lX~E;t+r&luc(KU;JK=Z>MAH90Y>ZdGcULcq6KFKiUgKgjDDkHj2C z#XR6qq}Cgdq4v~k>a50@6s2pLYqyR_svu*I%Q!I^;lqDiz)5nQx00FXKw2!j zr?QV6b|+K=uG8F~?W|XARA{io-(+E>z?@KGU!N_4CS&F%SYX$3m|Mo_+BI&n>lf+A z>DM6=*#ag>wY#xm10yplDE54O{Bi4)Uy@cj^^B!ExqU+oQP_(XJvHgDzw+h&$|sRb zN5;hy{^y`>4jV0qy%+OI$Wv1vVm7$8g>x1DM_p+ja6xY)$bKeZzux@-PN35s=KY>x zwpE94L=#zcH+DqKM7Ytd2oZr8+CAaMVqmtOg|+GksLXw=F`+aVy0kKu+zPAd9t5;1 zE6=ZfaS;Ywq{PegQ9TouuFB4R?2etn;B@mIc-0GT!fmpn2u1_c@Dde_M(|J*Ka|HQ z+h{A6e@s%HIF;YQ(`oZrT!hw!R8^IaI+qSce<&yjA&uvR#{U2tKnae3!gUpj*NXmS zmFlT;3T@(f3@&(A1uA|Ey1(Gq+IYKKszOCT-fZzF+pfqbMrM zfMgcow(|ua`1MUP#~sX)DdVg%hCuJH&pv60Q#oE`Z0k z2MltZd1sHiWajN%`G5Y(j!ESre*|$GZ99C-$OT&|tzMODR-2Gg+BPcWT){PDnI!~m zP`EwIYT!5vWA-eN-)-Ziu%_gq&I=cc%w1>OTgSeoTMeMeZ#1*lKB4t43RN*G9in)_ zOm18B-Jr$d>{+tv)-@b+uodbZYWGJVy#y7Vt#A;J$xQK?`t>SUL~!ErE4E%zub$fin5edD3B z>C9HGm9LM^;<0{(vm}@-pW6!wwZof9W9}&75FzUl78wCSM$j`SWE(Us&OWJFeH4IE znvqo3V}~M@fEft-cHfkLu@V^HZK42Qk$v{o3V8%3l};-mIueb+j2c@^Kcj|!)1@V{uTt|!F3 z2p};unG}RLz5+m`MkjfY5b5?B>|3pk1=n>eZ(T~2D$SzxNEu1BRhcNU%kD@;zaQfx z5wJ$|WN}mgXkzkM)m?R}ED`=v$MfnjxFaOJH@o@--Fh-3tq61B?WLt>KYt}riPt69h6GK#@dXEws94q_iQGTARL88~C2E10I36Pt zGbR53Jr{2@oSR*UTC#lFaMjZ&v0>Dwi1IS80Hv9cJdPS-K?EF!@`>uD{{T6YJJ{u@ z;-MK^i}tG(%C`fM%HTnZg{=o3s4ETJK#P)~Obn(QH%`6Q&ZVrX2t|=ctn#OmV;wTM zT(Q+p+X+m8tXyR*C<34Hk?0Dtxc1%4)V9p7I>mcH%HnLb_iVRZN+pYeOP1m&TaskR zkHeq&Ps~Ok_j9lzs4;qq@z8*Eg(Bfimeycfl+ckC{irX|CHW}EciqMR0NJ?){bluP zv~F9;+r;0~*(w&K)0A~eO0p+iJj{JcHid|;GAbCEiJn~glIn2zYPSi%Ml_HW7$CVU}c@Y+vP)b1B&7UV_!8I#Jj$Bd2; z5;ZM}l+!Lk$&|#x_c)Noo_y$Qiql!ij^Y@wa`-I8M2=R8%BNwqULrl! zhF3Ed74tE)ZMbjNvo)7&boHD~i;u5_yLq+`IJmuHs11VJAc*R=eb(Q!2J7FB&@&&G zF0gmFy@%F#9es|}UA@j~4F}y^V!i3k<8oyA$FgP}61IWKEM;wgBoRpn%#8jLG0~xe z(NA%-cbmPB?L_vcwB5rUN7|}+>N=-LV)BcNR&+*AozJ)&j+e;0^Qp{bwb+AX0j-82 zAJ}}eefs0WKREj|epdPQ;(vo(;qKmz!Yc!(R!;A`oXxPA&z}z*uJybP?jZ( zu4YU~#CnUZ8F-ELoylnHxbE2b)HrYnv{mWr%wUTtkn#xOYNQPCA><`2kC=iV*4=Fr z$bT8T7vzqb!1pV+Ry4)^Uj}aso-$$4c@W-nC}a-IDdh#iNLdpzKkhp6-q_Qx#F5^G zdX(O2yfVb^pVmt=k?i~X6W||=xDThlXzip7GE~=AmSH}{E+y3JW1v+^-x!eg#QUT; z?=ce{Ya_=$9=oaKCw6LfU$FhJ(0b>%wpQDAuG+$5`PE4}dELs|V91b6nH&j3nVg>U zJvP*Rj@0;VccpZWtJHWN-RT^rckJD(ER$1+`xjx7W|LZ2)^Yy;BQXvB1bW~9 z0AM^`?q7@jsQRk-uj013PNee7J%Pt-ZqMrmf@`l|X_sQQRN~D7pQd4adFz3 zH14>>*vQeTM&OwH@DFR^RE?Ix1T-eJ$E<`@GCa@o|nX!tMu~U7_(m4cR+{>VRrRK)si(A6>Uc88m{%s&#%TOY35+Hi zn+%t|ry|MXGc71s%ulFxz`Wi^QC-Kec`U}U%}zNpYZSYdtlWy5ffD#Bt%yv-5k$)5 zM0o8H6Tbe6exKDohF&%Hx3S&N?#F$xK23LDH<7Dk#{L!d)ueJTpd)3xYCVe+Q(3p& zJ9C(j+x#Q1sC`O4FyH6=id&_Owb;QO74&@X@0k6Bt#h=!y{|*J+0)1?FPhf4Mq+Q| zqPW7Vx|v)UoA#SBVu*x_6YGf+gCdBuvfbb9E~4_gMt2kHVcBh6se3=;k8CaI{@C_& zPE}=kmGuo4s3yKjvf6XIE1(U`nBd*k1hND`m#q8U;`*KGIv!l)Y<4@e8vg*gnY~o3 zZ;tfz)}v$bnGHJw{h3_PwqaF4KJs*&oJ-iySFdEO%U)ff`Z4$0UiZCS=kEUik=?oM zk8x?GIR;bh;|DF9tC8a%+qSG;AGcW?lNM`O6nfSJ$hYGfnx202XM!F0)qRWctI3Oa zu*vu9y;;2GuG4xCOwpH8?aqOfd&ei0Vq@Bn9hQIqPp^QiKVm{Qzh(PxOIX~-_eaQl zELQN#x7v#lhVK4F8jtwVz^LRGWzb52eTT{a0AQs<2QeiCJ5SGYc_ux>?Pr>rr#+)Q zvdU|I=jd#raJqB3x?rOpHPN*5#|jbwRcZMFb!5yW;sbb|uH|ZPHNLAJNa)_pYP{~A z*123&lgq6XG{|E#<^;|pEoZYUOv*~}$Gkn;bC8jU_?@H)G^cI*iJ0yWbpDTCGxv|O ze^Ac@JJPzj&fjG<$UTqkP1|ZaHykWTLn>OPy3=55u2%#OS-^`L!Rv5d7Ljl5N7G|c9tv(pE=1_EXaj6lJ4v(FOy38#D* z(Vdv>M{I8PyF06HU~)RoTH`U*3nQp|hhP$<1F-j>Z3;*Tkx%v!M8OmQ$0IJa!}WCf zk)y}H>_=t01=ze+z3*K<-(-URsdjaTTeqc{Yd-qBFm(2;?2i#sNw88=EgnTbJAqG| zA6A+k9`^4~c5|@V{@CijDf9G$HJ72Jvq;q1OS8zX*;HCg5Xd5KKtwL7ekzzV;xK!k znT#%k@~_A)=<06b;yaPs#po)IZmsV2v+e>h)@rdYbgB;}kYJOmw8&9LnkoMPX-gI9 z;p;MvzwK|1z4Fz$%^9dWapes5FU5Tly0<%-sQJj$!Bcgq37dGRnH;WB@b*c7sOc`%&XAnzmU?9+-2v<#i5EnF}=reakuiOETVELS|;R zHAGa9A?R$F7_peYcSdO~Fxu8L8kGyj@>jmAQn%P?NdOYgA&J~cL~EV+l*~-b#Px4# z%$8FOj9q+gS3=;9h0r{uoW@GE3M_M#ESg9+7xpydV`vD1iP~hoV{Z9cZHyJ^vtvD<@1Wjh=Yi3>NM{7d)q z)@*p0^(*po!)e{Y|d3)m$@#(|ma9Iq@t3RZ1L2Yg*t7<+RfaYxVmh5bi0ZfR5 zMiRz99bV=mMd^GlcMXqSW##NYGbIly^ApO+ZwmW^DJ}UYaO1=M^6Ni7nOYaKJ<$4u z_A|1b*~aPa<}RK$EvuWS?d24Tb|#&Dt4*nbD3CTXCKTwNM6dlvKyMSs&pvK><)^UP zJF+?tUTHr9GNn@1rZ!u%rFA!ZX_TxRimJ-O7BLuk2n4q15W3``>I6W0IpAN_Yrt=( zhig1w(SBZb63uSHcY6Lq2O590bu8rQ&v5;2QX@~rRN05)1J$^jl>)ISi7kkTi)VgN zXMAe${{UY0&sg}v{dcUqjMRB!#!>A?2ODDI>?KwdyVq`31+BQ+wE_x#t07x`P%#Cu zPg>FKFJ`-!OAVQ`gI0^9nzbs!8>;=o5_f%nac|PLEi%(0 zGL=sA@f{tI)0$F?@d(rS3{DSBfmfB9F^pAqaflfZW0NNg_56Fk+!o*JddxpIyDy#b z_sp$lrM!YuG!~HVC967Y>HY~`-;QqyuJ0?WJHJ>oCyU_DATe$NIzP0% z=bcNadn=jC*urD8=bm%3x>mHZ3wQ|Q{DlY$8xmt;ts6EcX^p)NtLgLN=X71`?q_Im zc}A}_XDa%bEm3m<+c~DE(l0x8IEAYSSSx@qr{KAM*i$}9^*?Cy9$9%m*`Eu%LZzD4 z*^_llZb`Q&s2rHKnEpp2krhW21XdL&250>r{{Woz`cY{v)ArNHwI?N=%ck0KHK`#F zu(IBwlf?r2MH4=-<_-19NP)=|O!Nnh?>qjQUF-1gO{2){j;C*sJ&?r0>gMxU3|vlE zw@xw{N8V$bEc?{N8ojR{@{*oW@e?@p^uh1WtMOa9`h<1nn$~^W$#)-GFFT{Vr=+yO zYAb56g+wnKZkQ>S!l)cA(4n7Lk?tcBGd+8L#rXx8cBb!sE51Fx)7o#c*sLx($z-#6 zs_hKYY$*0q(I8c(!=zWbfrJ2}Ud71BW6U3gK4|z;*gvVqo&EXAXq`#g&mP}{tERL) z+;$pk(!gFvvAHOxR!S#(4YBJ@jsi0(F^z|P`cr)Jaju(O9mDm(@^cNSdq1VTLeo8_ z??#uz>z!B`&2^}C4ua0jIRW9Cb&OeDS|9C`fB;yj|+RF z-7eL6I?&YKF83OkBRiPVMUiXtZb?(>L!45THbILLS(><*N|I6W$E~{dBhNn5cdx@N zFKzqN*#7`3{-ODtUZJ;lTGTxaH*IM=bX>IBR_`{l#deqrk=xNE@{u_$q9SKoe_Vde zXn!Aj)7m^gVe4tE&Xv^qU7728Gg@kUXdN!)*i;KfqucD+;8GD?k@%Wf{{S=AYIefx zZBCBqEsHF?JkI+2=sxpM@?*puHRAR!xLz~Z(J#X3T-L3~wYPHFO6v%(a^*V%Gd2B& zlL&6-CZA-^k_UKTZE7^jF%acpN-~b zcVV6KQ^238SBQO(@iXdO+?`?B9{uQaDz2XI9yb`)(7eK`w6%u97?n##x`nk*@i|Z# zPUZ1b>P;@C#W>0lZa-pYORY+cY*tuE?JpC*`84MHtKRK7*>5R4O~zsLHm=N6!KXi` zvvzVx#}%h3NDKJeYHU4Z&uH@kh#1>pjizM})(7cyP4C}tu$~z9=Dn;jJ zgz3x(S;6UilNM5o*OyT&6&hk8fHo{CFkDFE;tF?L*)G@XZy~kLTgyJ{R@Hr>&~DQ< zG?t$2&+?f3g{#yPl{eYRW%6}Q$83d^02&lhEL3{Wki^GO8a9gIbsCB;IP=*O+Rfz& z<}{acL%&N;qiy|fjniG%@4ssEx^uHEU3`WwPh`XG@*3YFCA3`5{$&fJ5Q11%oy7fP zGCNF9S#9-;`q*OpD#m2|KJbb(#;5YXA&yyRGRlCnitSww(qQE=!I>x(gf6)634vL} z2^{a$Us|uN#SX&b@_r-uNvts$uO)$VM^tM>HFJ#Z;EMfZuyjPJ_sB>EY6zG}dS*76 zn2$AHJb3QPknLTo@HX`}p=L!_8G9#p*>5Ld@h0ofXZ}v+Qc_d-L_o&>03Ce}FiK6L zqvXAN8$(hurJUZR&+5G1r@C&+b{5}|@NETqB;cuWk4!E7_W@e4B;+IdKw zVU&#dyAzLO(XE!g%yaR!rJMp+X@pQO+9&ZJh#4KfbJca~D&ad1jkl%Z)TM!CV`u;j z#(1M}l#u%8@%-X<-aqvn5r|$o)nkfS+Ba8H)K|$S%cCh=>@U+C8pGmb62}z5a43!c z0Dl`m!A(S4_nUJ01Xy*hb3)xaZ2N>ngu%Vf0F~HqALGV%l7oo-b@r^@xrnBe)2UNW zaP-p>%6*}z-@}TF-5}b*>-UJlIH-03jiw4ZAMA!}_()#`xXAm z=h|^J*#(Nm5Rnzfu4ZNn+U9H`uYrxXl@~G7X4PzUL|ZJ4eUO?~Yu8-K{sL+>@648B zBl#vGCvCs+=-DbM5Xzx5-)BC1l?d8WCe*QtLQpR{d+V&HPt6^7k!qo;K zaS;Nh=ZA)F~0KYE(!aZ zl<(v#A(Bm9%Qfw`E)tmo#cw3ZK30xWJjw(>wiu6{)+trUGT7?*6J9W)xay?LFrpzU72sI~ z)%CWRepJjwUA&JMS^m?6Kvs?4w*ioBmA|Wgm3qs8!oFZ;K4Jh}OAUW9U9Ku9%4V#r;OsK{P`_9xiW-l)kz)i#7*It&n@4Z| z0EZhze;*m|TPfxjmR3gK+*(;;s@_x>!UV*`69^kB`)KyT2}A*o(YMJ}=M7Cb%NDV= zB&sY0HEvg)5Nj3?7)rz)XoQ|bE}4;;nHc#A>YK$G72YqhHVetv`*6u+GE{@h?d8gA zcq|EpBM}3NQ7eTbkIxHg_Hm=tm3a0+L(CSoF4J3#(Cc+5x4^)qYa z#nhPL}gJBJMkVr5gjt8dgf;_e-~?1>H1b&^y9(! z&QUh3scTzJprZb}L6eW6Y??R)BJx+uQ+sd6$UA$6{IIrWL|AVck# zfSCMZci;2q39f%`Q7{O#HwPs7CtIuPs(ilfbG=267K+KnawR+@;Zw(OiRz4=cD>|g z+gX(tjHFYKnyt$rtf&DbOKq8x<6arcOwVa&=K~u|bs!@w>-HaE6G*|VWDY)4?3D5; zc&R8v!7?Y(-)}gE6Qp+BCT6rt+Le|?_psRI$i-}~MpC;JY>7jm&S5lvw02+;xJ<~m zjLgLGfEDL!VB+>a4VB1fd&-DVDoHk6IPdFQ=U`0Frf1*rxx~oGl*i}Lbtu=OwXzeY zviNW|J;|{3OMMdJn1F&JFYJ^Eeo-Y5F~7veOmNod<0#?c3n6+L_R!h6yc?kF!Lgix zb`<+0<^~EsTWz#QP4SFl5Jx!t)}&of3&~_rST5l6fhZ!EarEwC{&C7=cb|?u0K4ug z4fDM;v3TllvV}EwE3K`{TbKbOe=ZR2Br>5E2|&uEqJJ-leaCvd=C9;4&(*I$TFNv9 z7aUDjuVmi z4l^{WUG!(#77Z?`Li~FJ(u)NmV6TeH<5Z{E1~Q?Mn2+wBRMt(`*)gYk8s&k57W7qs znU7SEvKXduV8F-(O2#4#88aN@=4xdOZR)phR-C-1pZj#J^%IWw)=e_rMj>$UX)pm$GYsYleCoZh=A;>#$5(!8aCNoA!4&G zWSi}V9Fjrx>n^zrqw-^kaM3222RN7znPF+QtXeDp<8jrr{4A}my>yBc1qA?eX1VS_ z=K&KZ=17WU{{ZvpIx1bi{I*F;EOlUO1!+t)0TtIGuzQ=!osa8MqBq`0gl)Fb&<+B? zry-S!LkzEMYeOyDVpSGBWe}vUv>&dOiHY_~=3wR-6EpcoNwc~=?zmR-T%U}rEF#5? zP+mfJd2HpdnAnywN>wr>F(R1!W9DSrc$`pTax}4}pULRL^_2QCqSCQkWC&PIGJ;_H zN!xB*hvt4a>8%X4ikA_Np+h2Ai#JjsM-(X~nfqturf-))3~W>RKw1^uM&(mr@j2KwNh-xu9e9f7GBO^(;xpnINKP}6yF6n(e+(EHl?Q3cbjzJ?Ts>H0u%DF+ABo)FzN|4w| z@KGGgZ`||-et66E9_(+MH8Z`r?nV&P-0L!R^Ey)XaGZnBj6pFhAceJ2$fNTwX50S& zu03}(uNAdNW_6cud&Ag^daJowb4y%yYZauIta3P&(nIHKVTH9(vdndx1OPvt$YT}x z1pLhTx9?Alxg6!DYg~1GMTORMEL;04=whq64c$h$MYuH?LgR56<1rgdL40i)t>Qn` z$GJW>W~pfpCh=L_ccM~ZU3$q9r(LG9*kCdhNN3nFGs<1_Gq}d{#x~2J4K7Mtx3m%@0(-R~vw{r>eQN3pmPq2Li(pT1 zi76=}F0>QgZs+%tzuNhI+42*(n$Nj<{iF6Hn951QC{z~_vbH@Ezg0?$IezI}K+m)0 zKQ6aHtF#AVJl4}V9d)C%4jMCeYsyiVq{TDb!jjpn{{YEzJmh45_5T3AvFEX!n(@1` zJ<{$*gZheg!&7Sh-RcYltsSOyy>!k`4WX{vgHtjVv7q<>5ihC>KFN!^=@gGfj<@Gw(+NVNxYfy~c(Ap~*~0vrhL0x~rzD zvN+d(ayquvQ7%)q+*r#A+9g}fnc?UE02(g#_M^SJ1HayN_p`A5x9nzs&f~R@uSw+W zy4HH_Qx^~1+HeADS5p|!nH|_s6aJtkK3{bz^Z1pns!kO$@RH$rV~%oMEu(1~S#Rnx zksfIMMSMc~oc5o_Uo5=F(D!sIDbu4GlUCzvBL%B;CmYFw zXZ`OudDvYYV^??2wp114*1PhHO<-)lIiAqC7-8AV;Smuw7qW&uYnWum5;zud<0CtK z{ToP?$H+px;!vNSS1ZGB!+wQU=VYeTIbYoEe-^w~@?*?Bcc!~{;}30Y>TE_kD;Uhy zrD@8r`ZavbjhCBm*V z)lQ`U0Hv>?qrwiQigo>dt1e^$L{w1G^suI89UJ#wmmS~n)3!ct_|w}@H#qI#}%)s&wROs(p<`IYGtT5hj}0*pnkrFd55n z_>h6)I#$x!Q!A_UI@h|o&$`*vX#`wd-F>Sv>@1$9O}h{2~fr66RARVNg z`0(q0pIMISRPF9o_m2K(c9XYWOKKfSi)NBfc~WjYPer7}xz2!GKVdw2*FEX(9S+R) z!y8*Q-J3|OkviE7n84$)cFsn{>n7&M+a)RpWRBY(#76V+74~Ds9`t!3lXi;iT`f6~ z*3iZyBb3QFDB^p6LKV&VT#bep?g*~#lx?I=@LX1$jgGL{V!UO;NWz#RLE0%4Ly23&ndJhkn1zwxiJo+Eg_de4!T zdo51IMfX1SRU|boVyzMop^FJ(&9&j541%9ieQS@(0w=EB`WE<&;(wLBxy$PQ$9Ze6 zvYpPSt2F)I^yzI?pzC6@>_8b=wTn9muuoziX(>QkhRoMe3_wHJP+A=A)*^dNrw;zP z)|zipYF5;&i)_Oq*;<&a7aW%{_&LnpVn=PFB!B0w>e4y=ZKAW0-+d3>F6nsV+$JK- zSIcQ^h*ZiRFl5|ul7mrKAPGnUK~n#(&ozID7O@^7`Vq&wB7 zyH(ts8>-w*t)TUVy2pOesj#@nV)taZmRAR`wGuB>FrrKSb*W5m{{S4%rJlI8hRoH$ zd2goh^Tm$SSnlFleOn)~B`#i~e8(b@lJ4XtoKLgTdNkJs|- zORL~CR%;|zDCzv8ZhhNw_}2S`it9NbWC)?KDPG$|4_n8>cDqz*tUkHadS?lztLj>H z*=G`rW!n~ikd&@rRfe^ofu$uNzEC{MOr)igyg=@jR!tmm%zN>Z!M_SVn%X}lQ^yX( zXimmmy^iIS%MzycRn&kWd0)u7C8Q!-%pyuv%%r%%5lr0L+f8==0J^#>C*7YSimhKA zu=VFrT*PY%ri4o?49MKb2E-3piiqIkNGFYDs9@ofA!tomb0LoIe}4R^!7sEur^C&A z7`mB>B6FJL1)CN)8JxOFtW8C#1M~ZG2!i+?vDZ`UIv#L#X5&Wm{w@!UT z&$u3GcqiW7SKOZGYOwD~)g`ac0)mNH@!k$(=dIdyueLhd zQc~1@Q29C7KOH=L^3I-^w}r;{9}@Ix8@SACjijQp0+oopKZLMBtWiw10h|biJj(fj zceQ>TyfK}>@*`aLx9Vw=%qLQ7-tTE$OJ^BYk{_{u9xJZtLqMUBQC#OMo zFiJiEKi>Q7E59Ag`a*pnHBk2Rx!tkV-g|kom`rMIOLqP;uAs`;J0wl}%V&Ff^<>y5 zFcUu5ji!DGXRQ|a;ot1vjNVjskIFH`Th_X#PwE)WX6s}ME#Ati-DWD|C5O2>(Tm($ zjPDZxJMY%i{O|fm=#Q)a0CaO6e|sxZR)O}jwftGr=eP)VP zSWPDrJcdt^dwQYuowVxBL!X4#zkhsqEL}Y-Wi+lH5t=?a>p!EX)}yz&%MII}&*S?G z-%U428`EW zcQaovUn@s3Ui%Hhu9Z;1r!Gtpl|HyrWB$=QabtNhXOu)o^sNfiujLvqG@~oZ zBgEwTvwpUJU28g9SLggK@F%%zUvt~X9j?2viIm%3jS~Zd$Ks@R_T>md1&xW_5JLh` zP*Was{ATQm=vPK(Az}8iPnob6F96#U6ZSOhHRlp+B4do&B{R&+=Y6BErImqijGjJe zs)}BFIj7f^%gxxxoy?c9>{*M_PRJ9bf+5a%M)MMUp_4N(QPy*tD2^zyv|5>MCx0HG zY)coIywVVnCMcwa3|G9k=aBN5nf$(1W1C&rtBuF~nb%zumDrl1aWT$AgcD8#m}IFx zRE)$7ujlm;AUGlUdspk`FfH_*W;m-@Td$$YX9=;wSh86(ePl5^Yy-Idra&Uw8jxKC zUDCo0T?j1B+XZn*A`e1QL@f=fa3!j zK<(5O?_Mi5!x+nUk!q7BnM;fwuj~^M;>1LO3`Bs;Z!r-Qzt2E8Wyjwvc2euWYwj|P zYKpR!L{AW3^NHjUuA0)@XbH*w>Iv2P=F?OXU& zg(=o4nR?pStfZsVLcUWaGDjp^{^NM4jn!gl3mfX9G@WKL$5e%N)-W82h^iaO9JU}? zGs}3N_>QJkXT7bqtY}rn(y?4^I@N=;mQ*-csMcsSnE~*w0r5V$7LNOTL~_zvvv|D4 zC1vjW$o4wN?r--%>;k??6p1cCM2nvlj`6o1fFjf59~k@u-lux$umx$j5-YBI{{TzB z30v5?!#jVPg?2z5uPD)ra1GpdTx;nl~ zD6E*SogA=$laA=ttrjJ&BjfP3oRn}Kr+xnb@+jN)y%%zrrQfXkO?XqQ40^p zDG8Eu*%4AVbU{}b+{H07yloHzDp#9^Zc#Y4>SZam*Uzbvb8{SRXNfKuKl2A_Ff2bez(H4>6{0q~VT3AG_)(0%bOc1rQ|-+GYuD-{You%rmRB zot>>}l2(UVw9X2FeYFSX*}8^IEO^5TC1bmbk1h6&fEX=fF?nma<zQlcJP0}F`Hxok>fb~S#IF)yEIBPp3Fo~}!lE8{YT zWH~%*kec@Fr5M?Js=0G8xi86JQ8P0F$Qd!%qn6PT03fww8Z@XGVzM@fQ(#lTB!>4)w6e1R|)+v2ak5uo80|mF+FI=R2S}_+zPujBDLd zAuJ!b`=Y$RQyU_YF;rJ$ASPD@1q3ieQ@rmn02x~|TOW!}P0tJX7aD6&q*%tJ43=Rl zPXUsNIb@qA7+*4QTYT>`>ZBr#*E;n~ecXkH6aeJVsI5}bxWCrMA?la=VirPYGI2i< z6Vc8FH&IenLm`dH!}iS6k^KoeNh~yc~Aab6p6}(czvBl$)|8u^``DX ztQvsY0+-0xuOMbZvKSbSAUi~D^Uwj+6<*15$WyPIsaaJf#fxs3iuk2Ui0!#ZAu5Tk z_XNTmCk&IB800fO1x%=Dm_aAKaHNU>3sI;$kLDC1o=+KN70& z-DQzHJ}Whs6ROt{doD6>pAoCS+j^8P*jW)IvXu!$^4Ru@*f`rOqft2OnTFL~FxQ8s zYq;I_A7I#AtUyQ$f0=?VFdvlsL;?3HUX6^sXl|WFo0Tja*?rocp}l9>B-u+?fKsL+ zS1{QA$tWo0u*5*^vZhT8quFBpwb*5P7sbk~vbHnqS`OOgTFz44r1yxKkC^`el8Vdb zqMcarS=#9`Tdqt!wXx<3TZpWQ2`*$}%S+-nBa#0AV;xsXcN3RkS1m96MI2kC2?6hm zY@RGxegLu=VhCiQxAqhemhd}33*#QYv}PpF(tI~4w*&O>y> zuQa^nEUnLa)Awtx`jFC7K#Cb)C!t`2`Gndt`z2UE;6Lm&AxE+G0ma2!Ka%Y0|z4%P682F1X0+1nVAR&I}9$eH@zWepP ze-FN>y_@nh3$@+b)7Y-x_oTqS=LMd=DXiwJ*1?K*8MwH4L=+2mK4CvU1GWq5y$OoV zvRzd;?9ryq)uQ^1wp?LhWh)jF1%iktHeh$*xgW;zU15)N{CC7!jCr#eiqsjYE$ihN z{{Xf+?<)&G>$a(qQ3OoDiB9pn&*-|^oUrl_RP?(Iu6sR_$#+M^3cbG8dJj6T%={Zi+$ttBi8ycFYzPl2ixGxX>86DQRVGHSFe<<9-Gw~APj|j zpm?ChOZ+Bd;v@cJt*Xy=j!mN{lxaV(U6joE9pBE(`1_|UMxMQ_bzMy_V=?O~ua4q_ zeTf$c!24BQRzI#LW(op-)NQq2H2$sH2k9x@y<6b-(^JQ8#8%E}*;0L5L`mB7x_|A~?)-c4T{#-VYOeVZin)Tz26(>_2Vuzy6{2XSsR{9+hOY z-lj6 zoX&{GhN9D2jp}!--gYV~z#+3V-2_eqFvs&So_yIu>a9AZYKl{Xl{|P^=k3Nxy%MFg zCnZ=@;P;t6I)Cy5%y(PF4>0^*(fSj~3>KZ8M}gM5RAOF~3lM{~PWeaNR5*2&l&lCw zVh8s#J6rv(`qX#B#rF?mJb>|Yv;IW+P1=hW`*Ekcp>rz;vlZ(f+RV6OlU}klED5X| z0q&BRA>4TrPSkk=^o;sRcI&xl@DBE-^4H64K|#3ddXFPg!y3j;#HC%nH+|^pMEtA!nrrn)s+#LQ$@7}ba3wCqa2E3SFpcv-enasqe^#>hv z=}kJl3bLx!$}Mpgu=DEI?*4{#yP8v$+B~yz`e(NN@bcQGH|rJU=XLa+x$(mT+-zkX zMWXTweTJ45Srw&~@atb78er@E{@8*f%4`uv#~b?O&1!D%+&c``fw0B`wT27WqmbxT-Ak(0=P^V&$DHmK+J6uVz<>Ts?=~(TfINtwo?%* zpG@-}ONk~CYA;N9rR5&2?)~2!>2?D%+J7anr(xQ>`;&rVbZ2k0+J&I~MBI=^+h0i- zm)kO|h%lG5gbrw!RLZ^#cLI|q^N-lXui#9F$ORCXM)absI& zaB!+wF8AhvfUrAtY7ez|br_H;gd9Vsmo@D%C9ZENalQ2H*K>P`*^M#U4H>9BfTIdmdbtiz?nCrv+YbII7Y8xRK2+zw@fF+3-$?*ZUvl)8(s+Iz}B zEwNZV8R2C-)-@WgbnZo!@;ctFtctPqEu~fpAyfCac`j3;GqmI!e;O(y|RfoOq>x?x;kUG^)q8S1G^Y+yV4r_CuW#}?LYCBt0`VdLtf_73Ehwq zGHl<^WcXX(?-ftB{nh$$>g{WU*1DAN8+KSha6UW0`H4JRUx}VM7O! zguY4+N+DjjpIjeK?=bQ{Uv~Q|rM1UsHD`Quz zroOqkWr+^nXiSxn!r^ZyprLsQGT7RqA`u<9!l6?iGdt|#>eclG@*~5a9`bn~8#Jy1 zJ>G;}$7uIt^#zmrWaMt2uDRebCOhgJy0(*=OEHBBrLBSji0c|V$>$~u=qLP|Ge#EcF4F>4;> zZfSQtEcn~lzUWY?gYIXQ`U@|B?CuK}Pd|#GsWm6_*~RBL6YS=7ay@>wTUnBsTB=Ek zq$?j>0m*IDJ=yFRlf94Z{%bwsCvg0+^54jg@arUGtn0icqx%g%r?JFp;>n{ni8YfI z#8C|pmTnXI3<$?vf#R>3o-X+bs5`5!`ww$Sc=h!P);N{av4qxHSC%_8`u_m^O+`i6 z6vk*bI-;S zju_O5GDWGZlT|XFU_hpyw~wx8@sR0P(BHnDuI)dOo!{+_x5?Ji`u_l4;wqy~%U1$RDA9)gQCH?$UYe5zZ-3;w8j+g71nk3VY73H0G;=lp1oWBGdm@o`YwGib?kY&uCR3V zc4Jgz^&)hoT!`MBWs8(6)lLS2VoDoe*pFjGBaY4)o#qRqA4or?CA}$|(Vk%WLsqc& zWtQKY)0!pX45_0zw3rrcn8XV$LfAZDqjbQG#K!$`=!>g~RI6_}%5>w|%Rj5`dG(r9 zbC~kco4-mA9XyiJ9fi{g@?jcl8<=VW)*lF*FfTh5$T=x`k0HyA=1iQk*6}$Ah0gx~ z5fQ21t+&?uBZtfCU#EY7db-`t=D_~|1>BD1;|N4>Mq#@#SZ2t_w;5sO|7jHEt4si8A%VjVkQAF_aZTD?=dmfZJOCp&Rn|{6lsXD zk4TRYV1WpSI3ilYct*lMluq;h)Wn2Uw?YUo-4{iJLZV`wsIFw$sr(Fu5#>Qz*)6y6VXdYX+NTZZR`HvL>}7 zu}nlne`fMuGaLRrNCSGEdhE#D$g%LRu&66>QbX*)2NPR(lp#OZ-(W`2TqAg%g10a^ z8ddT$UZxNR%SA59>?XA~1d34A7qL=v1|Fe_XEsO7M?h0sCYwbI7G>n}Bt-V09-uBj z44X#Hy@IlsUjG1|^E{@1d&@T>+ybp5CxOG!t1Pxxg0kUGXx8~sJ?vn}PS70qa+wK_ z(8orIYNuZG9u%>aqTu7w^trPXmLVr8dOd3eqIjsGQ@ldhxczMrZz&3=Svd+=#bOx3 zuCi5ragMM=O(!MO5Wuf7Bt$$S3-gWsHs}iIXNB{8vH4b_@dNDe_bIYzS-~<6O=5h4 z3OGQ15xnvFlIXE^Pb3(u)ISktFm`LYnNXnX_(u7nq_QW zLz|Mvj-$j2D1FY^33(-F?NCaIpAyI|;$!1!;|w@upaC0Jo{ z8TNegnB-F%f15r8W;oA4eVlzJ&AXOt{iZ>7AqbJQOH~IM%$ieGEHgQf^&FWN-`No{ z`0p$TV=-376c>_CMw)@~kG>ymT_+Ypec$YX5a9$+sEL*nb}65TkBGHtL5QWOFnQEC z?ER&t*$-0Lz{7g=1#KT(%mBnhL_~`uN@Th24A*_CAIjsL@{wXLMOwbF&FaoDN+6-4P7=0sZ+S(3}Gxoo9C5*B87y2loW)I=kqbV z?;_?a)BZ-GTy8qfNi|Vuitz9G6jp2Dt zLD*GRRtm=RFduT|fGnF0CQ0l(c7U1ro}Q+zK(9Ksp5Zw;CeijTlJh>R?^A>sSlW3F@#Lsa1K zcArHUJx8dQ3~chn<^3wFFv1y81!Cg`xXJ!smlGfLw_NB2-iq-2b!=y+6L>1GDDO>Y zgDN3bLH`^J@LWIvmIB?YzAO8(fE4CeyI0qwl6`j`2h=O!dmKQTRhy3)0A`8Pe^ z%KNG)o|PM}t7tF6ZSWzkOx;@^`@{)v@jU>M>BQj~jXK}-&}C~|?rVvwTdFJZ8RDseB8Zup z9iTV6DT=vkEQDn2@H1eh$u5|!+(2b8w#XvGB)zA|L)QZUWBCzvH5gu1b@FbzR*G6h zj~kSUYCaNT$uJQH6G-J_2M|ybD-zp(nF6{NzV4kH%RGW{n2;+2RweaE*kVH@$%T-% zumD+-1(X?;k`j(F8_@OE%AHWE`t))*>8{$<6;cI)P#hG#A+!hxe{87#04a$r{x*(^ zW+L{WLh^Ph4pGRw*B#Z3iE>nBCS-1r6>i>J665FNdEb77en~}-$=A7ttek`HMf8N# z^{TXlGGKt^g$HQh+Azr1Y)$7X<(1#0yD&~;EG3xn=hyoE zbj5cy4J>8KtFuiATbvdyR=7u78()wVp$6fP&URPz2<^yspWnjoc6%mY^&VED&buPQ zYMw+#*G>bA3cwk}z_Vr<0?Ijr#LQ33b@l{qzPd41F{JkcVwJk|EEAAK5^J>&Sqj6D z1352lMnw}l?;QZ{%~e>dnZZ_h1Jw09Ab?;d!@!r#5+N#wvxqFGkgy z78yuIOiky1T=A@h39t!k^vJRZNAj46iHVt=6^jxymySBk8Z}L+YY;E3d+~5ggaCX= z7W)wt6zvoL029>qpHT$r`kM`r(=2^k3teT_Gi87Y^_^%VhWfXL35V+r&X0kX|o!* zuuG~z3R0@0oE3tDYJ|ojA|)nK^E1-4W9?kAT-k`y+1iXHxfPC|1~dNvD#}~l9>z;y zNfTiFM2E-D{Zo2{Govymi>HB6So>!t-J`0ROMOvbz(a+=fjN-_C}B8cr{V&701J5K z(X(q2l4bmz%ymaCiME8}tEK9ZVu1@_^WGlNh=xIg0m#Ju;w~#FbBYr@7gkVUyNL6F_o& zCy2TX*itPa2qB+bPgM``)k1NY2GCGFh~bDUCl&+Ja8m^l_zQ|mrWjk9Z!x^YM^{qv z{;QU9RchL+dZmbU7K}^nD#IHqg^D9-GbrN_b2|s5rZ)NL3s)zSikRpvOO?JCn|`~6 z%(iebjgMm53^Tg$CDhl_)N9Lax_k#YY3!a4$D$7Ev7tS0nQ`xh9iY!q8{ zBQ`@u4YF&Mf}&6V00@p}!+887rT0-YNlnV+GDyXj9Mt1$-dsfrya|&p6a?(X!eP81ig*NUE!+NMpe4u>n`3N~BKny&ifLnAR4loo z&^Qo5Ghh;7#6*V^0Z|lB<0K1 zLbTl~=wiW~NMfs?xqZ6VSjfZIJf_(M%)~@M9S5yDOM}&T`-oNp_#0Lk47yjGiVjGf zgY-&SD}Y4$;d}}sgcP6qlIswtXzuiQ-P|U32gfaUsdRRud5AK{^$29Pu-KpEYpx*< z2o+2V0CwI;w%m$mXSVIO!YC;K>Od90m9FHiigs-WR5?`cGJ1}a{Dlxi-s}Tf{5WCZ)Br@Nk=V|TSn9W0R45CTK@pY4(#@|ea+2y zU*273*+JD+imsx@U~ zyPYr?wB%SUYSPXdG5{Er#1zTK#S^)HqvB@r>=)Em$$tm(G&DzX^O>&uc=DDIO>5Ft za=4)rkXWtX{{RpNjK>yy{{H|`w_7L1A7HY(9lxsd9&<>i0wYZ zDKP=B&P*Cif*2$CiIFdljpudWPp=X?kK#XhJjU)vd^;_O*4|b2qq0={kK0`rZqnLU zS#R(7+DR@X2-aBjSCAi-lQxZ|olB#8nc}aWy{E_L^lq@zSxX7@Lkg|3R!)VIk(k_7 zBGols$oP-MVq#LU&OuDH`$Wst+OhQCf& z5vZ{xD?`OiV7(_KVtc~)#p-smySJ4Za>S*^eZ3CW^|nn)Ybf%=t^TK;cXxld+1~u? zuQB|9(f!M1nOT($Q*#}UzzochRSZgu239aInO6_WV5VYub?kdx>fY#ing0OC@~@IU zYG{mSWxMaEFk!Crc54*a#@xo;sb~Wmk*gyD$}h7pd#Q3WFfl**^>z1)R{c6OXKk(h zLG}Ltf?rP$Dy_dS>Y<#_?y9WbrOA_Lb36`8n9X}(GrNKBdq;7YVGjWvHvK}rsJ-#? zn-7ldz0DDa@&5qFL|UAPX?hl!X6~hJbf2nnb{GT7wRw=3sIE&R5ZY&qK+|7N+*Yik zwbI)p^ZKRi%VwdjTU3fvpa`}e1~+7`Y82dwXEFk^JT zs=bJc(6>y&s!Q!L(;=}NB4oGXGZ|U*weTOaxC}>+-cxxYIL%n?Tary))b^hrV6Rrx z7ly=%WilH{e?m{%att3-L~lPc0$RZE)4^{3dE>10E|%>DO);l5#vA)JMy%9~YUyDP ze>mPEWaaV^21^);4ttUQQxUq47JityUeEU{QELAH0RE~ygtO#k9}jCEnhJVf9hhD@ zF4{;Aq+4^7xhglASNOme@2h67)Rwl=aITuhIf`;$nOLJ|Qf;-^+=rQ-17SS&?+0$N zz4FyHw6|*X9TjAZ^rhp)YRtZEkX$GEWXwMwjaLa|0*WPvGrUZ3p0RJgH}l=L?pAM5 z`5WTSu<{4O8Y4k^TfJ0HGTMU>E34{tZB>m#4cqvSa4_QW^Oea-ltghT55iw2JD-8_ zI>&$>XJ}0y+dk-{O8)@W3Dk+y(DZlC&)j-K#cL-%#;jJPuhP=wzf7(I075#0UiW7+ z;fAJvpPy8oIJiHL zVF4=F%rZT*5gcM-VkSts@+dx2Y8?SbR``$Q{{U}$JLOk^v@-d89UVOOsC8bN#rru^ zEIpcM#TG$acSvv^97ZNL`0Bj_uY9iZTf2D<%=qnZxJ+)f)Ry%qXgxccu$?QTRemSh zRAeGbhB;#s4F$*p8xP!Pd70;z{v~%$>GRwjFWSEG-qCIxj>#rQ{>b+rCBa5R{HDPKfqqWMm7Y9zGfQj!{r4hq_^o57H7=DcMW^)b zjD1FmHBFLPOR>$WE3IC#f;VZKL-bP}YY*wQ+OH-x-;q=)_ygR{UD!Qa6xVxF>PlbV zrfB15kjpLN+DA#=(g}fF2QF)a+9o1;-6w4OZR5vv{-@0BJA8rfhkx;UClOayWU=^s zYAE1o>hxL?WajUzL++W%2EtP_JSB$%KaTQC9gSz4aCx5c8?)Y1Wby~z?(cUGU19sh ztkE~AcN@9by9j=F@q(`GWp@GBrBPwIs&>T>$K9o#HVEGHDjSLM|VHQsl4E$7^~8_WbzNnU1Xgz+TA&a%J&|W zCo8EnP5Xsk7obGuVNh1Uh~nP>8G%7Tj{E#X?>l=(&?~r&$49Tre$r&Sgkt98aN(t% z)SH_;q~gHZ_L&yYMA;5gJIwF5R_9@JUG2bs@!Rf}XX(*m{hutt-g)`I;Na&ePb68g zP2XHZK@HHyF07%EJfLDECL$xR68dvj_m@)lx-;FHj^Wz#3iZ@~5bZv^ja^MSf|RTp z_9&p{+>mbWb1N@o6z)WO{Qm$@)UN7QsY(@gsQ&;C79Xomx-I%HhZ^*qNjx>{$-U1q zd@S#`i5jk^k?)=d*M`X0A;)H@SvKSH(-2V$_R4or%&&e2GEuP3{{S)7-`YQ^SJZR0 zb#WcN?SGYB>(r58QHsT3FJkIyi?YH25L#Pqvkam>2jrpvMmC7wt^0jX8LqOwNUqgs z&i!dEMXY?z%GT02x;WYZg1p^q`pWyEkb(7r;vl7^5wiV)T(_RC@1$SSQyb$0Yxxh~ ze1dfskn@d%20EAoM$}YLva64XIl7E;O?)zUsw^h2i%_MW6Oc*=zDg4GX(<8nRkqFZH1gb z0mKZ%@}84@Z~nS@jbWSA-U59-wT-E|1pHTWJDq@%SmMG?d1ElFndc4SW9+!H{N=OR)^L>c#79wp?qNnGpyV5~p!8X7dv<)vlZ%pVF{K zlX&OY99E6RW12aQIV;9Xjd$tWi1iGMjFM9j-(*bsSWrb1E#*9ZAg4A|>a>xND$RCA z$jRF)sX2F{iwN~g26#vjPqbj92qHiJa~&_5>#j?yl&6VpDr~Xt#bn1p%5b9F&_Qs=YzmN8Uql%5}Ann3yf{B zKz@g4pqh+^YNbSAEZS|jRj^_!B!`4cWMI$%5*2s*n3-|UGYH&&2%dni608im;$2WF zE2@@w6+kU2r&sBMVC;ORZolV*b&WV;&R7h(jvGgs6nYr@Y7K8x(#K zJqvNgX45gL3Raq=zaI;#+bv<7t|VUJA^f+HIT$D@9p-oZx&X{>BNdRO>~=!UT-t%= z54s9nrwDB(9@$`|y>T%k!UUk;VkTw=AXsBlmOGfoR80$|Rc3Jv0Tw#J2uO&4Hbi1Y zqy1ZPh>`yQ-%?((YR~<(U*$3O3gm!7n#VpKsVN>SFG;{mGDZw{AA%U4iHKZP{Wy%0 zOAcd=cu2H~LtVJ&7Qs*b#IU%@6zwqsCA198?Y6)`>?<*BsZAW~oIB0pU3qJ_&BGg$F$YVU33yz%wiGIFr?`rHJn&}uW2l9jQOF%uI%<BlbnMPG47EJdozhCNVCwP8T8_WIWa_z(D)#{U4ggH#!7IJn2-X;S_-C14Ve zWkNOD0+ug&;zzWP=O@L&K@t#A8}HBp->Z8fG*M>Vxv(ix+m0Ru>U2Rw#}(}Z8!QTD zKPjKz>N+m97|B?}hFLVSxUgzlQ~4Zgms%oKAi?=59y=^{f{%&Zzu!aDxrATwI7+!9 z%zdoHVdA>d&w4?z&T1r95^i4NWKsA?u%bR-`Zj4|ot|Zb!qyzA6{E_**{=aq$jfIO z$qNZ)ArS-f#y=SNjk*F1XymbJWlUZZU7Dcejd;wAEhsIcVB7|I&mI%Xes&>`(8pZr z)5?YxBO4cOVko=q_l4fb)l@)9oR6d0L`0pYA`5-Df{ni(xzG_AshAX@xrn2RzSLBy zTCMud8Zj?c!RnD=OwQy5%l$-0`swc+<;T-q%yxFB8m*;6BBMRTjf?^&!`KTEX+#*$ z0hxsmM=hslS9>Oj#7(KSQRuut%1uT&s;6aw(w3@<_uf>q`;JSPfin@Er)Zvv^-){t zwpmjLeXk10EQ6-2PP~3VDNro`0K9@%Jf>sjWsS#G5UsZL$dt&;M?jsXRm{;V*;0&)19idOrCaUC*oY%rW(sS}r04$L zCOvZo5%C>S_OH6ic&ivVaa=F#$L6>So}?b|wR;vyH<3kn4j~2-Coo@@(BSSVnNPRN zMfy2lY%$g{aIsvnN(q2w`B_XL%;SUs2?-9xJM16qHo~K1gB#wg?9!$mZo^BXLhfa%ohx7B|i{54%-h(7mx;5yy&dBeJBP! zbX^Q$9%4<7JBQn(VhoFq{{UnWvSxND=n3lGx_`&7AC|#Vx;3iSuY|?}S!&wYKEvYW zNd$yTB;aNsMh|F+i0P_o>I*0u6#?s%Fy`obp0-ywn1p|46^kQzX>o`siH-N(XJ!>L zSnQD5#$w$3eAu@6Qt|6eBZP$UU048~4g%UnV77x85t!Ixr7C_t4cVRScvrk0M zn-)|+da?&ar+Aj|koh3?gBcO>sV|s_35fWOx;pytwttcgmNVGkw51h#+-N5g24G^@ zYZzv601+OTiGh!p{{SiI1(>D@p3=cL6j%zaX17)HfD$TklZ91w{vBaF)DefloP+-6;d)cO1~vTEmD z(BP^w&7u(19dU67y!IiOnTcM)$%*C>wZu)%s~Kv|dl>cPUQ7dn$qi)FS#fU^u%EW( z1bak>D1#OR!I95EDjL{;4CO4AqNXIqrp1Y*145|*%!$^te%+RQqPzosV1GFH`RYd0 z%LZb_x_JziM^@4}Haw`o*aI1YI|*>UBi6Hn2!8Ml5i#Sqmi)?M{{W9Lt#>7L&%@MN z4nHAyE1QBg+hO%Hm5GQr*`!QlC|xr?*yv}{!>u;2_%_9Qsu>1Anu((@N9q;~`s4Oc zWAaR^lFQGvnOmtdfZAdF`BUR z36VHoqDnbH?IJsVJpn3HV5w1XTO?!ZrPo6pZB>_F8scFHL?%qsa03iKfZU1EAL=>< zl~qbdA!8HwxLRhm*0yHQ{zMIf3=)6fsAk7n2jg(yaT6Qu3~_jZ(hN(nR`M-M)%sA0!)p7MsGWj%w+Ko$y#dcS27CgoPk4HNQg`mWR{WOD`zN(;rNVg zyp@Z?SEWYY7dndTn@U^Cg>g#M*d2)6)3B%kl9mid2OAt>EA+%fk+d5*n%KN*DP%F1 zZCg`=?~0*2)};UevJ$m{9IRv(AaB@U;(dDt@*YmrN_B!AW{w>^>)K!OhRcNbM`@;ndR(>ncJWxWnZ{s>j^5=Dl({IRyID?*^7Xb1exH~I3`&JCmXEf#5P#2 zI)@!ubgE=d%TbvI60EZP=23OnNHHTP63lr*0$IieW=x5!g818@vKYpjB-E`jj$%C- zI@fWS=zP(tqAlE*_rsSmMIc_Nh?!sOefpZ|qa?d^arkh0Ez)a()YW2BY@jwGcyKA0 zI9Nv$nJM*-{{Rp@0V*-JD~2Mn@YV6ePn|tOCH5pBtId>+YAN0c&SMk;*<5~y zjJ$?_&SQ)~1lY%3aWf5GELOUTj8(8e`Yl1r58O?Az`$8BYbXhsFP*>Rs+(6oK*o)f zcpk)(t3dqEV99>w%5hJpavgTBaz}G`0XD* z@BqkhWMOx3FQJ~ShF7$cML4k10GSp+dq|`Yft14nVrP!g{yh+;Y5N0im8*4%kz7qQ zuxm13WoF(YMlR(I-aTSqU+4yB{d5L)xAK-Q(;HIk)OxKzQ+n8VxgW=CHa3lv22ry< zeq3V_@zbhB_kN4CsZO8DT!!Cmd_Ax(HVDRL19a3t-cY4Xm&C&3gnS0w02Vo|5OLkZ zok?YYwUtFw*r-jl1y~5@VJ=QM05fFIuZa%P%aq9$i!wOMWr#XyyIqqDt@ou0tGUO^Y4gxOuXyzL=23d*JylOh3{@FriJ2LAwz z4*Wo31; zS+kD(KBOf1F---W@CB4DQ#0%524yopF}F@@4%1N1; zCi>yi$%}l=f+-08xQN^*uHyb=DA*je?1om! z9pYwL+(tf6BaLMR*j8$ePuXb2!8( zi+R~g0f3o3_LwRE0L!9+d@+-L-bHv_qcz4h-*Pl7@wK%LlUog`Qub@5Vp7($dDos` zODs{H@S^jPK8PbjOX_CoArA^7q69^$LS%8dPi{g&Z^VRAwo@Xt3 z*V%t1JV5%8=^U0n8aRB8t!Ta33_e`Kz3g+K2b5SuL=(~S!3GZTAD+=0PhAzxAMGU4 z_3jco>%5(e@^YWi2fW@Rc!ghC=|3ntY1}{@jFd*!IQZYic+fBcQL9)!rBgI%_> zsWk0Q_R`H{GZ`C7h$|ReO^QH=zCdGi!)%POBjR}?OZO2yc{kSGkn#sJuJ0=bofoh4 zfU@AHSmbjBa{MW5WDCmOlO`c55L^D)akDoVo&Gk+{^IIQU8=Qyt?wsub-t|D`rjsV zV>O-1wq1Jct!1*wr7eOGhBSjVDo+!RV*k36CZ9x zYbZ84$Fp?AXlKT*-F+FpsH@gm1H{tu8^qrGVyoA@SiHtg^A6yH;%i)HChMGxrDZZC ziVR4Dnaqqt?civ@)Bd-Tow@I}iKVQ5s!3z??M~_DYoQucbdXo)Qtl$LLWOIF zlrX9#GPXZ*Y?l}q_G!A^E17NCDsuiAWBNRrUTJk`tfrsjUj9ILD*ph{$Glo=CFAdU zG=-lawZ>d^4|6*cjHo4|aP*i2Xo_YDn-$ow0Rc8P4EFXwEEogU%RF=QqsJdTyFcDu z(|Ez$oip_I^M_gEM&4nI!c+cQAM2Pbnwi8#;LLmA9@+N^!$06=a4WD%`c!JJ;rPke zp3QcDM15BLnC@lOPkMFcQz36XYfjhub{*YAe$!HDtrF=4Kp>UMVnQNhId!RzsppCQ zKlr)lPQL8FjCbqdG>%Sm?WU}*71e0lS462kf^9NMp1)YC&cs`+ta1GS^)ptiV4SDf zA~`q0$0p*>x?Rc89z0k2WBnlWzC!se+$}kgWlrLEov%5ejIv_|X1#o!!X;O*e#qD= z{wacj8QjWeQ+>|*PklnWL8okL9RC1~%*^R(aU}86+4?zKHJ33wpw^>XSbI$JC>e?0 z_dhWk5&FXYLA#IidedGteLs8`?S2!qx@zW@n@QKs#RGoQ65l~8fDn=kAj4U?jcCu} z^-uo*%LKlV{{URysFtYncgIf@`{}Ohc{$syeU>ac?Pal*)0x1O*ESoKkfxO_%U1y+ zh76bX6mr@JZ=YQ2+Jy5`+Hu<+e+T!;Yo(#Z(fIROUYRjl#Qy*`yp8a~xLJKk*v(1* z08PHrlUq`0{QViZLnKO`EBm^zP}JE_E(RR~G9kcVwvD54I#=tb>AW&+$shW3u-D0Po3$vWb-{x7`Y(a55=x3Eywn%=Oh@U2hz*SkE;(5T76PQ}Vsh z?lzsY>)1R+VFR&gE%k-QrE$SZWEk=|h=P$RpP8Pw1@z!S)V0>Y-ti6%5=IYDvx>jx82A*7@MIVee8;2pDUh|U}ZLuij5@QoPO!Z)W zXTG`FuKeV49t{0AbxqAN+4|0YGgfy`5ORiR-z|c594iN7Qe$~p*cpjzZZo)yZ>m1T zc=?U(eiKaQ>td>v^t7v12VCb$*qM_CFD@h5xEo$uFKIY2iTIAJR4u8~jw$eu4CdtW z#2z_#{{W}^OQ*3J8o4{ob)z*!Qmh|rWCUE+<25m+KGn8jS1?6C`iP#hd5229ia8sq z1OQVwOA63bWrwsxfzk|I6p)J?u`}GDca8R)y1TU9JXQ-WhJ9@}Y*9`7MSMnRRb+yG z8yoSHuN;mznQq<;fSKb15oP6W@JUa#$gcr8UN5^{zPB1@Mq z%l$`VQoBOCc%qyh3eD1MY`Fg2h_h8AB)QzdO7#)JL7v4DQOke#9a}f-Q9`PLGTp3m zh=RX5szyCbhDibaqEK9jN^GCX_9Bp(FUB@$k%rP`EQI31trAJidrx!{YpnPg&!hhU z@*IDk2qK<4jKoIqJspb%)2&I^fU}UbkNd0D-+`ut*-Qz5`@A|@tiW;V~*Vydqha;UaL zFEUT{%M4c@)z7J$gH#Z<3t)y1-9H<_Op}ktQODTD)om(N$ZRn+>~RO$M#RE%IPL3! zbcr6}v`Cys`s$iaeABSJStAnnp>Tpipqh2LM&8Pzx!@`vkvN~2J~1DUKpT#2e6q0U zj71t$&K}^aVd=CnUO>63O0}P2$&nC$oNpyFzWqY_$+I+Q<4*QN8j6c{D!($82*}Jf zYy<%?mjlEDkxYz(f>)5H4b{jBL>`SZJ7l@#kQgJPx$pHfZaSNDf z%Q%$Ch{RWq!O_cDtb@w0GK4B^RvWFX>cS4>C95R9fGW`1YcKl9Ss@=j7{Td$Bf zB(lwV{MAg{!&6fftBsdH6p4tme-0`b+-4?cU>H<%TAVq*8;yMyE=t8FnG@`|oC}4t zAbs=g3EmeBjiBd$gPqd2DZnccZy=>=O7>T1s9K=ivCsKXylH!8RA4OuDCZu*N~UA+ zj+rrJ_kFW2>H1gZ!N7g7#fI`AZ1E{3h{bt?tcpNnOK6?vXxrqP7U~#NB(KnIpiAlG93T6uC*Sc(d5ibl0U z?(!I15Fs=a*ivh<6huD6i=pu`1W8m8NXbCVPbuCa2{F`JGb?!GxA!S8yN}^(2iTi^ zw#@!N5o=6V5ry~Wu3xJx*D1z2jC9c7fRizZ+epl_{d0+4j`s#Cme z2S5Fh&^K?_!d1i_T-G~IUwQ%oE_f}*md9H6pOix zx+=YP1`m-WSjc3Il_tP(Os-`@L_;zA+J1VGIn-Dh*08oRD?1x4Sp}Tc3ycX9D)Ppl z0?l{{^}$4OnGzWP03LvOi`1I;0aj6ojXyTMokzQM7*d z=Usf%S;+$L(Yso$R~yql(PM zj&$OkD(;bQ>5ysyHY8#f%i0Dz@|ffJ%*yID6hi6y{DI*n;pE1>G(BUHAeoYhX%{6x z@4o*4zn+N@$mEvHc|QGGWm&b=bMA=S__8EyjL400GM{fFU`*^&^VL={HFG&+j!LdL z-0Ax&mj32pPJx4%Dy{G}jGJn|rhmDT(U3`srK2cgv`>TEL+n{X-$2n zhzY7D4RQ>f#HB|c_|HImw|T<$U%!5vF*3ll54k+qW$ICg?#YNS5-AqIkj%uKmnr4( za^%A8T6tQRlo*S*g48u&mM$6uK?WYj4DJ&H6Ff&^{e0~`F2)Njg)-80oMzAzT(^z5 zpL4)h0>|1XD3J(vklW@bpa`m}xh#kAcd_;@IA0H;NUJg|<@rpE!oBF?y7MtSihrskN@6)lOwVv> z{mu;~PO1*UMANRudn%lAG@Qc%RRSPNA(;_@D39Fqw3#r-R}|#<02R7eR;*}+V=qz1 zrXpPfEms&OGoSSw%yE&KF~N|>uP_%Mda)@FMndg&n4EEtkpMuMSD*5j^+@l>iBG}D zKrb9^x71B*)1*o($x^u#Di%JSx+5?HR%9$eEpSAFQviR=TM_!`n|aK2l65>!-C4)F zz#X>{*$Y_~H=3cs3uqXC&dFP5XNddeCOxOQHRj8$T^h9lu1fKtbwbj?H7dnvmO!~d zvp+v<>-1oy5*xx_1d;s;XY3u8h+1!;!Lu zEAA$zy|0g1HHMWXv#|*aBWR8!ZQpI?dTm)1^0(b*P7<<|YN{g5!@f2~W7+U?=@JGu zOPov${6^m&JIefv>g4FPwvyavos+gob+=c5um>W)vi2aC?3sv}gPswv?GZc7fDJ2H z%wgk^{6)MaD{wY#RjJK3L`W3RU73LyLkcV-^}LLWBY&Cd=Uemt0DE<<)EIipaM-MV z+RQq)q)IkwSp&L(UvAilf{t=UGaDB3U2Lha>4VX6((~hVY|CrccgGVkWo2z)#B)EG z5X_LwZSlO0)?|%oUQV?@%GDyJLP(5Q5O6>cQYj^ZrhgJ9m)u7p|RDA9bwUEqmj;OGAhT{V!jB2P2nvbwF6Kc(Sme&vm%^Q562+U{KBkkLX zM8L;NSC6k-9dh`!83+TbalXWuijFHt%oR|EAF#NDeY*-oKovY=@z^~WMT_lfDr=V)c7)o5;1Xjr#kKFxPgFJTEu5yf~F0701?6gFl*5BcicsYZ)v z4m!f#c~#X4)QtrNE8Xm2#LQTg9864%ltg}{cGzQ}4WiKdoK^D3Co3$qwP)HNZJQD^ zGD~w}83`uI?5s5STE!lWWKQETx8y&N?Z!R^BcKIvsN!*Ny5~}`YCp5NRaGuP7_WA+B*n%n zXsRH$>AQ5thy%+CJaJ_Oqdd$Loo*v`0p|E6DC|; z5@jrwO}cL82iYrhrroO_bt^Jw5%x^Xkuzx`9fo8F{f|}qPTpd+MYQYW9l9K*S+5H; zsG?*}yF>Ff48tIXXY(0|o#HwIEQ2Q=%u_OFT3L~@Su-zK5K}VP;mU%ETLFAvrVM#= zmGAx|ut3LE%h#^T8N$Z8UUcXa4VQocGQ)W}vnq=P&1Jbq02Z^3(nq;w+xV0^z*5tC zW`w!l$dW{9%#%oDhz*f4Wh)BuNsqu{0(ReisJWA`L3ukvtu;oO$H6S%onb`&5>Q^# zW8jw0@nXig#Hqh^9}yul&j+q2mQH1u|pKP8bq0KM@1f%}!wzSB(lSt&p#6 zY`8fpOqj)0h7rh+tO=5EN5qN?Zej5e0zCw!h2$MP9Yw_jOIyiucGs~nl4LM&Bn2fB zL{k!Tzs%3Zz%P_!@zrI3$i)^se(stkf|pSiCyc~^zQoKe8@^27KRIk|yu|cF*F~p| z94>E5Jgr&uuEQN-!Yvl!atdPCGsZp8M6;c_6#oG0uZUDy$mFX#5;st5MB29$1)NpD zC1fioB6l+q9f~F*SHJE$`IE`I^`thIPcNq|%Zb94Dekvyf?%4v3vxGDm*M_Dhs1xl zo`9y!+LrF*u`y{4mrH9TtXEQ`y(cj(dgPa3t1^RFuZb=paWV5H*TAPl(h3=1ZnjNT z;X(3AE-)o7T830gDV@Dc+`kW>jy-%lhDA>PNYRW8n*wZA7r4~_0CAqsD>>qDL(7!R zM;U_{-gcOU;rt#Um9sW4FCAXFGQHLirinevmQ0k{X#+{T*&D!&jEIE6Oz#i}S?bQ* zQO(qYO=HJ}po%qaBkcxnttJ+U;YZwRShSoxIdJy*J#I zzwYQ|G?_(zv_vE&CTxZroNp#AToeTUq>ns?{7%tX%lWP&Bbt64E+XX_l@FbezOSk!HIIPZ||}GIe3m;sPFG#Jb|;4&>myz%5~S< zjc=%67o{;b(`(yP6;{Zz{@TrlEJgMmuoA4QBjsfi+}~8sr*C+^t$obUo=JG+s`Q4K z@{dJn-~Rwk`;pkaTbmjeFu4@I!)_Kf%o{5d8Cm5Hu28osP;)$tqpMTKUod=U^S=V# z-U!g8+@q>7o6(hEgEGNr%3xZl2`G|O&*EHX^*v=a0DFPsMk@h@M{YD1m;N=lgLY+`hMyv|bYJ53J5175PMu!cZJ1i6evNfB-O>FmT@zqpY+#Hq-g)@@`O1 z3kPfMTCKzSyq_G`=z;L~1PRBCKqk1XC-5p9p+q_Uk< z6inAdDMBZ>i@nT`$%Q>=qs<)+<0hKcI!FHi>7&bCdFCa(P>UH2ZJgA&mQcwjGwx9f zB-)gTJ+R4`TLg$Wu6fS!1G5h&ezN{IeJ*>stGqS(eE4(P{Zp#6PDMD~ajtbUzRWIP z5|4TziAg%cVj(-WS;i!`+i~7feM<<^*{F3K{J7RCTE z#Rz(@q(s|ZOk-s-WT1j)^&`|RPO+^+E#gD6(j2TZS@tSNFjXSLHRppuLX@LOtG(n+lcQ~nV*P!58AUp0+GuM82yWd}< zw}`#Ps2@wOr~d$dyR+rSqpr*zCQliVE5a;-f`?@C*BLZX{h!+8K$!$_l9-5y(1jk$ z_Y*7LyPi3A^8o(g_f1-!-j>DFsm&?9W-JnA%=y`A7zraO`1qOq%=PVi>7n%B?Pt^X zNB0A{TJKn5H7>lhg8OY-tgJ-R$6~80Il83=$n3i6Ic$@6f^3w*ZvZ__QPAx!Qmqfd z`Qs^b>_*D!;*xZnvlF;G1LOT`H!XQ(q+&z)xLFH&G-l4B<8W6GJhhRMyuDAEEP*y;D*y6>d=rO zn8p_vf@JOO-GebBw)Rifm+Moh{PD|bZw!1X&Dhd@6k;w#9Z{(@~OK~HEBSeP$B?74b03qaY z6C3T-f|WXS(uFAD5z}r@a|ZGEu{e(3cK-kj?1Wc^R<5?+VI~$e*8~wNO`>!}NfQ=4 zg>q0JUzXDm8J&{5POFn`x`A~HN*IR4xq4wsIRa|q{6rRGw)=d+f5i1pDx~49SimH4 zI9irW>Z0K=))=BG;~t~MebGaK!+b#Pd% zgOJB#2P=>qy^FQdHzGs9slKIYtCx_V!M#qi zGDel%WTqe;03i}0q9BQ{B_T1#{{VdpT4>{Pw35u`MQ?hUCPYA#+Er$Py|xwXBa(j+ zV3bG6PyEEsKuLcyV&AmqC2X2&WJ?)QBs3#!;6EU0rVogTn)V_fnV9&A>y=mc_7TdX zg;475Y}hTUsm3dxWIDkCGyF^N7~vbv-!fegRS7K9tglu70L2bISzK?JP_0osBiO`= zz%lO`l9-vDx0&1Le!1$x-_2swXNSwyU8Jvm04|kG43&hbWYYIULWT=?kI23^l9>Pt zmulpRAJ4H@8(|El+lu=njmNPmJ>Y=%G2<(US$u9YKkurtRhM$kMKXs<1nXY`u~Y2j zOBKq077?5roXcRsCIE(GarvF)HXa`30kNM1U1IB#?6Tz4NvG5@bzVZXilj$}5)qSv zlH9hKh#KW!cdFxVH|&_pb4nbz8o5K7<~+?pJc(<9SwzV|F^ZDo$|ht3aqboc+BnOo zv4kZGYOsb{%x4wCXMhIF zF*IsW)5_$F1y;+wax3Kt2W;^5@L>tZv2g{+Oa3FE0sH#dhpF}S##29eMO6f+RGG1Q zw(2&GH!fkW^?zA189Yp8V`<|(MU(rIbmEnSvKGo0WX9$_c43VbEluJf{jh8_nf_(- z1Tp@)WC^)J)iQZJ1@Nwqv{hE!B6U?Yi{eCXlY)9$MsWu-xR4zDZ`3ne4N|sg0gkPZ zzSW~6Qp2)&geyu{HoC~ME)aGZL=eJKSmI>aIVOxQMqpwJL}E6b z=(B$5*umv;)iM|x)t>bfL>WclUf~DpnVo>SZxQ;9{{UO>(vcv>WW9%hZk**PtBt!{ zR!pe@F)9k{nf!J*GJt{DWTd0!XP_Qq>DbFtMVd{~*(7m@_t=(GVU))y=8>|I5{W4i z;yX!1{O`Wp=nS!9hbMe>7B@>XFYO|6GccHGnNK1njKbm=L_}q@PsvR0Gc&h30c*dL zG*>s%C*OQUs#Rtom6;H5Fw%;|wUBQHJfdO>K&E4T=3=;L7`-Qr9gH{Z;AV&wTN*Tj6v|>5HK?l0Wf@`CT0g{0cA|p3`*(( z2M~j&X*H`>fQxo4TG~V0O@aY71W(T>nVt6DcG@Y5Ox4jjk*UPi^t<)!m(JUT>G4Dni%kBJ57UY1|GrO3RNHD zJPLkx-~IG-FwgmQI<(@k5mkecg>$$DhTTpK!~VobBv@hqB+{89iIAVe z;wNqQ>5efaQi~4_sBy4nwk4OcbXPUtLO@C21S$_?mobIN6pzVso_j#{8Df(U_{?5o zCw|QkSrs&MV`d5j)ydHig$ODN4rAn?zvHN~7GkTfULQzc4e-4 z1Vqr0;6cEp$Pyy>DO7Lzj)BNxn;6S^jDmFGWbHN0yxVqA61D*>gkKP$frW^`2#jwM zJfeRtfNaY=qHKCGLWCw+T{m&8I`me_=CX2>uqyIGGLe~{At|4T-gjH4>tj;7I9z*h zwwjw?Z3zmH$t$2T!xIgOWXa|-16l#zUS$CM6NXL^cwMIQc2+yV*Nbbo1^gueB>1DGH%s zUX`(q7&G_n^DKc}&foAe(f2GxCBEO;QcYX)F0uCyR1M0(0AW_M_7@XeG842%A>F^1 zHu9~7OJxCC|+X_5Th3@ z5o}yV0!JLJj1&+-7?d1N@>|B=jCI0JdmjOF9-Q$A!3E4XqNt~H{zDo{WDpuR5JWM&3uoNd1?z$)`{7pYbECX3w0khLI|I~II>D4*)uzQM99B+b-Iu#TCI?iU3I0 ziQZ*7@sY}qD#pw2SMC9FAm z(3vt~XWr;AXv;|b+^pig^kr2IH7ZG22ABBrumuHKf(CrJ z#_$b~nS$G|m8!5xs^W%H>MK{PWBBScv=#(J9|`v#Qi z0-%h0Yy+WFMr~MP*UTV*1b7o9!Ut~0CF}|=)5Sq#K)MHzVOUPkP^U0? ziwNOB0uwVlb|{bc&=pbCudav`($iRH7p-v2J-}Nm$;_CkRr#=xU)ds4B?r7nmhv+) z^l<M1hXslW!#5LJ!hfxnon!4R3^RfKxXckBHWU%W?Jy%B`1G&tE99(Mr(V_x zmR$PQk#eSc?d~grclE6!1R}VNr{v(Ir1y{1%ot?*(Tuf_t(CcrM9UIQY&yD|1qH;V zMLV3yZ^XVLOPB1XdIBmHt>dzI)2(L=?7T&VSBr^SJyQ!AXAfyf!7!wTLSyCxerNR) zmAq}rPR(1hsBh%H(tXuyb6LQf0TL#gaWcq{Z~p-6?GXSQe2-MVv)+%q%jw)zX93t{ zsJ07Jl3v0&_gG>70DSOT!~$Y?L6*}Tr>Nd%hGL?nRB5WMtPeg3HX7%T=k^Fd7;_>B z5_A~M$V5oT2$=x&U&jtl7mvo-vt2+{+rpe*3nOkqOcWzrCx3h^n;6sOJijlEx(2Fo zkjl9erpp$IzPlu!Z?!KEn-e6d7751N5RAmkOiax3>6;NQCehY9 z;B_Em8(=0QVHpCIM)R@%0K~^YQASOR#JbAyT8Il8VM^Lzm7~+SErM1VGd`k)`~+>e zODAv2cL6pyJcb2kn()pdCdP zt2ZI#XJ(5^MY?Wlzky3|xX>XMOhL{{XIlR|k%% zjiqkoe4Equ!H{V2Q(ELjgsIVFp+wFDDiMw5Sk5iwxb4)L44xrYF7v|HE4D7IVM(y3 zQnR{ZXZj3ARw5pqghPmr2#NTZf{@b_!{zQ|ve>6aMzf10833C#38JH8BDy16?o(EH_O}@JUKleH1~OJNB?#sP9@sJ7B4cfaCP4U#$qa@X z_FEBOCy_${<|#1jnR}Q3V5ICawTQEvkp3kuWPJWzb>6Db!>MsaiyW4e#oMGMRWG?j z60}(o7*T);1ap7`4T>juk@=mXBeBwl;g0b`ar6mQmqOIk^)9tJ{-_4RUJi)@gWhH) z3zFh?{9<}4`sTw*aSx+xLQ0(jxnAYVFG@~e-fm#R+#@@+OD~0)nG8gn%z>@`;`sfP z(^}q+cLifLr8SK=GcAK{9J1-&#KzmgmvL=@Ognk_ncIG2G1kKTT>8uR3$`!D_UFxv zGBb2iwW_AQqf)$$K=~OQwRLhCksX2_jklPY+kNJKx0x(Q+}@~mF?mcSsIgwaZ!#?0=1iA7q;@};At>AR z))@Bp2jmCStICek_uEG4%s#4C11PHVW^8e*kj7e%O`6w8_6o+?WJ26V0y3iBc8;|H z+uc*-SA@CeWIGv=WnBq3Q0uyK_^k1{0yT_5wd>w%3t&cK$Pl&-CMPf?Gd`7k7W3n= z9&JtsL29a49XH=3;}0F0(79t@-CK?a2HNGye(7Zg$|R5EON__I&pOFUE;8)QWv)}f z^UV*VuYkT|ci&j~0i=AayY&3-_HxwaHTICzn7WxfY-9-p=2)p`?h{&I)B@vTp5-%W zDUMQ6)@}GX*q;x+mHn}H7s5?jK2iBQ-Mpyj>fOT6D~2B@kgr|utNoRR7h4jaQ&@7I ze%4qBCm#@ieOKx8;0SBEXY5`XMU?o zrER4x)h9N+9yb2~l3upGa;d6Pd5LLw3E)3$d=2d$W550T%xN6|0FfEG*0pB4?iP6j zjD8V}{^wP!v!80v63Ll8_i+@#Z?|4zey`tI-s1g9vUv{_{6NWSJZFW~vIScyomje*S4O`Adx6I&K0I|XTp=0ImL`Nr7$+78Cx^opul3~h#0N414z4Pg*3fRCnm0WFO- zEpzkowE#?Q@zt80I&g}OHH3(%RBiHFor>}APWIOqj=oszg@qRX0LNwj0FG^H*%e98 z6a0k8f&^j*hZ&JvjQ%klWwtJ&FwrmLnWGjH$i!);&1Adscs@BN^1Awq-m~e{3f(B*=M5JOipPO4HI1~OeAsEW` zbk;y>(XEnLGOFw%Q6gV(xL__e+l&tmJ4AoaTjaq_$7HO#Bv$g;uH^*{o7N7pq?<(G zfJu+769psgmYjUdn3?|LqOvo2pLsR^0FS#Z;&yDE1#x`EFwN5rH4(=sg%Q`A5P_2QtsLQS<1R^QoUs> z2~0y4Vh&uACU_i3@4rAaH`#3BF`1#Oa@@!Z7K^@uYd|1(QOOkWpTuTjVmU0QZ=K~G z^f;*6%i%DTH5G$!jhQU8P*jMJsg{OfV|fqonBy{BCU>4)9deyk>RO4#h47{(X|C1P zSr`#O^H~hX^+v)wNA4qN{{T_b3#}S9Os(X`<|XiT>8%E0YD{e}_ZUGOl!*S zQv%sgRS9d5(Sd|5RbXN!07ZsE(v|P)C>~KW(bW<+*^Qi9GC3L+**00S?O0uK4d4Om zF<24{enlK+WVe}__}VdMO2Ahva#Nj!NErp1<6OmH*@LhRw>(E__kz!sH^IA98W ze+iH&V-99Mcb67ef;*F2Ct|h7RW-tHRWubuGGo&`@haq8`$OUU-XAn)X z0lw*luXd3`eMSaDvcv#p2YD%$mmR1UPWxA3u-MhxNMkCL^Psa2hrH#Gs0mpP`*4$) z{{YT@AZUn0s{7S#*+<22LTl5jWSGe+%!w7uZ7wf}9&&Iq!e?*X%$7p!Ow}`e3{{P3 zUd(b;3dm%Dz>G>7xa49`F6Zom+Dmxbahd1@Ft1i6IYYMClF((ltg&(RZ9dy476$34Ng*jOWmXTZaTCgSk=vB=`JRNqB!f3> z6$k$SW_DA3_~DmB21Z~k8bo47Cujyt7W2rr{rsOnu=UmoD#5-^(aD%C+%uWe;qSpdX< zut`(w1N4k6;%DMiaWNZ2&+a;nG%TK10Yd62kQ4N9JfL%^fDWB*T@ltCoz*2qb1pZ`RSi@z**7B)pbQ{{YA) zt~$6jOr}{?td^Ispo%%FNMn=~K+ODY{{X(Z&;wSYdCaNKA0>A&Nh0Y3c}dN7G9W+i z51gu0JCuMn3PMI_Xx=)K{n>=yiB&v?SNaON3X<6eQYsFD}mg|x$#sK5QgMa zD^9fpWJ0pfJ98;blWF4sZ1k`~3U~;rCxpwk*k_E$&&K=oDGhu~R|@uR4kfBtkk`k! zp^Y8IY`3%ks8_~BRUbYg?OMg^TupNjBd2bf7WJ=>x<+hsHSA>7{y!5kxZXY^sGfIf+q~R0YMEQ|MsBHo z{K5N30ESFBh`vA0IE-=Ic#rqhIC}U+<#H0dMqAxt<~_EKl|UNR(IxrHfs!JGjGo)7 zVt0w?2`@gvV!oL%$63q}rSol*DXm@5zkpP%gbA?*Q8V!oCSU$j)O7QVRK*apicUrx zE;Q0rc0KkNyprt7h?xTdKv4d1Gs}+OhVw=@*@dxerv5u6V#QUWgJ^|#gA(2u!IDg5 zw`daPMH|Ua$L?lajl5%NW+zc(aW(5>6c%jKvtCtIYl4CGGA3mXEr?D>)>ATD?>qbe zk+X$^{v$T(ISS0N?5~Vk1P#`py|611iE|Dl;$vcs{{a4b^vv43wewE5l8p97eRr+^ ztOgR`J|JvC2I?s113MqE<|miLM@%SQ#9pu#DvR4mwvNIXTXTzIppDrO&OV?_Z7~8I zb}z4KSOA26`Ax(${T%#XG~vCopu7%{vN7RC7d04TyLf@ zEq%ZOf&sSFx`m=(`pkq5VX-g=^S|H(!P+8caqSga3Q$?c;%&tzj5@=x<|Aq9nFET- z`SqwszXBbj_c7Bh8GM#Sm~>gLnkrG;wBcyd$K%?;g_5A!=_gLo(=m^OD<3<~{T*I@ z!prF<CT-X4S^scf_)U|DvZlaQny>k(?M8^F923^a>Qu`c%+UCr(T&lT|IiS+I~r?WtD3P*V+`WLgvaY%(CDiAWb2nV6rRikf3)?J5aEZY*t- zwyrhqV;qtudfW+xf;p1~e1?8jFjK$h&=p&%H|V;qJyr7c?xF2**Q@BGV$bzNy3K<5 zh#y=CjK?j4Hu#w6i%Y=!loOw={LP%cQN36^n(pS%Ov z`~0Wp=cb2WHCs+rH{mjPx7S)s=){-~5>5ss3^kDnvPO5>3M284kB$1RHrbJ6*It~= zzc^@$54q?<;t66rN&HMEMCLdW{$u*afBsWrMGmaIPCEvNi(Z&wT$8Q*YXVwu!7qRJ z{{UgQwx5lPKljiJt7I%!%w4wCuPdm9dv6t`XLhQ~h#_hhN3b?zoWcGiMq9@F?sh$N zsztr(FYY$`qQ3e{kG(Y$Kkb^xKV4D{qwtC6v^7VY zjB-W_4Ua*$X^A0@GCwh}&-#v-Ry1ZZ81-bg$v)2Bb#djB*hmjs7EIttT}$Q(m5KwR|&`Cpgt(lr?f8?Lw*; z%*VJ55iB`jOs$ON@yZHhYK=RVf`cwwwRN*$DXn*ni#a;Y4n;Ozn1zW*BnwBDlPTb>8&;Wxnr)U33m!tJwE!Yu2)-Wd#D6iu#tTF zPjZ?08Hn5Cq;xVYJXL)`S!vPuB&3*{(=t(y_Ob>_$E*T!8iL!jl?s&FC+Cpykhc9OlmCqQ6`H(Bhpv5+( z`m83&*|J`xE-TbY!A~T^NpUKjrUYgtAfRLZXQgAZuT zB9XgYhDmU$ObMr0WW?qoAXx>!BZ!~ZKuA+|fmyWpuB;+o2x11@8>@38D)lb41uPGA z54K%1BmJ;5ABR#qA)98NJk(=z!|6d;O4nkoxPt(Xw@Gj?oq|cbPT%4SpY`$bz8TE2 znszCKN^2w9#VBh&nKfY_hRJ~f5^4fid(Zy>XZw=qn-OaLkfK$vSf?_>EHfbJU89yj zuy?3_k3&{44G--ZiH-viun#~=%2>OhZvGO^d3frq3Yi+1>(%T{arcoRn8}$XK(J)x zF+YrOExu!<`DMgKWPsc$Kj}mZ0Gnaba}r7sDBYg}v5@lP&NtiRsVJuIWb5Q<)^s_RRscTh{60u#0B7-ti3yn{#fi64g?q85kydOr-NC;f*=*od9?&MV zm@Ekrkxb7X25}Mj7T^n$$3kum8#J;3n}s5%S9NBBX$Z*?Otw=a%6&URptwK^_K%*F z)O_UbEjYVbJf+ESmFJB`xk*dLBu>oCM6{qoge&F*U}hpYPggxGCN(BsYlFj~Dq%20 z$wq^6qERe;Wws@1ou)z~;9_=&>WFn)$AwlyAgqH%N~qSRD{{_#auEY1Bx(h~#KA=J zjpz08& z6uVYeVat0JS{ej~!xvTUjxn@CoA4WKLmTcpLm_4-48gXFgJ^11Z{5kNRk4sLW-GJ& zn#lF0VCVgrNBW+P9DVvXvK7@z4=W@d(WZ+wlq_^f5L!^2DRHx4OtzVwqkZ;`fJ%eJ z1>{7vcZQL$>MGswV3*GxEMx$R*E}O}2;x#Z{LfDET7+_VtS`K%1NJDc;#yT!!&J9Q z)`NlNz-6Q(Gy0gGx%Vlri$AqZ+VZO)0X6cda*$!nSq({#seuzPLJWd2lHYx#dacD~ z*1kT&c%#m8W zWUb^-tIDu#AO*u3WU9{>DNC6}NRcol$;A66PGDjRIKcE6ItR0VQ(vlQjcUbdT`}ZN zobN`MtI4>;Yt1GZ*Wwf^l}7ht*5EEEDBpRQiQj#vZmizr`E}?20G%3Yk8b>u@>@Hp zJ2`VAyuIBCr|_%CW1h$;^@WL2&G%~V@hMx|E8Sx}B1e~5a5`U2YZ z&9K3P^|HeNAPs&b3K7rr- zk-TrlCS&sGFm$eh?d}6W1$b)lb!}RaQxf4-auG=v_5&w#Qw&a!gp6(=1ra}#$6e)B zPhiR1Vy3EipqqxqNkq7zp6MjGmU5DkCCP+vE)zd9%c*MRa?^#iIOJEytimfY)kT~S ztB9^ZA|_ynM8k+d2t=wT1}EliOSfrPhcxSC%?f3PzR^-W+|h-?T_!NXh8ozoAc=^b zqIUeIXE_5x%*{IjD6fLXFzGde7Hl=4>>z~*z*jjUVF^zNWX~BH+irnlMHfse~@0>5SRF0M=~?Pll6Bu&LW&Hn(f!DOiB9A-I0PSN(&ojAv1>ix=a^%#i8p@JW76j-&a z;0co}7=buAfiWVTprogiL{WaUWGF~Rp~%|9RAH4D*&3lJc!-M)#IgwdP7H;7b}muB zOb)Hf0(9`#R`cU3%7LX~=^{j!v4vc}rMpKch@bHx{{Y`WL3-nyabG)}c0%W`+{KUp zt{77?2Lz_U7#9Bk@9~+5`2F-AIh63%8<(9|PL?SRQk2CFX*UxX11K0=OoHH!XJVcA zBH#DZmkC9NB`dLzrp%ILSxw_DY%QORF^~}|0f~r_<;r9C@iEjDQIp6G7w4(g%ao~B zOzVGA<|AVmkyhpF68z-3#F0$?KO4vp<7njH6~e{Z7qF5r4FJeJ28ZySj>gmI^u&x5 z@ECInW(cH2A_vTJ5W>`9>DJ^?Ddg5#*_fBi$qNZAi6#Nh0Q41O$SNxWdWV1qph=R5qxz?9q(px}Kk*R&EU6h_ z#9}@5(UxQ>DYS`nk)3%VSydJK%ktU`_uu|LJ~|f71Ep6VbVjuxMl+5zRI$>#E-B(W zL%5F_kmDwQvXY(VdSODnq+d$~4ii;y%CU>J_U8%-l}mj_xRY*cZwG_q8k{7yg6q7kZ_hUFzwvps82Y{{{?Z^mbge1EnHQ9*$R#V-hsf0%lkBfN}DKjtT*o);=(omQgaExR##^Lqg^G0 z!5o*aA%a{R6R=LjBmV#+JzQ-=-;q`$6^N&HiPslH$xB%-21*pziTt>>K4xe0-byFp zBcK@3UZTb$?eyBQS7=P~Hnnb7H|-G4K89>#2L%vk`Ig^59D3(KTw+esqV5kO?1*s- z5_WFz6M>J#MPG3>#Bqp{{I}jeQ5|!jEY@RRc@i$s)mw;*MyhnvZSPGw>)6AJ$;&tr zY>yrxCOb3om@T1w+_SH_8JC6puPFxE$k(|h=2+xVLH6!h%2W*Y1PM&Hh(zzkL#ph} zl&>3d%T-NoTXL4{otR=wV1h@|r4&5LqPYQri4Y+&kCQFS^x3gxY^$1nKB>9N234p3 z0C{n<3))SD9D>NeNJ|+7#6~73a-M*#&b4l`@n&^0DpMo?ty-~5?&XYB6q^hp2soL9 z8sul3Z9fqm1zRC*pj-_)87zyTW}8ud(6tGOh4CvYQA?7|xsLE$nKL9?@}16m=+^~U zxSH`++`Yt1P1VKp14o@{Uf^@0x`kv&5;`58e(K~-^@cDa!1)Tb$chY< z3tS&5n4iLCN7d?&)NKF@X;(M5h)q?l)ZP@6QVok2!BTQbCJRDqq)Zqw$Kqlq{(7ls zwPAHxbc)SiTO7J+x$G1Kz?3C1S_@*{AiuD=O#c2h>O8FDfa>7=g&5_R+&*b2PzGsi z&lj#y%2>cLjx#g=06+OpR9�K~p)tGQFE0a77rZW(b2%siLIDzzvdFa4u0iLLy=| zo?QSIMjM^Tx+3;^$=O0e^^?e=L|_bvT1l7^1;mtzL=4QxOw7*vM0e3Al%mUVjL&5n z!);8Z_DGa019=gd2xiginF9X+d(1@qbVV$>te7UPjSr{jQWe+r9Ybr_aKZx$%82y{ zv8r@>$~T|$o#5lHHTCP=w8Bw=PpLjXcgyUsQ8g99oT53e1b5`zsla za?HyZHBEJOBF{Zy#)d}Os$iEYbK2aqlJfmPB%DfHL(NONS=Cp#c z2$#10OieKaAdqy(Fs4#M@&5n_gNWOV^x7}vF1seYyK@#Z0I{(YocV-T6Brov)}9dE z{lzj9GY7zCciZ7*rqRXHsc$kk>{UvZYpJPXKF}5I5#q8jVKt>c+&;zrUm!C(M07Ik ztf(#3881WuwKCcbN~uk9U?RHBqaKE>Ca;K%{{Rs#Uq1jCGl;(2@+hkrjI*d*1;5v7vd!Y08l(*Y2TJ6t8Xge^P0mqkNc%mr%sI}2)|B2eo5*5r)xuYEL=g0{W7Z_qfudq3+H<^5`9S`@KXWw6s;x{8Ce}dl z&3#3oh{#t=22Fd<t@oaQRS`ywFt2ANYNF6J$?XL;YEYg}6sksFtmnsYD`6ydCzYlDe5ij@nMh=GsDe&nV%o;yU#`^s9J z@yN**R>+XTN}o3!1k7!~!c3IEm@VLT_}k;5Lba=PGL-DjJ}fBW)H27l?5vcW$#4dj ztQQhuQlXd3O8(nFXMSA}9_P9WeIMD?@VCA@qb$;1ec=tr(lU8E&Q ztP96IRihv_X|veYFh_?ut0EBwALRrQ5gh(Lcj(iDx-UH7R(Grh&@=89!&5fe2za>t zT(<&%h>fOyT}5b|)z`Us)v^|*y@4Eh#E&nLWUq{gxRtmrI0+QY{$CM0?HvFOM5?lW z?BAMR7NP>fxZ{f&ggAHsJ`J-XL$|JYjBN!3QSwvKqiu}0jKX89IBv~?3UzAQTj_CF zKp9vT#@iCfQM`UXj6{B?pzl;FcQSbDGkV?77gVYjtD&D{aNb2;0lXlQ#hc7Tah@^% z0ORo{O;pXc9{k2~Fhqt`dTQTE#k7*hNLZMHl^YCHOE5T*;$IQI@&MJenbEU+6H6as z9FvzNc*Qj=Nd!c&Sz-oL5fTB$A~}9jAE}O{ZR%(D7OL6IH8$&vCc+97_qJe3zitq* z=L!)8gv`do2e#c&7}{$pk9LyCX0BEzuvVfvV_k?j;D}88T~(ap5viFmh5`{{XI~wQ}xWEfptQOu~k`Xk+S({t#rbi1pa#2mnw_n9M}P z@#FaX)swcQrlm`{CJ7GppYoG4;8PHUBwEN|pCJ82NXYN;ymcmKa!OtG<%Gs7)-E-` z87!_p*YF850EU+m5{VMtA|^^=c7PRy$djdInM?NEc7-r=PT@(hak%}l%Lrg#gm+o~ zJ0AZ4`E_vQ^I1zzO_$zodnDsq@->>ewPuOUgp(lSki?iw#Kc5QM&q>azd;S__M+2r z8JqA;iD4;up;^>HMDwR2o^mk@^|RJLkL%;(s6-K&TtKfWoXJ^49TKpX$^~(>1JuVr zEh(5#kpQk_nFdl*CA0umKE6%tzipb5${Bn<)9=$^34M4oiG>?VN+qlqAtV0)F$o`? zraFSU!G~>FstjJ92TwD{S5xb%C9oR_#6^Y>`i4E@JAR@+$EFre#k`$`<#F?xE&*g= zwWSM+ygfy0p2Nuff*>=t`wVSAu9u~Zvu$q~SKU%5t`}kd0BkkbD~?eB?bgWWFa^AR zU#b0c1X&DqIKno~>~<=xAh#`fWa_MFV%6_IUehr$!((|IGihWV^E3MCkd28^SF?u6 zWUVm6huctM9eIHgD>xevNNlQP%VCizl37R2)6%EYqxTq#&b3G}R*8`guEAxcoIsHz zfTMz-oi2@oVVHsV>4l`^9bU>WWb-w~!;raH5i}+Yq=b2dafX2>meNrJxX;G@0UhM! zb9XG#rH0g%=J7>^Rw@Z(Ve82Wxs4|omgWQ-&iuLajlLtJ;~seG%33|D{zE3giDT z%*XrarK+1+%%A@N<=2^5KFPz3y%QUX&PpeddnKEUmeCtd-#q{r(YtB(7<6gnZ&^Mm z3t&fcC`(%5rC}THpr2%roJ?{xlhSTxJc7o?I5i>I&3o$|$jZNBiD=_QARFzW}m)q?pC+k74bBPV$ zi}f)dKOHAtI|vQ0l33fws?@@d?yNPj592I@z5T>tJ6IEyZ7_Q;efEu>RkbzhIx_e3 z6^hGMjH_)HQC)KrGTnwE9Ja(lAVM+{we7e`5k&rf65}gWaTwEGnNq-cL>$`| zv|3`-;Q|u(5xJJYfM(CI+md^41i^(cD}$0aYaxdu z5+13Yq81azH{NaoVsAQa{{S+DlP-WPoBgj$%YqA<`#%Fl{ z08`P&X3*AIjV$(OAPAF%*}E=^1`-<*gMHSRjf2-8B?GkY5fRW8K{x{)k+DkFa{5zP zDY5hkks^QCspr4spT(0dZv0A5Xy1L~S<E#v~a(bYz&`GsUV+^JY zmQqVu?X=7k!Hkykw(&C(VQEvioMYCnXj(;^LerOW-XP^uJdff}=jH{2{@w&-?a;t<)4csbtrCKXKG;F;SDpl2E~`5MW~! z_K#GFexg5LzLF}YCm~+x9eY_yRlq7a4WDSeVGl7C!9>8!j1+A@JriQ0>`499BGg0#E~^1zI21_; z!GnmG#5Nd+35nZjo&I)*U&<=xLkAYIwcLhSSt7JE>tZj{o19YTOx6;a#of51i;G7-G&aS^x7#O?FEu&_-UmhYo8lc9()V-)J_ z6t_yOE$3-MQ*6k$s%$9>cE@qLlYJgXOx7x1O_?8M+uGhi7Dv1%A=dz zH9eLwwG#;RF-$UBR>FdjcKe{rM*j{HUwh{wMj3@DpUgL^#~B8{y0kJb|_es z@5`VBJbt00aTq%&TIMXR^=$E4%CbaAnJp$9Ea7{^{{TqA9F)w=&q8DGq^FH}r-&=d z+t9{H?xC44aKw?96Oxkoo%flIz9XV(9qe-7TOXdui4qNUbP`u_-o$T8RR5lsTn=_Ol)&8_{T*zCktLz8II4}%;syEw}paDMuEVOu*zIf z6EPbIgm1SQ+J1VMDw_+dluKJymDbACm0M$LJCKx+Pv8*(&si*_V4!Dz`I+gP3gJ;E z->A}~MI|u6ldMMp9EKKA>_Cj04{+KDzGh=-jlfB5RIMu>IRS23*Ss57+=bS!$xsIn zgW}PaN4WNw;}bG_M)NZ=jtv&r+sVZ_trN9z*6b;j`EVfN>mSA77p@jX&O zUW2Kf_Z!&e(q|;TDxKh#$-);f0=XEIFTe&4Cwbpvj-azs5(&rTTsVcS5T>YYl&YPz zl*th}a#Jgga#1nHWTYhid2|GeWgGxSY>q!s)rU!0K-PgU^^s5eX7dxu3O0|Ai2nfJ zT?BZFYCTrERz#1}7@I9+V@#BkNDu&T^CcfKGw~lgZ4u6Zw{CHu=h=Q)xeM0L zD}C(IvF&q{&0dff0CC;|CzM3Q!AH#Pv`Kcg)LkXBPg-RNO4$?ZBe24dCb7iSK$H}a zK>kO({KWqHsGX9bkc^8lcd~CKDnt+&GC+OXY@rC4jwW2U-~CK<0i%#zjK)(c+{P0(oV0Y>yLji-tm|ad z&hln$ID@`(QcDT&{GqhKv*PDY}!*KMO78KtJVQ_Q0hWhz{I@T;sV0<%$W}clLWa$vSMTL-=;YfDrCnXy3x6p!WVX!4D{aSE7-_~?5xle2daR57UupKtM(TU4IfOXP57 zm=G^xAa?dK^E~EeHl95ILSW*hEN)*c`ZUyp*pNguO2;A~CR+}O7CqDcFjKt7+i%j< z+qs#fy{Of*jUm2kH&A^@LGy_8S1~R9tz2$w{{V(eO#IJGswR=*ad_-;2111yZJQ+t zc_0L5{{Z4NsFjuI(C*lY!vL2l?M zE#S9^+9p6@65Doa*}scx5ozRb7~39`mPo+DIV>fLXaIx*pren@+f2^p(ptwltaLJ^ z>pyDsjbF;!mj*tUDTX2hD}@+AflT|P&zCM!)Gn=6tykJ+DBQ=|thzF_AG(*dMzQ2_ z#T0JO*Qm;74iy08sBIXEp0<@;RH87Te9S z?Y=T8xYfWI38(~PehVa%jtF)S-^}&)-bVddb23&@kEv+Fqe$z5O58-Oib4=m96;u0 zns}26OMmf+>I=0hQd-w@8hGcDE+DIYyN%TOlmx=$%4IUeaGBbEMB*p@Isyq7WbUSm zGZ`#Wf;4at^SpZbpUHWMHj0j7(GjQ#@Dp z$m118e<3H&#O<{Hx-A1@u2GZ&8x{C- zuPt2eRDj5SD;xCMN~z3(KG=dpc*~?oa2stLB4_-%0avbqAT43%D^YS^bjQ-Y0>4(` z3~(%V_JEY}+y4M9x9PJmc9O?XMSPTA3qNsgtl9fxt1}1dGvP4V1C@am)3(fknEZO> zsI`>TUwJlBIY?ZnE4V!eg{}o6PI_f#5h3e=7zzBKM|k+_<@p*pIY8xU)yZ55xNo?W zM6CHl5nO)}WRrk54^Z+6ke**VKp$(bH+>)(8N&uL!|9t-d;yivxgh2M(UB>iVYFdv zo#G-t)W<_r1Y7|c+1SUf%TO4_MK-l!E13oip-wm{6c+5y|AMRcXrsL4N4 zOXQBhT!)XnLVSfxFhm@-IoE+V2q$THYo{$j%{5vin7v>zZa;-;@{l>|#N5|7XF`JJXZn${h+ zjaPD1DAcQ$v-a?D;&s7S zO>Hgq0``vrCdh`-2Q%;`$KoTS#?64oR=nxR!iKRuHmW92MGTSkwQD0TJYY?5Q87D- zZMV+#);j91l5K3^T4S6}OtH;^7!A3uOMXUd7Q{k=V|h^T{)6ZkWIF? z8lZq;$jkAWXjzB}9v}fQ6B|U#%zo#um8;dpTz$i{OCg9=#FVUKl%tp!5gN)QPQgbA zD43Yz3!nGUj;Dr7)GTws)pa-Z9`(=6a6YP&gZQNH_3&+mWS&rPda%FpsyeC21GB6635(3+tvjU2MZYCFcCYavwE}8fgnhZ=vGk@* zVoyt$W>O*^!YJF-F){{R!b{`!V$Vygwp^vfBPwQ|Z=bunVPxhIeIlr~9#uo-Or zwlDRz+jT|DOvQ0^#!$SI32N)YmJwOp!b$b48N$6H&U=p-mcYjQ#17TD^{gF;P}|Gn z=GazSR4LkdoCpN2un}z5u%nkKfrW>}Z4)32G~*tytr-hA+Q~4djGtessR$Iuv6i5A zE!L&!2UzK1C+$h-y7}m71O1Wwsq{jnsMq{pzE@!6|$`d zGGqc3-3iX}wic(6xsk>+1(0r5M=)A?=x039f0YvWgD1-6ozEmEsNR-~aQ zI2nkEK@5x#mku-g{{Si9Xg{hy#%A12gdgG5Uz;nwIhJxmmU-*(`uR?e1SSy)0~ikZtzC&PR-G z9>^#e-eYfxnRvXFy17iR-C20tTGXrcc$?E+uNY~x)&dNGAr*{I%*2x?{{SiI0N05& z+h4R-ji&}tbycgBxOXTNivIvVfr)}C*ncl%$IjhbD@vGzV6WEAXDy9LDW_CiR&nDf z+H9s-#7@f?Nr|755ebN&^$xN*W(GRy?UgE71xT{WQH^igRcLS}SUVH_k_r+(#%5=k zbsW^MdCkUD3c83Y%B-&+KH7i_DUu6Fe2)BvCMSMSLR`OJxdNlZ#gS;XzB$xsKHd4O zIJXMuvJQEnhXO#=u#N;Gca_a{Z4n!EEV9)_)EhZ~tTQVDHBTfEk*+xa2nhg8^ND8L z%x%2PZLu~mnEwE<9D#*f&8SUKC7jx%w4!7lFZcWq$sZ$#<+Dq9{HLZSnicHP%6}t_ ziwsh#4VfTQE61Z|g6xaovs`C@h|EkxhyK0*wD9QkRIN^h3iokh9M$ap#8a*SJUzq= z2N**ovM0Rr<-&d!5!DybU2{hlbd5YsBf<35T2R?JI6Cn%bGPNZ9{j#`{{Y9PwW~{4 zi41VH?5k896spueP?|*GNt;Xo@BUwuO#cAA{{USRQT3(t6pI%!w&1FmFe@$VONdP7 zH*`!aM2=*JK0j0b`T+~^)fHjtYELk`1lRFv{&mQ~^pgDgDXUwDp8Ni%bW`r~cJVkCY#0OPDEL#Hh)rIemi zW*XuPNhvb*m!Nz^?oBED z4C8N^-bIsQW;Tcdfwvl=ae6bD{HZtX>sqY#O-aW7Tb#*A2_Ez7E| zIs%M^tGB=j?zrlP{{Ur*?H^jJ0?|Ca@rE%4GdwmCiTnj$KM@c^)f1S>I&EV^9M=-m zF zf}hmJ(H$wsqZf9rqJ0MBsWFXH9eO_9fWnY6CbAc~F`*$b8_wgjPsaQ71;=1)ttI@m zJ5x+V(`PS~AQ(beQbu7UM#CcbEw}#wf3AUP#!751q+|1fihjzJxU1f2j(l#s1&eGz zdgexUowl8)qO*C7SKQrOFXAi0E)BJXr_6hoCCAwk=q-q2a)2G6r)Zz?=!d**BqvkqZm&KX0k!37(hkDA~O?EwJBqtCmfC+*9f2jWeQxW=(jI&|6 zaZ_!EXC@K&0|{|4%x7^j4k8l2)I>~7@)Di?W2w|x6QWICS(LA&B1OLOm7s=xRl*~f z6pr7B{yTC10N+3dZM5Z$taq5V+9pHmzFIMS1ym&E2hFfAR5M}9=kxJ?V3#pe4M@v3k=brP!*)9CP z_x}K{k>sj#%gMb(%%zEJBVmSOy5sjn&0Pj5jMGSLRm|YswcZU^Q z)KZ|cWdpQ8%Zv>tBO81~2}FOX{{T=`#w#I^Mlm=|LzHYxqDo%0OhV!acIETxnIeeg zGdsa_ZN3?cBzjpf@%YzI7BRmZx0slYQ9JLyKo?x{RfpO&Yo;KHh6~9HFDN$-W$iDXQvt_}Pw0R5 z)fLUS$Py97Wxu)4HPU*;12YBbn@6`Tpf~{pd~C7ngEb;?lV}a^3&imY3V?PgWAP+H zP#oHEw!l*{AHDu(sZ279MZ0xrAg%)0O+z--O{x!Br5K==X5=9)y#wLHz#DA{2(APfU)(CBCfBF*2gb;K`9b(MP Xh{Ssd+t0FRX#At&<8SrXIs^aN+iI5( literal 0 HcmV?d00001 diff --git a/docs/samd/pinout.rst b/docs/samd/pinout.rst new file mode 100644 index 000000000000..7e8d7ad9014e --- /dev/null +++ b/docs/samd/pinout.rst @@ -0,0 +1,850 @@ +.. _samd_pinout: + +Pinout for the SAMD machine modules +=================================== + +The assignment of device functions to pins is very flexible. The same function may be used +at different pins. The representation of the assignment choices are given by a table, +which is a subset of the MCU's Pin MUX table and is specific to each board, as the +available pin set varies. The structure of the table is the same for each board, but +the set of rows is different. + +.. _samd21_pinout_table: + +Adafruit ItsyBitsy M0 Express pin assignment table +-------------------------------------------------- + +=== ==== ============ ==== ==== ====== ====== ====== ====== +Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC +=== ==== ============ ==== ==== ====== ====== ====== ====== + 0 PA11 D0 11 19 0/3 2/3 1/1 0/3 + 1 PA10 D1 10 18 0/2 2/2 1/0 0/2 + 2 PA14 D2 14 - 2/2 4/2 3/0 0/4 + 3 PA09 D3 9 17 0/1 2/1 0/1 1/3 + 4 PA08 D4 - 16 0/0 2/0 0/0 1/2 + 5 PA15 D5 15 - 2/3 4/3 3/1 0/5 + 7 PA21 D7 5 - 5/3 3/3 7/1 0/7 + 9 PA07 D9 7 7 - 0/3 1/1 - + 10 PA18 D10 2 - 1/2 3/2 3/0 0/2 + 11 PA16 D11 0 - 1/0 3/0 2/0 0/6 + 12 PA19 D12 3 - 1/3 3/3 3/1 0/3 + 13 PA17 D13 1 - 1/1 3/1 2/1 0/7 + 14 PA02 A0 2 0 - - - - + 15 PB08 A1 8 2 - 4/0 4/0 - + 16 PB09 A2 9 3 - 4/1 4/1 - + 17 PA04 A3 4 4 - 0/0 0/0 - + 18 PA05 A4 5 5 - 0/1 0/1 - + 19 PB02 A5 2 - - 5/0 6/0 - + 20 PA22 SDA 6 - 3/0 5/0 4/0 0/4 + 21 PA23 SCL 7 - 3/1 5/1 4/1 0/5 + 22 PB10 MOSI 10 - - 4/2 5/0 0/4 + 23 PA12 MISO 12 - 2/0 4/0 2/0 0/6 + 24 PB11 SCK 11 - - 4/3 5/1 0/5 + 25 PA00 DOTSTAR_CLK 0 - - 1/0 2/0 - + 26 PA01 DOTSTAR_DATA 1 - - 1/1 2/1 - + 27 PB22 FLASH_MOSI 6 - - 5/2 7/0 - + 28 PB03 FLASH_MISO 3 - - 5/1 6/1 - + 29 PB23 FLASH_SCK 7 - - 5/3 7/1 - +=== ==== ============ ==== ==== ====== ====== ====== ====== + + +Description of the columns: + +- *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given + as a number. This is NOT the GPIO number, but the board pin number, as + given in the board specific definition file. +- *GPIO* - The GPIO number. +- *Pin Name* - The name of a Pin which is expected argument to ``machine.Pin("name")``. +- *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When + using ``Pin.irq()``, different pins must use different IRQs +- *ADC* - The ADC channel assigned to the pin. When using ADC, different pins must + not use the same ADC channel. +- *Serial* - Two columns with optional Serial signal assignments. Both may be used. + The cell content is device #/pad #. The pad # is the respective internal + signal of that serial device. Details below. +- *TCC/TC* - Two columns with assignments of the TCC modules for PWM. + The cell content is device #/output #. For PWM, devices 0, 1, and 2 + are used. The TC device pair 3/4 is used for ``ticks_us()``. + +SAMD21 UART assignments +``````````````````````` +The UART devices and signals must be chosen according to the following rules: + +- The TX signal must be at a Pin with pad numbers 2 or 0, like Pin 1 with serial + device 0 or 2. +- The RX pin may be assigned to one of the other pads. + +Examples for Adafruit ItsyBitsy M0 Express: + +- uart 0 at pins 0/1 This is the default UART at the RX/TX labelled pins +- uart 1 at pins 12/10 +- uart 2 at pins 0/1 +- uart 3 at pins 11/13 +- uart 4 at pins 2/5 +- uart 5 at pins SCL/SDA + +or other combinations. + +SAMD21 I2C assignments +`````````````````````` +The I2C devices and signals must be chosen according to the following rules: + +- The SDA signal must be at a Pin with pad numbers 0. +- The SCL signal must be at a Pin with pad numbers 1. + +Examples for Adafruit ItsyBitsy M0 Express: + +- I2C 0 at Pin A3/A4 +- I2C 1 at pins 11/13 +- I2C 2 at the pins 4/3 +- I2C 3 at the pins SDA/SCL This is the default I2C device at the SDA/SCl labelled pin +- I2C 4 at the pins A1/A2 +- I2C 5 at the pins SDA/SCL, + +or other combinations. + +SAMD21 SPI assignments +`````````````````````` +The I2C devices and signals must be chosen according to the following rules: + +- The following pad number pairs are suitable for MOSI/SCK: 0/1, 2/3, 3/1, and 0/3. +- The MISO signal must be at a Pin with a different pad number than MOSI or SCK. + +Examples for Adafruit ItsyBitsy M0 Express: + +- SPI 0 at pins 0/4/1 +- SPI 1 at pins 11/12/13 +- SPI 2 at pins 0/4/1 +- SPI 3 at pins 11/12/13 +- SPI 4 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins. + +or other combinations. + + +SAMD21 PWM assignments +`````````````````````` + +The TCC/TC device numbers 0, 1 and 2 can be used for PWM. Device 0 has four +channels, device 1 and 2 have two channels. So in total 3 different PWM +frequencies can be used, and 8 different duty cycle values. + +The DAC output for the Adafruit ItsyBitsy M0 Express board is available at the pin A0. + +.. _samd51_pinout_table: + +Adafruit ItsyBitsy M4 Express pin assignment table +-------------------------------------------------- + +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== +Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + 2 PA02 A0 2 0 - - - - - - + 5 PA05 A1 5 5 - - 0/1 0/1 - - + 40 PB08 A2 8 2 0 - 4/0 4/0 - - + 41 PB09 A3 9 3 1 - 4/1 4/1 - - + 4 PA04 A4 4 4 - - 0/0 0/0 - - + 6 PA06 A5 6 6 - - 0/2 1/0 - - + 16 PA16 D0 0 - - 1/0 3/1 2/0 1/0 0/4 + 17 PA17 D1 1 - - 1/1 3/0 2/1 1/1 0/5 + 7 PA07 D2 7 7 - - 0/3 1/1 - - + 54 PB22 D3 22 - - 1/2 5/2 7/0 - - + 14 PA14 D4 14 - - 2/2 4/2 3/0 2/0 1/2 + 15 PA15 D5 15 - - 2/3 4/3 3/1 2/1 1/3 + 18 PA18 D7 2 - - 1/2 3/2 3/0 1/2 0/6 + 19 PA19 D9 3 - - 1/3 3/3 3/1 1/3 0/7 + 20 PA20 D10 4 - - 5/2 3/2 7/0 1/4 0/0 + 21 PA21 D11 5 - - 5/3 3/3 7/1 1/5 0/1 + 23 PA23 D12 7 - - 3/1 5/0 4/1 1/7 0/3 + 22 PA22 D13 6 - - 3/0 5/1 4/0 1/6 0/2 + 34 PB02 DOTSTAR_CLK 2 14 - - 5/0 6/0 2/2 - + 35 PB03 DOTSTAR_DATA 9 15 - - 5/1 6/1 - - + 43 PB11 FLASH_CS 12 - - - 4/3 5/1 0/5 1/1 + 11 PA11 FLASH_HOLD 11 11 - 0/3 2/3 1/1 0/3 1/7 + 9 PA09 FLASH_MISO 9 9 3 0/1 2/0 0/1 0/1 1/5 + 8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4 + 42 PB10 FLASH_SCK 10 - - - 4/2 5/0 0/4 1/0 + 10 PA10 FLASH_WP 10 10 - 0/2 2/2 1/0 0/2 1/6 + 55 PB23 MISO 7 - - 1/3 5/3 7/1 - - + 0 PA00 MOSI 0 - - - 1/0 2/0 - - + 1 PA01 SCK 1 - - - 1/1 2/1 - - + 13 PA13 SCL 13 - - 2/1 4/0 2/1 0/7 1/3 + 12 PA12 SDA 12 - - 2/0 4/1 2/0 0/6 1/2 + 30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 - + 31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 - + 24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 - + 25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - - + 3 PA03 - 3 10 - - - - - - + 27 PA27 - 11 - - - - - - - +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + + +Description of the columns: + +- *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given + as a number. This is NOT the GPIO number, but the board pin number, as + given in the board specific definition file. +- *GPIO* - The GPIO number. +- *Pin Name* The name of a Pin which is expected argument to ``machine.Pin("name")``. +- *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When + using ``Pin.irq()``, different pins must use different IRQs +- *ADC* - The ADC0/1 channel assigned to the pin. When using ADC, different pins must + not use the same ADC device and channel. +- *Serial* - Two columns with optional Serial signal assignments. Both may be used. + The cell content is device #/pad #. The pad # is the respective internal + signal of that serial device. Details below. +- *TC* - These device are currently not assigned to Pin. the TC device pair 0/1 + is used for ``ticks_us()``. +- *PWM* - Two columns with assignments of the TCC modules for PWM + The cell content is device #/output #. Details below. + +SAMD51 UART assignments +``````````````````````` +The UART devices and signals must be chosen according to the following rules: + +- The TX signal must be at a Pin with pad numbers 0, like Pin 1 with serial + device 3. +- The RX pin may be assigned to one of the other pads. + +Examples for Adafruit ItsyBitsy 4 Express: + +- uart 0 at pins A4/A1 +- uart 1 at pins 1/0 This is the default UART at the RX/TX labelled pins +- uart 2 at pins SCL/SDA This is the default I2C device at the SDA/SCl labelled pin +- uart 3 at pins 0/1 +- uart 4 at pins SDA/SCL +- uart 5 at pins D12/D13 + +or other combinations. + +SAMD51 I2C assignments +`````````````````````` +The I2C devices and signals must be chosen according to the following rules: + +- The SDA signal must be at a Pin with pad numbers 0. +- The SCL signal must be at a Pin with pad numbers 1. + +Examples for Adafruit ItsyBitsy M0 Express: + +- I2C 0 at pins A3/A4 +- I2C 1 at pins 0/1 +- I2C 2 at the pins SDA/SCL +- I2C 3 at the pins 1/0 +- I2C 4 at the pins A2/A3 +- I2C 5 at the pins 12/13 + +or other combinations. + +SAMD51 SPI assignments +`````````````````````` +The SPI devices and signals must be chosen according to the following rules: + +- The following pad number pairs are suitable for MOSI/SCK: 0/1 and 3/1. +- The MISO signal must be at a Pin with a different pad number than MOSI or SCK. + +Examples for Adafruit ItsyBitsy M0 Express: + +- SPI 1 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins. +- SPI 3 at pins 13/11/12 +- SPI 5 at pins 12/3/13 + +or other combinations. + + +SAMD51 PWM assignments +`````````````````````` + +The TCC/PWM device numbers 0 through 4 can be used for PWM. Device 0 has six +channels, device 1 has four channels, device 2 has three channels and devices +3 and 4 have two channels. So in total up to 5 different PWM frequencies +can be used, and up to 17 different duty cycle values. Note that these numbers +do not apply to every board. + +The DAC outputs for the Adafruit ItsyBitsy M4 Express board are available at the pins A0 and A1. + +Adafruit Feather M4 Express pin assignment table +------------------------------------------------ + +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== +Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + 2 PA02 A0 2 0 - - - - - - + 5 PA05 A1 5 5 - - 0/1 0/1 - - + 40 PB08 A2 8 2 0 - 4/0 4/0 - - + 41 PB09 A3 9 3 1 - 4/1 4/1 - - + 4 PA04 A4 4 4 - - 0/0 0/0 - - + 38 PB06 A5 6 - 8 - - - - - + 49 PB17 D0 1 - - 5/1 - 6/1 3/1 0/5 + 48 PB16 D1 0 - - 5/0 - 6/0 3/0 0/4 + 14 PA14 D4 14 - - 2/2 4/2 3/0 2/0 1/2 + 16 PA16 D5 0 - - 1/0 3/1 2/0 1/0 0/4 + 18 PA18 D6 2 - - 1/2 3/2 3/0 1/2 0/6 + 19 PA19 D9 3 - - 1/3 3/3 3/1 1/3 0/7 + 3 PA03 AREF 3 10 - - - - - - + 20 PA20 D10 4 - - 5/2 3/2 7/0 1/4 0/0 + 21 PA21 D11 5 - - 5/3 3/3 7/1 1/5 0/1 + 22 PA22 D12 6 - - 3/0 5/1 4/0 1/6 0/2 + 23 PA23 D13 7 - - 3/1 5/0 4/1 1/7 0/3 + 43 PB11 FLASH_CS 12 - - - 4/3 5/1 0/5 1/1 + 11 PA11 FLASH_HOLD 11 11 - 0/3 2/3 1/1 0/3 1/7 + 9 PA09 FLASH_MISO 9 9 3 0/1 2/0 0/1 0/1 1/5 + 8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4 + 42 PB10 FLASH_SCK 10 - - - 4/2 5/0 0/4 1/0 + 10 PA10 FLASH_WP 10 10 - 0/2 2/2 1/0 0/2 1/6 + 54 PB22 MISO 22 - - 1/2 5/2 7/0 - - + 55 PB23 MOSI 7 - - 1/3 5/3 7/1 - - + 35 PB03 NEOPIXEL 9 15 - - 5/1 6/1 - - + 17 PA17 SCK 1 - - 1/1 3/0 2/1 1/1 0/5 + 13 PA13 SCL 13 - - 2/1 4/0 2/1 0/7 1/3 + 12 PA12 SDA 12 - - 2/0 4/1 2/0 0/6 1/2 + 30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 - + 31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 - + 24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 - + 25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - - + 33 PB01 VDIV 1 13 - - 5/3 7/1 - - + 0 PA00 - 0 - - - 1/0 2/0 - - + 1 PA01 - 1 - - - 1/1 2/1 - - + 6 PA06 - 6 6 - - 0/2 1/0 - - + 7 PA07 - 7 7 - - 0/3 1/1 - - + 15 PA15 - 15 - - 2/3 4/3 3/1 2/1 1/3 + 27 PA27 - 11 - - - - - - - + 32 PB00 - 9 12 - - 5/2 7/0 - - + 34 PB02 - 2 14 - - 5/0 6/0 2/2 - + 36 PB04 - 4 - 6 - - - - - + 37 PB05 - 5 - 7 - - - - - + 39 PB07 - 7 - 9 - - - - - + 44 PB12 - 12 - - 4/0 - 4/0 3/0 0/0 + 45 PB13 - 13 - - 4/1 - 4/1 3/1 0/1 + 46 PB14 - 14 - - 4/2 - 5/0 4/0 0/2 + 47 PB15 - 15 - - 4/3 - 5/1 4/1 0/3 + 62 PB30 - 14 - - 7/0 5/1 0/0 4/0 0/6 + 63 PB31 - 15 - - 7/1 5/0 0/1 4/1 0/7 +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`. + +The default devices at the board are: + +- UART 5 at pins 0/1, labelled RX/TX +- I2C 2 at pins 21/20, labelled SDA/SCL +- SPI 1 at pins 22/23/24, labelled MOSI, MISO and SCK +- DAC output on pins 14 and 15, labelled A0 and A1 + +SEEED XIAO pin assignment table +------------------------------- + +=== ==== ============ ==== ==== ====== ====== ====== ====== +Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC +=== ==== ============ ==== ==== ====== ====== ====== ====== + 2 PA02 A0_D0 2 0 - - - - + 4 PA04 A1_D1 4 4 - 0/0 0/0 - + 10 PA10 A2_D2 10 18 0/2 2/2 1/0 0/2 + 11 PA11 A3_D3 11 19 0/3 2/3 1/1 0/3 + 8 PA08 A4_D4 - 16 0/0 2/0 0/0 1/2 + 9 PA09 A5_D5 9 17 0/1 2/1 0/1 1/3 + 40 PB08 A6_D6 8 2 - 4/0 4/0 - + 41 PB09 A7_D7 9 3 - 4/1 4/1 - + 7 PA07 A8_D8 7 7 - 0/3 1/1 - + 5 PA05 A9_D9 5 5 - 0/1 0/1 - + 6 PA06 A10_D10 6 6 - 0/2 1/0 - + 18 PA18 RX_LED 2 - 1/2 3/2 3/0 0/2 + 30 PA30 SWCLK 10 - - 1/2 1/0 - + 31 PA31 SWDIO 11 - - 1/3 1/1 - + 19 PA19 TX_LED 3 - 1/3 3/3 3/1 0/3 + 24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2 + 25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3 + 17 PA17 USER_LED 1 - 1/1 3/1 2/1 0/7 + 0 PA00 - 0 - - 1/0 2/0 - + 1 PA01 - 1 - - 1/1 2/1 - + 3 PA03 - 3 1 - - - - + 12 PA12 - 12 - 2/0 4/0 2/0 0/6 + 13 PA13 - 13 - 2/1 4/1 2/0 0/7 + 14 PA14 - 14 - 2/2 4/2 3/0 0/4 + 15 PA15 - 15 - 2/3 4/3 3/1 0/5 + 16 PA16 - 0 - 1/0 3/0 2/0 0/6 + 20 PA20 - 4 - 5/2 3/2 7/0 0/4 + 21 PA21 - 5 - 5/3 3/3 7/1 0/7 + 22 PA22 - 6 - 3/0 5/0 4/0 0/4 + 23 PA23 - 7 - 3/1 5/1 4/1 0/5 + 27 PA27 - 15 - - - - - + 28 PA28 - 8 - - - - - + 34 PB02 - 2 10 - 5/0 6/0 - + 35 PB03 - 3 11 - 5/1 6/1 - + 42 PB10 - 10 - - 4/2 5/0 0/4 + 43 PB11 - 11 - - 4/3 5/1 0/5 + 54 PB22 - 6 - - 5/2 7/0 - + 55 PB23 - 7 - - 5/3 7/1 - +=== ==== ============ ==== ==== ====== ====== ====== ====== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`. + +The default devices at the board are: + +- UART 4 at pins 7/6, labelled A6_D6/A7_D7 +- I2C 2 at pins 4/5, labelled A4_D4/A5_D5 +- SPI 0 at pins 10/9/8, labelled A10_D10, A9_D9 and A8_D8 +- DAC output on pin 0, labelled A0_D0 + +Adafruit Feather M0 Express pin assignment table +------------------------------------------------ + +=== ==== ============ ==== ==== ====== ====== ====== ====== +Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC +=== ==== ============ ==== ==== ====== ====== ====== ====== + 2 PA02 A0 2 0 - - - - + 40 PB08 A1 8 2 - 4/0 4/0 - + 41 PB09 A2 9 3 - 4/1 4/1 - + 4 PA04 A3 4 4 - 0/0 0/0 - + 5 PA05 A4 5 5 - 0/1 0/1 - + 34 PB02 A5 2 10 - 5/0 6/0 - + 11 PA11 D0 11 19 0/3 2/3 1/1 0/3 + 10 PA10 D1 10 18 0/2 2/2 1/0 0/2 + 14 PA14 D2 14 - 2/2 4/2 3/0 0/4 + 9 PA09 D3 9 17 0/1 2/1 0/1 1/3 + 8 PA08 D4 - 16 0/0 2/0 0/0 1/2 + 15 PA15 D5 15 - 2/3 4/3 3/1 0/5 + 20 PA20 D6 4 - 5/2 3/2 7/0 0/4 + 21 PA21 D7 5 - 5/3 3/3 7/1 0/7 + 7 PA07 D9 7 7 - 0/3 1/1 - + 55 PB23 RX 7 - - 5/3 7/1 - + 54 PB22 TX 6 - - 5/2 7/0 - + 18 PA18 D10 2 - 1/2 3/2 3/0 0/2 + 16 PA16 D11 0 - 1/0 3/0 2/0 0/6 + 19 PA19 D12 3 - 1/3 3/3 3/1 0/3 + 17 PA17 D13 1 - 1/1 3/1 2/1 0/7 + 13 PA13 FLASH_CS 13 - 2/1 4/1 2/0 0/7 + 35 PB03 LED_RX 3 11 - 5/1 6/1 - + 27 PA27 LED_TX 15 - - - - - + 12 PA12 MISO 12 - 2/0 4/0 2/0 0/6 + 42 PB10 MOSI 10 - - 4/2 5/0 0/4 + 6 PA06 NEOPIXEL 6 6 - 0/2 1/0 - + 43 PB11 SCK 11 - - 4/3 5/1 0/5 + 23 PA23 SCL 7 - 3/1 5/1 4/1 0/5 + 22 PA22 SDA 6 - 3/0 5/0 4/0 0/4 + 30 PA30 SWCLK 10 - - 1/2 1/0 - + 31 PA31 SWDIO 11 - - 1/3 1/1 - + 24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2 + 25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3 + 0 PA00 - 0 - - 1/0 2/0 - + 1 PA01 - 1 - - 1/1 2/1 - + 3 PA03 - 3 1 - - - - + 28 PA28 - 8 - - - - - +=== ==== ============ ==== ==== ====== ====== ====== ====== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`. + +The default devices at the board are: + +- UART 5 at pins 21/20, labelled RX/TX +- I2C 3 at pins 22/23, labelled SDA/SCL +- SPI 4 at pins 24/25/26, labelled MOSI, MISO and SCK +- DAC output on pin 14, labelled A0 + +Adafruit Trinket M0 pin assignment table +------------------------------------------------ + +=== ==== ============ ==== ==== ====== ====== ====== ====== +Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC +=== ==== ============ ==== ==== ====== ====== ====== ====== + 8 PA08 D0 - 16 0/0 2/0 0/0 1/2 + 2 PA02 D1 2 0 - - - - + 9 PA09 D2 9 17 0/1 2/1 0/1 1/3 + 7 PA07 D3 7 7 - 0/3 1/1 - + 6 PA06 D4 6 6 - 0/2 1/0 - + 1 PA01 DOTSTAR_CLK 1 - - 1/1 2/1 - + 0 PA00 DOTSTAR_DATA 0 - - 1/0 2/0 - + 10 PA10 LED 10 18 0/2 2/2 1/0 0/2 + 30 PA30 SWCLK 10 - - 1/2 1/0 - + 31 PA31 SWDIO 11 - - 1/3 1/1 - + 24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2 + 25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3 + 3 PA03 - 3 1 - - - - + 4 PA04 - 4 4 - 0/0 0/0 - + 5 PA05 - 5 5 - 0/1 0/1 - + 11 PA11 - 11 19 0/3 2/3 1/1 0/3 + 14 PA14 - 14 - 2/2 4/2 3/0 0/4 + 15 PA15 - 15 - 2/3 4/3 3/1 0/5 + 16 PA16 - 0 - 1/0 3/0 2/0 0/6 + 17 PA17 - 1 - 1/1 3/1 2/1 0/7 + 18 PA18 - 2 - 1/2 3/2 3/0 0/2 + 19 PA19 - 3 - 1/3 3/3 3/1 0/3 + 22 PA22 - 6 - 3/0 5/0 4/0 0/4 + 23 PA23 - 7 - 3/1 5/1 4/1 0/5 + 27 PA27 - 15 - - - - - + 28 PA28 - 8 - - - - - +=== ==== ============ ==== ==== ====== ====== ====== ====== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`. + +The default devices at the board are: + +- UART 0 at pins 3/4, labelled D3/D4 +- I2C 2 at pins 0/2, labelled D0/D2 +- SPI 0 at pins 4/2/3, labelled D4, D2 and D0 +- DAC output on pin 1, labelled D1 + +SAMD21 Xplained PRO pin assignment table +---------------------------------------- + +=== ==== ============ ==== ==== ====== ====== ====== ====== +Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC +=== ==== ============ ==== ==== ====== ====== ====== ====== + 32 PB00 EXT1_PIN3 0 8 - 5/2 7/0 - + 33 PB01 EXT1_PIN4 1 9 - 5/3 7/1 - + 38 PB06 EXT1_PIN5 6 14 - - - - + 39 PB07 EXT1_PIN6 7 15 - - - - + 34 PB02 EXT1_PIN7 2 10 - 5/0 6/0 - + 35 PB03 EXT1_PIN8 3 11 - 5/1 6/1 - + 36 PB04 EXT1_PIN9 4 12 - - - - + 37 PB05 EXT1_PIN10 5 13 - - - - + 8 PA08 EXT1_PIN11 - 16 0/0 2/0 0/0 1/2 + 9 PA09 EXT1_PIN12 9 17 0/1 2/1 0/1 1/3 + 41 PB09 EXT1_PIN13 9 3 - 4/1 4/1 - + 40 PB08 EXT1_PIN14 8 2 - 4/0 4/0 - + 5 PA05 EXT1_PIN15 5 5 - 0/1 0/1 - + 6 PA06 EXT1_PIN16 6 6 - 0/2 1/0 - + 4 PA04 EXT1_PIN17 4 4 - 0/0 0/0 - + 7 PA07 EXT1_PIN18 7 7 - 0/3 1/1 - + 10 PA10 EXT2_PIN3 10 18 0/2 2/2 1/0 0/2 + 11 PA11 EXT2_PIN4 11 19 0/3 2/3 1/1 0/3 + 20 PA20 EXT2_PIN5 4 - 5/2 3/2 7/0 0/4 + 21 PA21 EXT2_PIN6 5 - 5/3 3/3 7/1 0/7 + 44 PB12 EXT2_PIN7 12 - 4/0 - 4/0 0/6 + 45 PB13 EXT2_PIN8 13 - 4/1 - 4/1 0/7 + 46 PB14 EXT2_PIN9 14 - 4/2 - 5/0 - + 47 PB15 EXT2_PIN10 15 - 4/3 - 5/1 - + 43 PB11 EXT2_PIN13 11 - - 4/3 5/1 0/5 + 42 PB10 EXT2_PIN14 10 - - 4/2 5/0 0/4 + 17 PA17 EXT2_PIN15 1 - 1/1 3/1 2/1 0/7 + 18 PA18 EXT2_PIN16 2 - 1/2 3/2 3/0 0/2 + 16 PA16 EXT2_PIN17 0 - 1/0 3/0 2/0 0/6 + 19 PA19 EXT2_PIN18 3 - 1/3 3/3 3/1 0/3 + 2 PA02 EXT3_PIN3 2 0 - - - - + 3 PA03 EXT3_PIN4 3 1 - - - - + 15 PA15 EXT3_PIN6 15 - 2/3 4/3 3/1 0/5 + 12 PA12 EXT3_PIN7 12 - 2/0 4/0 2/0 0/6 + 13 PA13 EXT3_PIN8 13 - 2/1 4/1 2/0 0/7 + 28 PA28 EXT3_PIN9 8 - - - - - + 27 PA27 EXT3_PIN10 15 - - - - - + 49 PB17 EXT3_PIN15 1 - 5/1 - 6/1 0/5 + 54 PB22 EXT3_PIN16 6 - - 5/2 7/0 - + 48 PB16 EXT3_PIN17 9 - 5/0 - 6/0 0/4 + 55 PB23 EXT3_PIN18 7 - - 5/3 7/1 - + 62 PB30 LED 14 - - 5/0 0/0 1/2 + 30 PA30 SWCLK 10 - - 1/2 1/0 - + 31 PA31 SWDIO 11 - - 1/3 1/1 - + 24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2 + 25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3 + 0 PA00 - 0 - - 1/0 2/0 - + 1 PA01 - 1 - - 1/1 2/1 - + 14 PA14 - 14 - 2/2 4/2 3/0 0/4 + 22 PA22 - 6 - 3/0 5/0 4/0 0/4 + 23 PA23 - 7 - 3/1 5/1 4/1 0/5 + 63 PB31 - 15 - - 5/1 0/1 1/3 +=== ==== ============ ==== ==== ====== ====== ====== ====== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`. + +There are no pins labelled for default devices on this board. DAC output +is on pin 32, labelled EXT3_PIN3 + +Minisam M4 pin assignment table +------------------------------- + +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== +Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + 16 PA16 D0 0 - - 1/0 3/1 2/0 1/0 0/4 + 17 PA17 D1 1 - - 1/1 3/0 2/1 1/1 0/5 + 19 PA19 D3 3 - - 1/3 3/3 3/1 1/3 0/7 + 20 PA20 D4 4 - - 5/2 3/2 7/0 1/4 0/0 + 21 PA21 D5 5 - - 5/3 3/3 7/1 1/5 0/1 + 2 PA02 A0_D9 2 0 - - - - - - + 40 PB08 A1_D10 8 2 0 - 4/0 4/0 - - + 41 PB09 A2_D11 9 3 1 - 4/1 4/1 - - + 4 PA04 A3_D12 4 4 - - 0/0 0/0 - - + 5 PA05 A4_D13 5 5 - - 0/1 0/1 - - + 6 PA06 A5 6 6 - - 0/2 1/0 - - + 7 PA07 A6_D2 7 7 - - 0/3 1/1 - - + 3 PA03 AREF 3 10 - - - - - - + 0 PA00 BUTTON 0 - - - 1/0 2/0 - - + 34 PB02 DOTSTAR_CLK 2 14 - - 5/0 6/0 2/2 - + 35 PB03 DOTSTAR_DATA 9 15 - - 5/1 6/1 - - + 15 PA15 LED 15 - - 2/3 4/3 3/1 2/1 1/3 + 55 PB23 MISO 7 - - 1/3 5/3 7/1 - - + 54 PB22 MOSI 22 - - 1/2 5/2 7/0 - - + 1 PA01 SCK 1 - - - 1/1 2/1 - - + 13 PA13 SCL 13 - - 2/1 4/0 2/1 0/7 1/3 + 12 PA12 SDA 12 - - 2/0 4/1 2/0 0/6 1/2 + 30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 - + 31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 - + 24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 - + 25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - - + 8 PA08 - - 8 2 0/0 2/1 0/0 0/0 1/4 + 9 PA09 - 9 9 3 0/1 2/0 0/1 0/1 1/5 + 10 PA10 - 10 10 - 0/2 2/2 1/0 0/2 1/6 + 11 PA11 - 11 11 - 0/3 2/3 1/1 0/3 1/7 + 14 PA14 - 14 - - 2/2 4/2 3/0 2/0 1/2 + 18 PA18 - 2 - - 1/2 3/2 3/0 1/2 0/6 + 22 PA22 - 6 - - 3/0 5/1 4/0 1/6 0/2 + 23 PA23 - 7 - - 3/1 5/0 4/1 1/7 0/3 + 27 PA27 - 11 - - - - - - - + 42 PB10 - 10 - - - 4/2 5/0 0/4 1/0 + 43 PB11 - 12 - - - 4/3 5/1 0/5 1/1 +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`. + +The default devices at the board are: + +- UART 1 at pins 6/7, labelled D0/D1 +- I2C 2 at pins 14/15, labelled SDA/SCL +- SPI 1 at pins 16/17/18, labelled MOSI, MISO and SCK +- DAC output on pins 0 and 4, labelled A0_D9 and A4_D13 + +Seeed WIO Terminal pin assignment table +--------------------------------------- + +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== +Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + 33 PB01 CS 1 13 - - 5/3 7/1 - - + 59 PB27 RX 13 - - 2/1 4/0 - 1/3 - + 58 PB26 TX 12 - - 2/0 4/1 - 1/2 - + 79 PC15 3V3_ENABLE 15 - - 7/3 6/3 - 0/5 1/1 + 78 PC14 5V_ENABLE 14 - - 7/2 6/2 - 0/4 1/0 + 40 PB08 A0_D0 8 2 0 - 4/0 4/0 - - + 41 PB09 A1_D1 9 3 1 - 4/1 4/1 - - + 7 PA07 A2_D2 7 7 - - 0/3 1/1 - - + 36 PB04 A3_D3 4 - 6 - - - - - + 37 PB05 A4_D4 5 - 7 - - - - - + 38 PB06 A5_D5 6 - 8 - - - - - + 4 PA04 A6_D6 4 4 - - 0/0 0/0 - - + 39 PB07 A7_D7 7 - 9 - - - - - + 6 PA06 A8_D8 6 6 - - 0/2 1/0 - - + 90 PC26 BUTTON_1 10 - - - - - - - + 91 PC27 BUTTON_2 11 - - 1/0 - - - - + 92 PC28 BUTTON_3 12 - - 1/1 - - - - +107 PD11 BUZZER 6 - - 7/3 6/3 - 0/4 - + 47 PB15 GPCLK0 15 - - 4/3 - 5/1 4/1 0/3 + 44 PB12 GPCLK1 12 - - 4/0 - 4/0 3/0 0/0 + 45 PB13 GPCLK2 13 - - 4/1 - 4/1 3/1 0/1 + 48 PB16 I2C_BCLK 0 - - 5/0 - 6/0 3/0 0/4 + 20 PA20 I2S_LRCLK 4 - - 5/2 3/2 7/0 1/4 0/0 + 21 PA21 I2S_SDIN 5 - - 5/3 3/3 7/1 1/5 0/1 + 22 PA22 I2S_SDOUT 6 - - 3/0 5/1 4/0 1/6 0/2 + 50 PB18 LCD_MISO 2 - - 5/2 7/2 - 1/0 - + 51 PB19 LCD_MOSI 3 - - 5/3 7/3 - 1/1 - + 52 PB20 LCD_SCK 4 - - 3/0 7/1 - 1/2 - + 53 PB21 LCD_CS 5 - - 3/1 7/0 - 1/3 - + 70 PC06 LCD_D/C 6 - - 6/2 - - - - + 71 PC07 LCD_RESET 9 - - 6/3 - - - - + 74 PC10 LCD_XL 10 - - 6/2 7/2 - 0/0 1/4 + 76 PC12 LCD_XR 12 - - 7/0 6/1 - 0/2 1/6 + 77 PC13 LCD_YD 13 - - 7/1 6/0 - 0/3 1/7 + 75 PC11 LCD_YU 11 - - 6/3 7/3 - 0/1 1/5 + 15 PA15 LED_BLUE 15 - - 2/3 4/3 3/1 2/1 1/3 + 69 PC05 LED_LCD 5 - - 6/1 - - - - + 94 PC30 MIC 14 - 12 - - - - - + 32 PB00 MISO 9 12 - - 5/2 7/0 - - + 34 PB02 MOSI 2 14 - - 5/0 6/0 2/2 - + 35 PB03 SCK 9 15 - - 5/1 6/1 - - + 12 PA12 SCL0 12 - - 2/0 4/1 2/0 0/6 1/2 + 13 PA13 SDA0 13 - - 2/1 4/0 2/1 0/7 1/3 + 16 PA16 SCL1 0 - - 1/0 3/1 2/0 1/0 0/4 + 17 PA17 SDA1 1 - - 1/1 3/0 2/1 1/1 0/5 +117 PD21 SD_DET 11 - - 1/3 3/3 - 1/1 - + 83 PC19 SD_CS 3 - - 6/3 0/3 - 0/3 - + 82 PC18 SD_MISO 2 - - 6/2 0/2 - 0/2 - + 80 PC16 SD_MOSI 0 - - 6/0 0/1 - 0/0 - + 81 PC17 SD_SCK 1 - - 6/1 0/0 - 0/1 - + 30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 - + 31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 - +108 PD12 SWITCH_B 7 - - - - - 0/5 - +116 PD20 SWITCH_U 10 - - 1/2 3/2 - 1/0 - +104 PD08 SWITCH_X 3 - - 7/0 6/1 - 0/1 - +105 PD09 SWITCH_Y 4 - - 7/1 6/0 - 0/2 - +106 PD10 SWITCH_Z 5 - - 7/2 6/2 - 0/3 - + 24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 - + 25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - - + 0 PA00 - 0 - - - 1/0 2/0 - - + 1 PA01 - 1 - - - 1/1 2/1 - - + 2 PA02 - 2 0 - - - - - - + 3 PA03 - 3 10 - - - - - - + 5 PA05 - 5 5 - - 0/1 0/1 - - + 8 PA08 - - 8 2 0/0 2/1 0/0 0/0 1/4 + 9 PA09 - 9 9 3 0/1 2/0 0/1 0/1 1/5 + 10 PA10 - 10 10 - 0/2 2/2 1/0 0/2 1/6 + 11 PA11 - 11 11 - 0/3 2/3 1/1 0/3 1/7 + 14 PA14 - 14 - - 2/2 4/2 3/0 2/0 1/2 + 18 PA18 - 2 - - 1/2 3/2 3/0 1/2 0/6 + 19 PA19 - 3 - - 1/3 3/3 3/1 1/3 0/7 + 23 PA23 - 7 - - 3/1 5/0 4/1 1/7 0/3 + 27 PA27 - 11 - - - - - - - + 42 PB10 - 10 - - - 4/2 5/0 0/4 1/0 + 43 PB11 - 12 - - - 4/3 5/1 0/5 1/1 + 46 PB14 - 14 - - 4/2 - 5/0 4/0 0/2 + 49 PB17 - 1 - - 5/1 - 6/1 3/1 0/5 + 54 PB22 - 22 - - 1/2 5/2 7/0 - - + 55 PB23 - 7 - - 1/3 5/3 7/1 - - + 56 PB24 - 8 - - 0/0 2/1 - - - + 57 PB25 - 9 - - 0/1 2/0 - - - + 60 PB28 - 14 - - 2/2 4/2 - 1/4 - + 61 PB29 - 15 - - 2/3 4/3 - 1/5 - + 62 PB30 - 14 - - 7/0 5/1 0/0 4/0 0/6 + 63 PB31 - 15 - - 7/1 5/0 0/1 4/1 0/7 + 64 PC00 - 0 - 10 - - - - - + 65 PC01 - 1 - 11 - - - - - + 66 PC02 - 2 - 4 - - - - - + 67 PC03 - 3 - 5 - - - - - + 68 PC04 - 4 - - 6/0 - - 0/0 - + 84 PC20 - 4 - - - - - 0/4 - + 85 PC21 - 5 - - - - - 0/5 - + 86 PC22 - 6 - - 1/0 3/1 - 0/5 - + 87 PC23 - 7 - - 1/1 3/0 - 0/7 - + 88 PC24 - 8 - - 0/2 2/2 - - - + 89 PC25 - 9 - - 0/3 2/3 - - - + 95 PC31 - 15 - 13 - - - - - + 96 PD00 - 0 - 14 - - - - - + 97 PD01 - 1 - 15 - - - - - +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`. + +There seems to be no default pin assignment for this board. + +Sparkfun SAMD51 Thing Plus pin assignment table +------------------------------------------------ + +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== +Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + 2 PA02 A0 2 0 - - - - - - + 40 PB08 A1 8 2 0 - 4/0 4/0 - - + 41 PB09 A2 9 3 1 - 4/1 4/1 - - + 4 PA04 A3 4 4 - - 0/0 0/0 - - + 5 PA05 A4 5 5 - - 0/1 0/1 - - + 34 PB02 A5 2 14 - - 5/0 6/0 2/2 - + 13 PA13 D0 13 - - 2/1 4/0 2/1 0/7 1/3 + 12 PA12 D1 12 - - 2/0 4/1 2/0 0/6 1/2 + 6 PA06 D4 6 6 - - 0/2 1/0 - - + 15 PA15 D5 15 - - 2/3 4/3 3/1 2/1 1/3 + 20 PA20 D6 4 - - 5/2 3/2 7/0 1/4 0/0 + 21 PA21 D7 5 - - 5/3 3/3 7/1 1/5 0/1 + 7 PA07 D9 7 7 - - 0/3 1/1 - - + 18 PA18 D10 2 - - 1/2 3/2 3/0 1/2 0/6 + 16 PA16 D11 0 - - 1/0 3/1 2/0 1/0 0/4 + 19 PA19 D12 3 - - 1/3 3/3 3/1 1/3 0/7 + 17 PA17 D13 1 - - 1/1 3/0 2/1 1/1 0/5 + 10 PA10 FLASH_CS 10 10 - 0/2 2/2 1/0 0/2 1/6 + 11 PA11 FLASH_MISO 11 11 - 0/3 2/3 1/1 0/3 1/7 + 8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4 + 9 PA09 FLASH_SCK 9 9 3 0/1 2/0 0/1 0/1 1/5 + 43 PB11 MISO 12 - - - 4/3 5/1 0/5 1/1 + 44 PB12 MOSI 12 - - 4/0 - 4/0 3/0 0/0 + 55 PB23 RXD 7 - - 1/3 5/3 7/1 - - + 35 PB03 RXLED 9 15 - - 5/1 6/1 - - + 45 PB13 SCK 13 - - 4/1 - 4/1 3/1 0/1 + 23 PA23 SCL 7 - - 3/1 5/0 4/1 1/7 0/3 + 22 PA22 SDA 6 - - 3/0 5/1 4/0 1/6 0/2 + 30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 - + 31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 - + 54 PB22 TXD 22 - - 1/2 5/2 7/0 - - + 27 PA27 TXLED 11 - - - - - - - + 24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 - + 25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - - + 0 PA00 - 0 - - - 1/0 2/0 - - + 1 PA01 - 1 - - - 1/1 2/1 - - + 3 PA03 - 3 10 - - - - - - + 14 PA14 - 14 - - 2/2 4/2 3/0 2/0 1/2 + 32 PB00 - 9 12 - - 5/2 7/0 - - + 33 PB01 - 1 13 - - 5/3 7/1 - - + 36 PB04 - 4 - 6 - - - - - + 37 PB05 - 5 - 7 - - - - - + 38 PB06 - 6 - 8 - - - - - + 39 PB07 - 7 - 9 - - - - - + 42 PB10 - 10 - - - 4/2 5/0 0/4 1/0 + 46 PB14 - 14 - - 4/2 - 5/0 4/0 0/2 + 47 PB15 - 15 - - 4/3 - 5/1 4/1 0/3 + 48 PB16 - 0 - - 5/0 - 6/0 3/0 0/4 + 49 PB17 - 1 - - 5/1 - 6/1 3/1 0/5 + 62 PB30 - 14 - - 7/0 5/1 0/0 4/0 0/6 + 63 PB31 - 15 - - 7/1 5/0 0/1 4/1 0/7 +=== ==== ============ ==== ==== ==== ====== ====== ===== ===== ===== + +For the definition of the table columns see the explanation at the table for +Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`. + +The default devices at the board are: + +- UART 1 at pins 2/3, labelled RXD/TXD +- I2C 5 at pins 20/21, labelled SDA/SCL +- SPI 4 at pins 22/23/24, labelled MOSI, MISO and SCK +- DAC output on pins 14 and 18, labelled A0 and A4 + +Scripts for creating the pin assignment tables +---------------------------------------------- + +The tables shown above were created with small a Python script running on the target board:: + + from samd import pininfo + from machine import Pin + import os + + def print_entry(e, txt): + print(txt, end=": ") + if e == 255: + print(" - ", end="") + else: + print("%d/%d" % (e >> 4, e & 0x0f), end="") + + def print_pininfo(pin, info): + print("%3d" % pin, end=" ") + print("P%c%02d" % ("ABCD"[pin // 32], pin % 32), end="") + print(" %12s" % info[0], end="") + print(" IRQ:%2s" % (info[1] if info[1] != 255 else "-"), end="") + print(" ADC0:%2s" % (info[2] if info[2] != 255 else "-"), end="") + if len(info) == 7: + print_entry(info[3], " Serial1") + print_entry(info[4], " Serial2") + print_entry(info[5], " PWM1" if (info[5] >> 4) < 3 else " TC") + print_entry(info[6], " PWM2") + else: + print(" ADC1:%2s" % (info[3] if info[3] != 255 else "-"), end="") + print_entry(info[4], " Serial1") + print_entry(info[5], " Serial2") + print_entry(info[6], " TC") + print_entry(info[7], " PWM1") + print_entry(info[8], " PWM2") + print() + + def tblkey(i): + name = i[1][0] + if name != "-": + if len(name) < 3: + return " " + name + else: + return name + else: + return "zzzzzzz%03d" % i[0] + + def table(num = 127): + pintbl = [] + for i in range(num): + try: + pintbl.append((i, pininfo(i))) + except: + pass + # print("not defined") + + pintbl.sort(key=tblkey) + for item in pintbl: + print_pininfo(item[0], item[1]) + + table() diff --git a/docs/samd/quickref.rst b/docs/samd/quickref.rst new file mode 100644 index 000000000000..5e8298d1b366 --- /dev/null +++ b/docs/samd/quickref.rst @@ -0,0 +1,469 @@ +.. _samd_quickref: + +Quick reference for the SAMD21/SAMD51 family +============================================ + +.. image:: img/itsybitsy_m4_express.jpg + :alt: Adafruit ItsyBitsy M4 Express board + :width: 640px + +The Adafruit ItsyBitsy M4 Express board. + +Below is a quick reference for SAMD21/SAMD51-based boards. If it is your first time +working with this board it may be useful to get an overview of the microcontroller: + +.. toctree:: + :maxdepth: 1 + + general.rst + tutorial/intro.rst + pinout.rst + + +Installing MicroPython +---------------------- + +See the corresponding section of tutorial: :ref:`samd_intro`. It also includes +a troubleshooting subsection. + +General board control +--------------------- + +The MicroPython REPL is on the USB port, configured in VCP mode. +Tab-completion is useful to find out what methods an object has. +Paste mode (Ctrl-E) is useful to paste a large slab of Python code into +the REPL. + +The :mod:`machine` module:: + + import machine + + machine.freq() # get the current frequency of the CPU + machine.freq(96_000_000) # set the CPU frequency to 96 MHz + +The range accepted by the function call is 1_000_000 to 200_000_000 (1 MHz to 200 MHz) +for SAMD51 and 1_000_000 to 48_000_000 (1 MHz to 48 MHz) for SAMD21. The safe +range for SAMD51 according to the data sheet is 96 MHz to 120 MHz. +At frequencies below 8 MHz USB will be disabled. Changing the frequency below 48 MHz +impacts the baud rates of UART, I2C and SPI. These have to be set again after +changing the CPU frequency. The ms and µs timers are not affected by the frequency +change. + + +Delay and timing +---------------- + +Use the :mod:`time

MicroPython documentation

Quick reference for the Renesas RA
general information for Renesas RA based boards, snippets of useful code, and a tutorial

+ From c138e10fbb60981ca9e9b7459e7b9ae0c2528c94 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 27 Oct 2022 12:57:10 +1100 Subject: [PATCH 1917/4290] py/makeversionhdr: Fall back to py/mpconfig.h instead of docs/conf.py. Commit 64af916c111b61bce82c00f356a6b1cb81946d87 removed the version string from docs/conf.py. py/mpconfig.h is a better place to get the version from, so use that (when there is no git repository). Signed-off-by: Damien George --- py/makeversionhdr.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index 54b7fa9ab7d2..d1b41e63b084 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -62,21 +62,27 @@ def get_version_info_from_git(): return git_tag, git_hash -def get_version_info_from_docs_conf(): - with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "docs", "conf.py")) as f: +def get_version_info_from_mpconfig(): + with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "py", "mpconfig.h")) as f: for line in f: - if line.startswith("version = release = '"): - ver = line.strip().split(" = ")[2].strip("'") - git_tag = "v" + ver + if line.startswith("#define MICROPY_VERSION_MAJOR "): + ver_major = int(line.strip().split()[2]) + elif line.startswith("#define MICROPY_VERSION_MINOR "): + ver_minor = int(line.strip().split()[2]) + elif line.startswith("#define MICROPY_VERSION_MICRO "): + ver_micro = int(line.strip().split()[2]) + git_tag = "v%d.%d" % (ver_major, ver_minor) + if ver_micro != 0: + git_tag += ".%d" % (ver_micro,) return git_tag, "" return None def make_version_header(filename): - # Get version info using git, with fallback to docs/conf.py + # Get version info using git, with fallback to py/mpconfig.h info = get_version_info_from_git() if info is None: - info = get_version_info_from_docs_conf() + info = get_version_info_from_mpconfig() git_tag, git_hash = info From e20bb98392c988a410ba04d01d3f573e6c15803d Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 15 Oct 2022 21:37:51 +0200 Subject: [PATCH 1918/4290] mimxrt/machine_pin: Add the Pin.toggle() method. For consistency with other ports, even if this method is undocumented at the moment. --- ports/mimxrt/machine_pin.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 836bd8524b72..bb2c820100be 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -285,6 +285,14 @@ STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on); +// pin.toggle() +STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { + machine_pin_obj_t *self = self_in; + mp_hal_pin_toggle(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle); + // pin.value([value]) STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { return machine_pin_obj_call(args[0], (n_args - 1), 0, args + 1); @@ -366,6 +374,7 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) }, { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_pin_off_obj) }, { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_on_obj) }, + { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) }, { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) }, { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) }, From 9d2e179fa565d8af96fb6ce3643e00f999c9210a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 22 Oct 2022 21:28:42 +0200 Subject: [PATCH 1919/4290] mimxrt: Fix CPU freeze when calling __WFE() in MICROPY_EVENT_POLL_HOOK. This issue affected i.MX RT 1052, 1062 and 1064. It seems to be addressed by Errata ERR006223, which also mentions i.MX RT101x and 102x, but these devices worked well even without the change. As a side effect, the current consumption at an idle REPL drops significantly with this fix. Fixes issue #7235. --- ports/mimxrt/boards/MIMXRT1052_clock_config.c | 1 + ports/mimxrt/boards/MIMXRT1062_clock_config.c | 1 + ports/mimxrt/boards/MIMXRT1064_clock_config.c | 1 + ports/mimxrt/mpconfigport.h | 1 + 4 files changed, 4 insertions(+) diff --git a/ports/mimxrt/boards/MIMXRT1052_clock_config.c b/ports/mimxrt/boards/MIMXRT1052_clock_config.c index 93492812977a..fa7450d487a6 100644 --- a/ports/mimxrt/boards/MIMXRT1052_clock_config.c +++ b/ports/mimxrt/boards/MIMXRT1052_clock_config.c @@ -465,4 +465,5 @@ void BOARD_BootClockRUN(void) { IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + CLOCK_SetMode(kCLOCK_ModeRun); } diff --git a/ports/mimxrt/boards/MIMXRT1062_clock_config.c b/ports/mimxrt/boards/MIMXRT1062_clock_config.c index 05474167bd85..589ffb0b5831 100644 --- a/ports/mimxrt/boards/MIMXRT1062_clock_config.c +++ b/ports/mimxrt/boards/MIMXRT1062_clock_config.c @@ -487,4 +487,5 @@ void BOARD_BootClockRUN(void) { IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + CLOCK_SetMode(kCLOCK_ModeRun); } diff --git a/ports/mimxrt/boards/MIMXRT1064_clock_config.c b/ports/mimxrt/boards/MIMXRT1064_clock_config.c index 5e49a2fff80e..56dd75d7fbf6 100644 --- a/ports/mimxrt/boards/MIMXRT1064_clock_config.c +++ b/ports/mimxrt/boards/MIMXRT1064_clock_config.c @@ -487,4 +487,5 @@ void BOARD_BootClockRUN(void) { IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + CLOCK_SetMode(kCLOCK_ModeRun); } diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 8642d53ecc45..3f87800e3056 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -241,6 +241,7 @@ extern const struct _mp_obj_type_t network_lan_type; do { \ extern void mp_handle_pending(bool); \ mp_handle_pending(true); \ + __WFE(); \ } while (0); #define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) From 65fa7fd8bbaf570be3f4654bcc597a46c70e4b75 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sat, 15 Oct 2022 11:40:22 +0200 Subject: [PATCH 1920/4290] mimxrt/machine_timer: Use soft-timer implementation for machine.Timer. This releases the hardware timers for other tasks, which need a higher resolution and faster response. And it is less port-specific code. --- docs/mimxrt/quickref.rst | 9 +- ports/mimxrt/Makefile | 1 + ports/mimxrt/board_init.c | 3 - ports/mimxrt/machine_timer.c | 158 +++++++++-------------------------- ports/mimxrt/main.c | 2 + ports/mimxrt/mphalport.h | 4 + ports/mimxrt/systick.c | 7 ++ 7 files changed, 58 insertions(+), 126 deletions(-) diff --git a/docs/mimxrt/quickref.rst b/docs/mimxrt/quickref.rst index c75fe60c8d66..06f91f7f5031 100644 --- a/docs/mimxrt/quickref.rst +++ b/docs/mimxrt/quickref.rst @@ -56,21 +56,18 @@ Use the :mod:`time