diff options
| author | DavePutz <dwputz@gmail.com> | 2021-02-08 10:39:26 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-08 10:39:26 -0600 |
| commit | cec921f3747beccff10c2d2dfbc237c305083f62 (patch) | |
| tree | 4fb9ed7d2dc50123b1d858a86f3556b4784405fa /ports | |
| parent | 6043fdf94085bf2ec00e9f95149a74fb7eb0c7c4 (diff) | |
| parent | 482e58307756bfec3cb7d4c0c8d73ffae0ec228d (diff) | |
Merge pull request #40 from adafruit/main
Update from adafruit main
Diffstat (limited to 'ports')
94 files changed, 1523 insertions, 351 deletions
diff --git a/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk b/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk index b5a4bc735..f976dfe78 100644 --- a/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk +++ b/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk @@ -22,7 +22,6 @@ CIRCUITPY_GAMEPAD = 1 CIRCUITPY_BUSDEVICE = 1 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ADXL34x diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk index d31d1f54a..36d463697 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk @@ -10,3 +10,4 @@ INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk index 7eb83a123..20307fc05 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk @@ -11,3 +11,5 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 +CFLAGS_INLINE_LIMIT = 40 diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk index a5722c9ad..697ec02c3 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk index 178258b6c..2ace30fb5 100755 --- a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk @@ -16,6 +16,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_VECTORIO = 0 +CIRCUITPY_BUSDEVICE = 0 MICROPY_PY_ASYNC_AWAIT = 0 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk index 505f5c145..0b150a5fb 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk @@ -22,7 +22,6 @@ SUPEROPT_GC = 0 CFLAGS_INLINE_LIMIT = 55 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk index c3be33134..ae0b6837c 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -22,11 +22,10 @@ CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 SUPEROPT_GC = 0 -CFLAGS_INLINE_LIMIT = 50 +CFLAGS_INLINE_LIMIT = 40 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index 4b0c324fa..1586a3289 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -43,5 +43,3 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 - -#define MICROPY_PY_URE 0 diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk index 51e9b05af..aace5c0cb 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk @@ -18,6 +18,7 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_RE = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 # So not all of displayio, sorry! @@ -27,7 +28,6 @@ SUPEROPT_GC = 0 CFLAGS_INLINE_LIMIT = 55 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk index 143910318..ab6c4ed99 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk index f06163b84..309563ff4 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk @@ -21,7 +21,6 @@ CFLAGS_INLINE_LIMIT = 50 CIRCUITPY_MSGPACK = 0 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk index 6e089bb90..6ea21ed82 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk @@ -28,5 +28,4 @@ CFLAGS_INLINE_LIMIT = 35 SUPEROPT_GC = 0 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM69 diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk index 383b6a6df..76a6be2e3 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk @@ -29,5 +29,4 @@ CFLAGS_INLINE_LIMIT = 35 SUPEROPT_GC = 0 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM9x diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk index 0345417a9..e1c0f4b9a 100644 --- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk @@ -20,4 +20,5 @@ endif ifeq ($(TRANSLATION), de_DE) RELEASE_NEEDS_CLEAN_BUILD = 1 CFLAGS_INLINE_LIMIT = 35 +SUPEROPT_VM = 0 endif diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 1931ceb9a..2b211abd4 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -27,7 +27,6 @@ CFLAGS_INLINE_LIMIT = 55 SUPEROPT_GC = 0 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk index 4895cda77..58d4e4980 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk @@ -10,3 +10,5 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 3 EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C" LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk index b7b8073ab..a82362b8d 100644 --- a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk @@ -21,7 +21,6 @@ CIRCUITPY_GAMEPAD = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD diff --git a/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk index f49bb3fef..3bf42d705 100644 --- a/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk @@ -21,7 +21,6 @@ CIRCUITPY_GAMEPAD = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD diff --git a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk index 964cbe643..e100e2da6 100644 --- a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk @@ -11,14 +11,6 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk index 1dc686ef8..9ac24a014 100644 --- a/ports/atmel-samd/boards/sam32/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk @@ -13,5 +13,4 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_USTACK = 1 -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk b/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk index bedec87f4..6bbd84235 100644 --- a/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk +++ b/ports/atmel-samd/boards/seeeduino_xiao/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/serpente/mpconfigboard.mk b/ports/atmel-samd/boards/serpente/mpconfigboard.mk index 6e953adf7..09036875f 100644 --- a/ports/atmel-samd/boards/serpente/mpconfigboard.mk +++ b/ports/atmel-samd/boards/serpente/mpconfigboard.mk @@ -14,6 +14,7 @@ LONGINT_IMPL = NONE CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_BUSDEVICE = 0 SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/board.c b/ports/atmel-samd/boards/silicognition-m4-shim/board.c new file mode 100644 index 000000000..5fca974e9 --- /dev/null +++ b/ports/atmel-samd/boards/silicognition-m4-shim/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/board.h" +#include "mpconfigboard.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.h b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.h new file mode 100644 index 000000000..5028679ed --- /dev/null +++ b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.h @@ -0,0 +1,33 @@ +#define MICROPY_HW_BOARD_NAME "Silicognition LLC M4-Shim" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// Rev E + +#define MICROPY_HW_LED_STATUS (&pin_PA23) +#define MICROPY_HW_NEOPIXEL (&pin_PB03) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk new file mode 100644 index 000000000..bf88cd52d --- /dev/null +++ b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x1209 +USB_PID = 0xF500 +USB_PRODUCT = "M4-Shim" +USB_MANUFACTURER = "Silicognition LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +CIRCUITPY_VECTORIO = 1 diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/pins.c b/ports/atmel-samd/boards/silicognition-m4-shim/pins.c new file mode 100644 index 000000000..b7afd044e --- /dev/null +++ b/ports/atmel-samd/boards/silicognition-m4-shim/pins.c @@ -0,0 +1,54 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PB08) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PB22) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk index e71bb0739..2e15bc042 100755 --- a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk @@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOIO = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_VECTORIO = 0 +CIRCUITPY_BUSDEVICE = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk index 735d42297..1f88fbead 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk @@ -11,14 +11,5 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 SUPEROPT_VM = 0 -endif +CFLAGS_INLINE_LIMIT = 45 diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index b1242d206..640d421e8 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -28,6 +28,7 @@ CIRCUITPY_RTC = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_USB_HID = 0 CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_BUSDEVICE = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/ugame10 diff --git a/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk b/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk index 3562228c7..d6f333b5b 100644 --- a/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk +++ b/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk @@ -24,4 +24,3 @@ CIRCUITPY_TOUCHIO=0 CIRCUITPY_BUSDEVICE=1 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk b/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk index 53908293f..fd2fa044a 100644 --- a/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk +++ b/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk @@ -27,5 +27,4 @@ CIRCUITPY_COUNTIO=0 CIRCUITPY_BUSDEVICE=1 # Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index ffe74a274..2551f7bf1 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -97,7 +97,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, if (!gpio_get_pin_level(sda->number) || !gpio_get_pin_level(scl->number)) { reset_pin_number(sda->number); reset_pin_number(scl->number); - mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); + mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring")); } #endif diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index bce89e0b9..d2a529485 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -45,11 +45,7 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_PY_FUNCTION_ATTRS (0) -// MICROPY_PY_UJSON depends on MICROPY_PY_IO -#define MICROPY_PY_IO (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) -#define MICROPY_PY_UBINASCII (0) -#define MICROPY_PY_UJSON (0) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) #define MICROPY_PY_UERRNO_LIST \ X(EPERM) \ @@ -84,9 +80,6 @@ #define SPI_FLASH_MAX_BAUDRATE 24000000 #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_FUNCTION_ATTRS (1) -// MICROPY_PY_UJSON depends on MICROPY_PY_IO -#define MICROPY_PY_IO (1) -#define MICROPY_PY_UJSON (1) // MICROPY_PY_UERRNO_LIST - Use the default #endif // SAM_D5X_E5X diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 17e3995bf..fb9cdf2e6 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -20,26 +20,16 @@ endif # Put samd21-only choices here. ifeq ($(CHIP_FAMILY),samd21) -# frequencyio not yet verified as working on SAMD21, though make it possible to override. -ifndef CIRCUITPY_AUDIOMIXER -CIRCUITPY_AUDIOMIXER = 0 -endif - -ifndef CIRCUITPY_AUDIOMP3 -CIRCUITPY_AUDIOMP3 = 0 -endif - -ifndef CIRCUITPY_BUILTINS_POW3 -CIRCUITPY_BUILTINS_POW3 = 0 -endif -ifndef CIRCUITPY_FREQUENCYIO -CIRCUITPY_FREQUENCYIO = 0 -endif +# The ?='s allow overriding in mpconfigboard.mk. -ifndef CIRCUITPY_TOUCHIO_USE_NATIVE -CIRCUITPY_TOUCHIO_USE_NATIVE = 1 -endif +CIRCUITPY_AUDIOMIXER ?= 0 +CIRCUITPY_BINASCII ?= 0 +CIRCUITPY_AUDIOMP3 ?= 0 +CIRCUITPY_BUILTINS_POW3 ?= 0 +CIRCUITPY_FREQUENCYIO ?= 0 +CIRCUITPY_JSON ?= 0 +CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 # No room for HCI _bleio on SAMD21. CIRCUITPY_BLEIO_HCI = 0 @@ -71,27 +61,13 @@ ifeq ($(CHIP_FAMILY),samd51) # No native touchio on SAMD51. CIRCUITPY_TOUCHIO_USE_NATIVE = 0 -# The ifndef's allow overriding in mpconfigboard.mk. - -ifndef CIRCUITPY_NETWORK -CIRCUITPY_NETWORK = 0 -endif - -ifndef CIRCUITPY_PS2IO -CIRCUITPY_PS2IO = 1 -endif - -ifndef CIRCUITPY_SAMD -CIRCUITPY_SAMD = 1 -endif - -ifndef CIRCUITPY_RGBMATRIX -CIRCUITPY_RGBMATRIX = $(CIRCUITPY_FULL_BUILD) -endif +# The ?='s allow overriding in mpconfigboard.mk. -ifndef CIRCUITPY_FRAMEBUFFERIO -CIRCUITPY_FRAMEBUFFERIO = $(CIRCUITPY_FULL_BUILD) -endif +CIRCUITPY_NETWORK ?= 0 +CIRCUITPY_PS2IO ?= 1 +CIRCUITPY_SAMD ?= 1 +CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD) +CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) endif # samd51 diff --git a/ports/cxd56/README.md b/ports/cxd56/README.md index 7fa439aac..c399b8a4d 100644 --- a/ports/cxd56/README.md +++ b/ports/cxd56/README.md @@ -75,7 +75,7 @@ Bootloader information: * You have to accept the End User License Agreement to be able to download and use the Spresense bootloader binary. -Download the spresense binaries zip archive from: [Spresense firmware v2-0-000](https://developer.sony.com/file/download/download-spresense-firmware-v2-0-000) +Download the spresense binaries zip archive from: [Spresense firmware v2-0-002](https://developer.sony.com/file/download/download-spresense-firmware-v2-0-002) Extract spresense binaries in your PC to ports/spresense/spresense-exported-sdk/firmware/ diff --git a/ports/cxd56/configs/circuitpython/defconfig b/ports/cxd56/configs/circuitpython/defconfig index a97f821df..096b53b80 100644 --- a/ports/cxd56/configs/circuitpython/defconfig +++ b/ports/cxd56/configs/circuitpython/defconfig @@ -165,6 +165,7 @@ CONFIG_USBDEV=y CONFIG_USBDEV_DMA=y CONFIG_USBDEV_DUALSPEED=y CONFIG_USEC_PER_TICK=1000 +CONFIG_USERMAIN_STACKSIZE=8192 CONFIG_USER_ENTRYPOINT="spresense_main" CONFIG_VIDEO_ISX012=y CONFIG_VIDEO_STREAM=y diff --git a/ports/cxd56/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk -Subproject 752c4cd56dd0a270a559c28272ceb61ddcb7806 +Subproject 2ec2a1538362696118dc3fdf56f33dacaf8f406 diff --git a/ports/cxd56/supervisor/internal_flash.c b/ports/cxd56/supervisor/internal_flash.c index 2726fa4a2..9c103fb19 100644 --- a/ports/cxd56/supervisor/internal_flash.c +++ b/ports/cxd56/supervisor/internal_flash.c @@ -30,10 +30,10 @@ /* Prototypes for Remote API */ -int FM_RawWrite(uint32_t offset, const void *buf, uint32_t size); -int FM_RawVerifyWrite(uint32_t offset, const void *buf, uint32_t size); -int FM_RawRead(uint32_t offset, void *buf, uint32_t size); -int FM_RawEraseSector(uint32_t sector); +int fw_fm_rawwrite(uint32_t offset, const void *buf, uint32_t size); +int fw_fm_rawverifywrite(uint32_t offset, const void *buf, uint32_t size); +int fw_fm_rawread(uint32_t offset, void *buf, uint32_t size); +int fw_fm_rawerasesector(uint32_t sector); #define CXD56_SPIFLASHSIZE (16 * 1024 * 1024) @@ -64,8 +64,8 @@ void port_internal_flash_flush(void) { return; } - FM_RawEraseSector(flash_sector); - FM_RawWrite(flash_sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE); + fw_fm_rawerasesector(flash_sector); + fw_fm_rawwrite(flash_sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE); flash_sector = NO_SECTOR; } @@ -73,7 +73,7 @@ void port_internal_flash_flush(void) { mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { supervisor_flash_flush(); - if (FM_RawRead(block << PAGE_SHIFT, dest, num_blocks << PAGE_SHIFT) < 0) { + if (fw_fm_rawread(block << PAGE_SHIFT, dest, num_blocks << PAGE_SHIFT) < 0) { return 1; } @@ -92,7 +92,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 if (sector != flash_sector) { supervisor_flash_flush(); - if (FM_RawRead(sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE) < 0) { + if (fw_fm_rawread(sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE) < 0) { return 1; } diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index aac934782..b4ff0612b 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -164,7 +164,9 @@ LIBS += -lm endif # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S2 -DCFG_TUSB_OS=OPT_OS_FREERTOS -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S2 -DCFG_TUSB_OS=OPT_OS_FREERTOS -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 +CFLAGS += -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 +CFLAGS += -DCFG_TUD_VENDOR_RX_BUFSIZE=128 -DCFG_TUD_VENDOR_TX_BUFSIZE=128 ###################################### diff --git a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk index 2dce03881..52c63cb9c 100644 --- a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk +++ b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk @@ -14,4 +14,10 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB +# We only have enough endpoints available in hardware to +# enable ONE of these at a time. +CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_VENDOR = 0 + CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c new file mode 100644 index 000000000..aaef97c7d --- /dev/null +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART +#ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); +#endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h new file mode 100644 index 000000000..c9020c200 --- /dev/null +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +//Micropython setup + +#define MICROPY_HW_BOARD_NAME "LILYGO TTGO T8 ESP32-S2 w/Display" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk new file mode 100644 index 000000000..38a7ed1fb --- /dev/null +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x303a +USB_PID = 0x8007 +USB_PRODUCT = "TTGO T8 ESP32-S2" +USB_MANUFACTURER = "LILYGO" +USB_DEVICES = "CDC,MSC,HID" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_MODULE = wroom diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c new file mode 100644 index 000000000..bda0fd227 --- /dev/null +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c @@ -0,0 +1,55 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO18) }, + + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO10) }, + + // 1.14 inch LCD ST7789 + { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO37) }, + + // Peripheral Power control + { MP_ROM_QSTR(MP_QSTR_PE_POWER), MP_ROM_PTR(&pin_GPIO14) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig new file mode 100644 index 000000000..ce6fe832b --- /dev/null +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig @@ -0,0 +1,31 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +CONFIG_SPIRAM_SPIWP_SD3_PIN=28 +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-T8-ESP32-S2" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of LWIP diff --git a/ports/esp32s2/common-hal/audiobusio/I2SOut.c b/ports/esp32s2/common-hal/audiobusio/I2SOut.c index 86322be86..eb9b6f8e1 100644 --- a/ports/esp32s2/common-hal/audiobusio/I2SOut.c +++ b/ports/esp32s2/common-hal/audiobusio/I2SOut.c @@ -63,6 +63,9 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self, self->bit_clock = bit_clock; self->word_select = word_select; self->data = data; + claim_pin(bit_clock); + claim_pin(word_select); + claim_pin(data); } bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self) { diff --git a/ports/esp32s2/common-hal/busio/I2C.c b/ports/esp32s2/common-hal/busio/I2C.c index 772262d0a..8372eb8c3 100644 --- a/ports/esp32s2/common-hal/busio/I2C.c +++ b/ports/esp32s2/common-hal/busio/I2C.c @@ -85,7 +85,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, if (gpio_get_level(sda->number) == 0 || gpio_get_level(scl->number) == 0) { reset_pin_number(sda->number); reset_pin_number(scl->number); - mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); + mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring")); } #endif diff --git a/ports/esp32s2/common-hal/displayio/ParallelBus.c b/ports/esp32s2/common-hal/displayio/ParallelBus.c index d0c98f361..f77b37b57 100644 --- a/ports/esp32s2/common-hal/displayio/ParallelBus.c +++ b/ports/esp32s2/common-hal/displayio/ParallelBus.c @@ -33,35 +33,196 @@ #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/microcontroller/__init__.h" +/* + * Current pin limitations for ESP32-S2 ParallelBus: + * - data0 pin must be byte aligned + */ + void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { - mp_raise_NotImplementedError(translate("ParallelBus not yet supported")); + uint8_t data_pin = data0->number; + if (data_pin % 8 != 0) { + mp_raise_ValueError(translate("Data 0 pin must be byte aligned.")); + } + + for (uint8_t i = 0; i < 8; i++) { + if (!pin_number_is_free(data_pin + i)) { + mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); + } + } + + gpio_dev_t *g = &GPIO; // this is the GPIO registers, see "extern gpio_dev_t GPIO" from file:gpio_struct.h + + // Setup the pins as "Simple GPIO outputs" see section 19.3.3 of the ESP32-S2 Reference Manual + // Enable pins with "enable_w1ts" + + for (uint8_t i = 0; i < 8; i++) { + g->enable_w1ts = (0x1 << (data_pin + i)); + g->func_out_sel_cfg[data_pin + i].val= 256; /* setup output pin for simple GPIO Output, (0x100 = 256) */ + + } + + /* From my understanding, there is a limitation of the ESP32-S2 that does not allow single-byte writes + * into the GPIO registers. See section 10.3.3 regarding "non-aligned writes" into the registers. + */ + + + if (data_pin < 31) { + self->bus = (uint32_t*) &g->out; //pointer to GPIO output register (for pins 0-31) + } else { + self->bus = (uint32_t*) &g->out1.val; //pointer to GPIO output register (for pins >= 32) + } + + /* SNIP - common setup of command, chip select, write and read pins, same as from SAMD and NRF ports */ + self->command.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + + self->chip_select.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->write.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->write, write); + common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + + if (write->number < 32) { + self->write_clear_register = (uint32_t*) &g->out_w1tc; + self->write_set_register = (uint32_t*) &g->out_w1ts; + } else { + self->write_clear_register = (uint32_t*) &g->out1_w1tc.val; + self->write_set_register = (uint32_t*) &g->out1_w1ts.val; + } + + // Check to see if the data and write pins are on the same register: + if ( ( ((self->data0_pin < 32) && (write->number < 32)) ) || + ( ((self->data0_pin > 31) && (write->number > 31)) ) ) { + self->data_write_same_register = true; // data pins and write pin are on the same register + } else { + self->data_write_same_register = false; // data pins and write pins are on different registers + } + + + self->write_mask = 1 << (write->number % 32); /* the write pin triggers the LCD to latch the data */ + + /* SNIP - common setup of the reset pin, same as from SAMD and NRF ports */ + self->reset.base.type = &mp_type_NoneType; + if (reset != NULL) { + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + common_hal_displayio_parallelbus_reset(self); + } + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + for (uint8_t i = 0; i < 8; i++) { + never_reset_pin_number(data_pin + i); + } + } void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + /* SNIP - same as from SAMD and NRF ports */ + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); } bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) { - return false; + /* SNIP - same as from SAMD and NRF ports */ + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + if (self->reset.base.type == &mp_type_NoneType) { + return false; + } + + common_hal_digitalio_digitalinout_set_value(&self->reset, false); + common_hal_mcu_delay_us(4); + common_hal_digitalio_digitalinout_set_value(&self->reset, true); + return true; + } bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) { - return false; + /* SNIP - same as from SAMD and NRF ports */ + return true; } bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { - - return false; + /* SNIP - same as from SAMD and NRF ports */ + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; } void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, - display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) { + display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA); + + uint32_t* clear_write = self->write_clear_register; + uint32_t* set_write = self->write_set_register; + + const uint32_t mask = self->write_mask; + + /* Setup structures for data writing. The ESP32-S2 port differs from the SAMD and NRF ports + * because I have not found a way to write a single byte into the ESP32-S2 registers. + * For the ESP32-S2, I create a 32-bit data_buffer that is used to transfer the data bytes. + */ + + *clear_write = mask; // Clear the write pin to prepare the registers before storing the + // register value into data_buffer + + const uint32_t data_buffer = *self->bus; // store the initial output register values into the data output buffer + uint8_t* data_address = ((uint8_t*) &data_buffer) + (self->data0_pin / 8); /* address inside data_buffer where + * each data byte will be written to the data pin registers + */ + + + if ( self->data_write_same_register ) { // data and write pins are on the same register + for (uint32_t i = 0; i < data_length; i++) { + + /* Note: If the write pin and data pins are controlled by the same GPIO register, we can eliminate + * the "clear_write" step below, since the write pin is cleared when the data_buffer is written + * to the bus. + */ + + *(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location + *self->bus = data_buffer; // write the data to the output register + *set_write = mask; // set the write pin + } + } + else { // data and write pins are on different registers + for (uint32_t i = 0; i < data_length; i++) { + *clear_write = mask; // clear the write pin (See comment above, this may not be necessary). + *(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location + *self->bus = data_buffer; // write the data to the output register + *set_write = mask; // set the write pin + + } + } } void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) { - + /* SNIP - same as from SAMD and NRF ports */ + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); } diff --git a/ports/esp32s2/common-hal/displayio/ParallelBus.h b/ports/esp32s2/common-hal/displayio/ParallelBus.h index cd636921d..84302118b 100644 --- a/ports/esp32s2/common-hal/displayio/ParallelBus.h +++ b/ports/esp32s2/common-hal/displayio/ParallelBus.h @@ -31,6 +31,17 @@ typedef struct { mp_obj_base_t base; + uint32_t* bus; // pointer where 8 bits of data are written to the display + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; // pin number for the lowest number data pin. Must be 8-bit aligned + bool data_write_same_register; // if data and write pins are in the sare + uint32_t* write_set_register; // pointer to the write group for setting the write bit to latch the data on the LCD + uint32_t* write_clear_register; // pointer to the write group for clearing the write bit to latch the data on the LCD + uint32_t write_mask; // bit mask for the single bit for the write pin register } displayio_parallelbus_obj_t; #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 5e943f8fd..1cdbc9058 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Lucian Copeland for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,140 +37,168 @@ #include "components/lwip/lwip/src/include/lwip/sys.h" #include "components/lwip/lwip/src/include/lwip/netdb.h" -void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { - self->timeout_ms = timeout_ms; -} +STATIC socketpool_socket_obj_t * open_socket_handles[CONFIG_LWIP_MAX_SOCKETS]; -bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, mp_uint_t hostlen, mp_int_t port) { - // For simplicity we use esp_tls for all TCP connections. If it's not SSL, ssl_context will be - // NULL and should still work. This makes regular TCP connections more memory expensive but TLS - // should become more and more common. Therefore, we optimize for the TLS case. - - esp_tls_cfg_t* tls_config = NULL; - if (self->ssl_context != NULL) { - tls_config = &self->ssl_context->ssl_config; - } - int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp); - self->connected = result >= 0; - if (result < 0) { - int esp_tls_code; - int flags; - esp_err_t err = esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, &flags); - - if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { - mp_raise_espidf_MemoryError(); - } else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { - mp_raise_OSError_msg_varg(translate("Failed SSL handshake")); - } else { - mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x %d"), esp_tls_code, flags, err, result); +void socket_reset(void) { + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) { + if (open_socket_handles[i]) { + if (open_socket_handles[i]->num > 0) { + // Close automatically clears socket handle + common_hal_socketpool_socket_close(open_socket_handles[i]); + } else { + open_socket_handles[i] = NULL; + } } - } else { - // Connection successful, set the timeout on the underlying socket. We can't rely on the IDF - // to do it because the config structure is only used for TLS connections. Generally, we - // shouldn't hit this timeout because we try to only read available data. However, there is - // always a chance that we try to read something that is used internally. - int fd; - esp_tls_get_conn_sockfd(self->tcp, &fd); - struct timeval tv; - tv.tv_sec = 2 * 60; // Two minutes - tv.tv_usec = 0; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); } - - return self->connected; } -bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self) { - return self->connected; -} - -mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { - size_t sent = esp_tls_conn_write(self->tcp, buf, len); - - if (sent < 0) { - mp_raise_OSError(MP_ENOTCONN); +bool register_open_socket(socketpool_socket_obj_t* self) { + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) { + if (open_socket_handles[i] == NULL) { + open_socket_handles[i] = self; + return true; + } } - return sent; + return false; } -mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { - size_t received = 0; - int status = 0; +socketpool_socket_obj_t* common_hal_socketpool_socket_accept(socketpool_socket_obj_t* self, + uint8_t* ip, uint *port) { + struct sockaddr_in accept_addr; + socklen_t socklen = sizeof(accept_addr); + int newsoc = -1; + bool timed_out = false; uint64_t start_ticks = supervisor_ticks_ms64(); - int sockfd; - esp_err_t err = esp_tls_get_conn_sockfd(self->tcp, &sockfd); - if (err != ESP_OK) { - mp_raise_OSError(MP_EBADF); - } - while (received == 0 && - status >= 0 && - (self->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) && + + // Allow timeouts and interrupts + while (newsoc == -1 && + !timed_out && !mp_hal_is_interrupted()) { - RUN_BACKGROUND_TASKS; - size_t available = esp_tls_get_bytes_avail(self->tcp); - if (available == 0) { - // This reads the raw socket buffer and is used for non-TLS connections - // and between encrypted TLS blocks. - status = lwip_ioctl(sockfd, FIONREAD, &available); + if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { + timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; } - size_t remaining = len - received; - if (available > remaining) { - available = remaining; + RUN_BACKGROUND_TASKS; + newsoc = lwip_accept(self->num, (struct sockaddr *)&accept_addr, &socklen); + // In non-blocking mode, fail instead of timing out + if (newsoc == -1 && self->timeout_ms == 0) { + mp_raise_OSError(MP_EAGAIN); } - if (available > 0) { - status = esp_tls_conn_read(self->tcp, (void*) buf + received, available); - if (status == 0) { - // Reading zero when something is available indicates a closed - // connection. (The available bytes could have been TLS internal.) - break; - } - if (status > 0) { - received += status; - } + } + + if (!timed_out) { + // harmless on failure but avoiding memcpy is faster + memcpy((void *)ip, (void*)&accept_addr.sin_addr.s_addr, sizeof(accept_addr.sin_addr.s_addr)); + *port = accept_addr.sin_port; + } else { + mp_raise_OSError(ETIMEDOUT); + } + + if (newsoc > 0) { + // Create the socket + socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); + sock->base.type = &socketpool_socket_type; + sock->num = newsoc; + sock->pool = self->pool; + + if (!register_open_socket(sock)) { + mp_raise_OSError(MP_EBADF); } + + lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); + return sock; + } else { + mp_raise_OSError(MP_EBADF); + return NULL; } +} - if (received == 0) { - // socket closed - common_hal_socketpool_socket_close(self); +bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t* self, + const char* host, size_t hostlen, uint8_t port) { + struct sockaddr_in bind_addr; + bind_addr.sin_addr.s_addr = inet_addr(host); + bind_addr.sin_family = AF_INET; + bind_addr.sin_port = htons(port); + + int opt = 1; + int err = lwip_setsockopt(self->num, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + if (err != 0) { + mp_raise_RuntimeError(translate("Cannot set socket options")); } - return received; + int result = lwip_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) == 0; + return result; } -mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self, - const char* host, size_t hostlen, uint8_t port, const uint8_t* buf, mp_uint_t len) { +void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { + self->connected = false; + if (self->num >= 0) { + lwip_shutdown(self->num, 0); + lwip_close(self->num); + self->num = -1; + } + // Remove socket record + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) { + if (open_socket_handles[i] == self) { + open_socket_handles[i] = NULL; + } + } +} - // Get the IP address string +bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, + const char* host, mp_uint_t hostlen, mp_int_t port) { const struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, }; - struct addrinfo *result; - int error = lwip_getaddrinfo(host, NULL, &hints, &result); - if (error != 0 || result == NULL) { - return 0; + struct addrinfo *result_i; + int error = lwip_getaddrinfo(host, NULL, &hints, &result_i); + if (error != 0 || result_i == NULL) { + mp_raise_OSError(EHOSTUNREACH); } + + // Set parameters + struct sockaddr_in dest_addr; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - struct in_addr *addr = &((struct sockaddr_in *)result->ai_addr)->sin_addr; + dest_addr.sin_addr.s_addr = ((struct sockaddr_in *)result_i->ai_addr)->sin_addr.s_addr; #pragma GCC diagnostic pop - char ip_str[IP4ADDR_STRLEN_MAX]; - inet_ntoa_r(*addr, ip_str, IP4ADDR_STRLEN_MAX); - freeaddrinfo(result); + freeaddrinfo(result_i); - // Set parameters - struct sockaddr_in dest_addr; - dest_addr.sin_addr.s_addr = inet_addr((const char *)ip_str); dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(port); - int bytes_sent = lwip_sendto(self->num, buf, len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); - if (bytes_sent < 0) { - mp_raise_BrokenPipeError(); - return 0; + // Replace above with function call ----- + + // Switch to blocking mode for this one call + int opts; + opts = lwip_fcntl(self->num,F_GETFL,0); + opts = opts & (~O_NONBLOCK); + lwip_fcntl(self->num, F_SETFL, opts); + + int result = -1; + result = lwip_connect(self->num, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in)); + + // Switch back once complete + opts = opts | O_NONBLOCK; + lwip_fcntl(self->num, F_SETFL, opts); + + if (result >= 0) { + self->connected = true; + return true; + } else { + mp_raise_OSError(errno); } - return bytes_sent; +} + +bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) { + return self->num < 0; +} + +bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self) { + return self->connected; +} + +bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t* self, int backlog) { + return lwip_listen(self->num, backlog) == 0; } mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* self, @@ -178,37 +206,122 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* se struct sockaddr_in source_addr; socklen_t socklen = sizeof(source_addr); - int bytes_received = lwip_recvfrom(self->num, buf, len, 0, (struct sockaddr *)&source_addr, &socklen); - memcpy((void *)ip, (void*)&source_addr.sin_addr.s_addr, sizeof source_addr.sin_addr.s_addr); - *port = source_addr.sin_port; + // LWIP Socket + uint64_t start_ticks = supervisor_ticks_ms64(); + int received = -1; + bool timed_out = false; + while (received == -1 && + !timed_out && + !mp_hal_is_interrupted()) { + if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { + timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; + } + RUN_BACKGROUND_TASKS; + received = lwip_recvfrom(self->num, buf, len, 0, (struct sockaddr *)&source_addr, &socklen); - if (bytes_received < 0) { + // In non-blocking mode, fail instead of looping + if (received == -1 && self->timeout_ms == 0) { + mp_raise_OSError(MP_EAGAIN); + } + } + + if (!timed_out) { + memcpy((void *)ip, (void*)&source_addr.sin_addr.s_addr, sizeof(source_addr.sin_addr.s_addr)); + *port = source_addr.sin_port; + } else { + mp_raise_OSError(ETIMEDOUT); + } + + if (received < 0) { mp_raise_BrokenPipeError(); return 0; } - return bytes_received; + return received; } -void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { - self->connected = false; - if (self->tcp != NULL) { - esp_tls_conn_destroy(self->tcp); - self->tcp = NULL; +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { + int received = 0; + bool timed_out = false; + + if (self->num != -1) { + // LWIP Socket + uint64_t start_ticks = supervisor_ticks_ms64(); + received = -1; + while (received == -1 && + !timed_out && + !mp_hal_is_interrupted()) { + if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { + timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; + } + RUN_BACKGROUND_TASKS; + received = lwip_recv(self->num, (void*) buf, len, 0); + + // In non-blocking mode, fail instead of looping + if (received == -1 && self->timeout_ms == 0) { + mp_raise_OSError(MP_EAGAIN); + } + } + } else { + mp_raise_OSError(MP_EBADF); } - if (self->num >= 0) { - lwip_shutdown(self->num, 0); - lwip_close(self->num); - self->num = -1; + + if (timed_out) { + mp_raise_OSError(ETIMEDOUT); } + return received; } -bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) { - return self->tcp == NULL && self->num < 0; +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { + int sent = -1; + if (self->num != -1) { + // LWIP Socket + // TODO: deal with potential failure/add timeout? + sent = lwip_send(self->num, buf, len, 0); + } else { + mp_raise_OSError(MP_EBADF); + } + + if (sent < 0) { + mp_raise_OSError(errno); + } + return sent; } +mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self, + const char* host, size_t hostlen, uint8_t port, const uint8_t* buf, mp_uint_t len) { + + // Set parameters + const struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + struct addrinfo *result_i; + int error = lwip_getaddrinfo(host, NULL, &hints, &result_i); + if (error != 0 || result_i == NULL) { + mp_raise_OSError(EHOSTUNREACH); + } + + // Set parameters + struct sockaddr_in dest_addr; + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + dest_addr.sin_addr.s_addr = ((struct sockaddr_in *)result_i->ai_addr)->sin_addr.s_addr; + #pragma GCC diagnostic pop + freeaddrinfo(result_i); + + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(port); -mp_uint_t common_hal_socketpool_socket_get_hash(socketpool_socket_obj_t* self) { - return self->num; + int bytes_sent = lwip_sendto(self->num, buf, len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); + if (bytes_sent < 0) { + mp_raise_BrokenPipeError(); + return 0; + } + return bytes_sent; +} + +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { + self->timeout_ms = timeout_ms; } diff --git a/ports/esp32s2/common-hal/socketpool/Socket.h b/ports/esp32s2/common-hal/socketpool/Socket.h index 62b5ded58..b86f5597c 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.h +++ b/ports/esp32s2/common-hal/socketpool/Socket.h @@ -37,11 +37,15 @@ typedef struct { mp_obj_base_t base; int num; + int type; + int family; + int ipproto; bool connected; - esp_tls_t* tcp; - ssl_sslcontext_obj_t* ssl_context; socketpool_socketpool_obj_t* pool; mp_uint_t timeout_ms; } socketpool_socket_obj_t; +void socket_reset(void); +bool register_open_socket(socketpool_socket_obj_t* self); + #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c index 3bec5f337..fbd6dca7a 100644 --- a/ports/esp32s2/common-hal/socketpool/SocketPool.c +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c @@ -25,6 +25,7 @@ */ #include "shared-bindings/socketpool/SocketPool.h" +#include "common-hal/socketpool/Socket.h" #include "py/runtime.h" #include "shared-bindings/wifi/__init__.h" @@ -65,27 +66,23 @@ socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_ mp_raise_NotImplementedError(translate("Only IPv4 sockets supported")); } + socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); + sock->base.type = &socketpool_socket_type; + sock->type = socket_type; + sock->family = addr_family; + sock->ipproto = ipproto; + sock->pool = self; + sock->timeout_ms = (uint)-1; + + // Create LWIP socket int socknum = -1; - esp_tls_t* tcp_handle = NULL; - if (socket_type == SOCK_DGRAM || socket_type == SOCK_RAW) { - socknum = lwip_socket(addr_family, socket_type, ipproto); - } else { - tcp_handle = esp_tls_init(); - - if (tcp_handle == NULL) { - mp_raise_espidf_MemoryError(); - } - } - if (socknum < 0 && tcp_handle == NULL) { + socknum = lwip_socket(sock->family, sock->type, sock->ipproto); + if (socknum < 0 || !register_open_socket(sock)) { mp_raise_RuntimeError(translate("Out of sockets")); } - - socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); - sock->base.type = &socketpool_socket_type; sock->num = socknum; - sock->tcp = tcp_handle; - sock->ssl_context = NULL; - sock->pool = self; + // Sockets should be nonblocking in most cases + lwip_fcntl(socknum, F_SETFL, O_NONBLOCK); return sock; } diff --git a/ports/esp32s2/common-hal/ssl/SSLContext.c b/ports/esp32s2/common-hal/ssl/SSLContext.c index e24fd338b..afc3ecce2 100644 --- a/ports/esp32s2/common-hal/ssl/SSLContext.c +++ b/ports/esp32s2/common-hal/ssl/SSLContext.c @@ -25,6 +25,9 @@ */ #include "shared-bindings/ssl/SSLContext.h" +#include "shared-bindings/ssl/SSLSocket.h" + +#include "bindings/espidf/__init__.h" #include "py/runtime.h" @@ -32,10 +35,26 @@ void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t* self) { } -socketpool_socket_obj_t* common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t* self, +ssl_sslsocket_obj_t* common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t* self, socketpool_socket_obj_t* socket, bool server_side, const char* server_hostname) { - socket->ssl_context = self; + if (socket->type != SOCK_STREAM) { + mp_raise_RuntimeError(translate("Invalid socket for TLS")); + } + + ssl_sslsocket_obj_t *sock = m_new_obj_with_finaliser(ssl_sslsocket_obj_t); + sock->base.type = &ssl_sslsocket_type; + sock->ssl_context = self; + sock->sock = socket; + + esp_tls_t* tls_handle = esp_tls_init(); + if (tls_handle == NULL) { + mp_raise_espidf_MemoryError(); + } + sock->tls = tls_handle; + + // TODO: do something with the original socket? Don't call a close on the internal LWIP. + // Should we store server hostname on the socket in case connect is called with an ip? - return socket; + return sock; } diff --git a/ports/esp32s2/common-hal/ssl/SSLSocket.c b/ports/esp32s2/common-hal/ssl/SSLSocket.c new file mode 100644 index 000000000..33507e0f4 --- /dev/null +++ b/ports/esp32s2/common-hal/ssl/SSLSocket.c @@ -0,0 +1,176 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Lucian Copeland for Adafruit Industries + * + * 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 "shared-bindings/ssl/SSLSocket.h" +#include "shared-bindings/socketpool/Socket.h" +#include "shared-bindings/ssl/SSLContext.h" + +#include "bindings/espidf/__init__.h" +#include "lib/utils/interrupt_char.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "supervisor/shared/tick.h" + +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t* self, mp_uint_t timeout_ms) { + self->sock->timeout_ms = timeout_ms; +} + +ssl_sslsocket_obj_t* common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t* self, + uint8_t* ip, uint *port) { + socketpool_socket_obj_t * sock = common_hal_socketpool_socket_accept(self->sock, ip, port); + ssl_sslsocket_obj_t * sslsock = common_hal_ssl_sslcontext_wrap_socket(self->ssl_context, sock, false, NULL); + return sslsock; +} + +bool common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t* self, + const char* host, size_t hostlen, uint8_t port) { + return common_hal_socketpool_socket_bind(self->sock, host, hostlen, port); +} + +void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t* self) { + common_hal_socketpool_socket_close(self->sock); + esp_tls_conn_destroy(self->tls); + self->tls = NULL; +} + +bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t* self, + const char* host, mp_uint_t hostlen, mp_int_t port) { + esp_tls_cfg_t* tls_config = NULL; + tls_config = &self->ssl_context->ssl_config; + int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tls); + self->sock->connected = result >= 0; + if (result < 0) { + int esp_tls_code; + int flags; + esp_err_t err = esp_tls_get_and_clear_last_error(self->tls->error_handle, &esp_tls_code, &flags); + + if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { + mp_raise_espidf_MemoryError(); + } else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { + mp_raise_OSError_msg_varg(translate("Failed SSL handshake")); + } else { + mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x %d"), esp_tls_code, flags, err, result); + } + } else { + // Connection successful, set the timeout on the underlying socket. We can't rely on the IDF + // to do it because the config structure is only used for TLS connections. Generally, we + // shouldn't hit this timeout because we try to only read available data. However, there is + // always a chance that we try to read something that is used internally. + int fd; + esp_tls_get_conn_sockfd(self->tls, &fd); + struct timeval tv; + tv.tv_sec = 2 * 60; // Two minutes + tv.tv_usec = 0; + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + } + + return self->sock->connected; +} + +bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t* self) { + return self->tls == NULL && self->sock->num < 0; +} + +bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t* self) { + return self->sock->connected; +} + +bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t* self, int backlog) { + return common_hal_socketpool_socket_listen(self->sock, backlog); +} + +mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t* self, const uint8_t* buf, mp_uint_t len) { + int received = 0; + bool timed_out = false; + int status = 0; + uint64_t start_ticks = supervisor_ticks_ms64(); + int sockfd; + esp_err_t err = esp_tls_get_conn_sockfd(self->tls, &sockfd); + if (err != ESP_OK) { + mp_raise_OSError(MP_EBADF); + } + while (received == 0 && + status >= 0 && + !timed_out && + !mp_hal_is_interrupted()) { + if (self->sock->timeout_ms != (uint)-1 && self->sock->timeout_ms != 0) { + timed_out = self->sock->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks >= self->sock->timeout_ms; + } + RUN_BACKGROUND_TASKS; + size_t available = esp_tls_get_bytes_avail(self->tls); + if (available == 0) { + // This reads the raw socket buffer and is used for non-TLS connections + // and between encrypted TLS blocks. + status = lwip_ioctl(sockfd, FIONREAD, &available); + } + size_t remaining = len - received; + if (available > remaining) { + available = remaining; + } + if (available > 0) { + status = esp_tls_conn_read(self->tls, (void*) buf + received, available); + if (status == 0) { + // Reading zero when something is available indicates a closed + // connection. (The available bytes could have been TLS internal.) + break; + } + if (status > 0) { + received += status; + } + } + // In non-blocking mode, fail instead of timing out + if (received==0 && self->sock->timeout_ms == 0) { + mp_raise_OSError(MP_EAGAIN); + } + } + + if (timed_out) { + mp_raise_OSError(ETIMEDOUT); + } + return received; +} + +mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t* self, const uint8_t* buf, mp_uint_t len) { + int sent = -1; + sent = esp_tls_conn_write(self->tls, buf, len); + + if (sent < 0) { + int esp_tls_code; + int flags; + esp_err_t err = esp_tls_get_and_clear_last_error(self->tls->error_handle, &esp_tls_code, &flags); + + if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { + mp_raise_espidf_MemoryError(); + } else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { + mp_raise_OSError_msg_varg(translate("Failed SSL handshake")); + } else { + mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x %d"), esp_tls_code, flags, err, sent); + } + } + return sent; +} diff --git a/ports/esp32s2/common-hal/ssl/SSLSocket.h b/ports/esp32s2/common-hal/ssl/SSLSocket.h new file mode 100644 index 000000000..e9e5bff06 --- /dev/null +++ b/ports/esp32s2/common-hal/ssl/SSLSocket.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland for Adafruit Industries + * + * 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_ESP32S2_COMMON_HAL_SSL_SSLSOCKET_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSLSOCKET_H + +#include "py/obj.h" + +#include "common-hal/ssl/SSLContext.h" +#include "common-hal/socketpool/Socket.h" + +#include "components/esp-tls/esp_tls.h" + +typedef struct { + mp_obj_base_t base; + socketpool_socket_obj_t * sock; + esp_tls_t* tls; + ssl_sslcontext_obj_t* ssl_context; +} ssl_sslsocket_obj_t; + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSLSOCKET_H diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index 930230088..574bab0a1 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -72,7 +72,7 @@ void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { } if (!self->started && enabled) { // esp_wifi_start() would default to soft-AP, thus setting it to station - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + start_station(self); ESP_ERROR_CHECK(esp_wifi_start()); self->started = true; return; @@ -89,7 +89,9 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { if (self->current_scan != NULL) { mp_raise_RuntimeError(translate("Already scanning for wifi networks")); } - // check enabled + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(translate("wifi is not enabled")); + } start_station(self); wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); @@ -126,7 +128,25 @@ void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *host } wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t* bssid, size_t bssid_len) { - // check enabled + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(translate("wifi is not enabled")); + } + + EventBits_t bits; + // can't block since both bits are false after wifi_init + // both bits are true after an existing connection stops + bits = xEventGroupWaitBits(self->event_group_handle, + WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT, + pdTRUE, + pdTRUE, + 0); + if (((bits & WIFI_CONNECTED_BIT) != 0) && + !((bits & WIFI_DISCONNECTED_BIT) != 0)) { + return WIFI_RADIO_ERROR_NONE; + } + // explicitly clear bits since xEventGroupWaitBits may have timed out + xEventGroupClearBits(self->event_group_handle, WIFI_CONNECTED_BIT); + xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT); start_station(self); wifi_config_t* config = &self->sta_config; @@ -157,7 +177,6 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t self->retries_left = 5; esp_wifi_connect(); - EventBits_t bits; do { RUN_BACKGROUND_TASKS; bits = xEventGroupWaitBits(self->event_group_handle, diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h index 9c0fd9da3..0cf695bc9 100644 --- a/ports/esp32s2/mpconfigport.h +++ b/ports/esp32s2/mpconfigport.h @@ -30,7 +30,6 @@ #define MICROPY_NLR_THUMB (0) -#define MICROPY_PY_UJSON (1) #define MICROPY_USE_INTERNAL_PRINTF (0) #define MICROPY_PY_SYS_PLATFORM "Espressif ESP32-S2" diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 562c60998..b273c02ee 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -29,7 +29,10 @@ CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 1 CIRCUITPY_NVM = 1 # We don't have enough endpoints to include MIDI. -CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_USB_MIDI ?= 0 +CIRCUITPY_USB_HID ?= 1 +# We have borrowed the VENDOR nomenclature from tinyusb. VENDOR AKA WEBUSB +CIRCUITPY_USB_VENDOR ?= 0 CIRCUITPY_WIFI = 1 CIRCUITPY_WATCHDOG ?= 1 CIRCUITPY_ESPIDF = 1 diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 21a8868b5..534f7f71b 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -46,6 +46,7 @@ #include "common-hal/pulseio/PulseIn.h" #include "common-hal/pwmio/PWMOut.h" #include "common-hal/watchdog/WatchDogTimer.h" +#include "common-hal/socketpool/Socket.h" #include "common-hal/wifi/__init__.h" #include "supervisor/memory.h" #include "supervisor/shared/tick.h" @@ -222,6 +223,10 @@ void reset_port(void) { #if CIRCUITPY_WIFI wifi_reset(); #endif + +#if CIRCUITPY_SOCKETPOOL + socket_reset(); +#endif } void reset_to_bootloader(void) { diff --git a/ports/litex/mpconfigport.h b/ports/litex/mpconfigport.h index a7caf8526..5f739e49e 100644 --- a/ports/litex/mpconfigport.h +++ b/ports/litex/mpconfigport.h @@ -31,8 +31,6 @@ #define CIRCUITPY_INTERNAL_NVM_SIZE (0) #define MICROPY_NLR_THUMB (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UJSON (1) #include "py/circuitpy_mpconfig.h" diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c index aaa2549a8..c8daddc4b 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.c +++ b/ports/mimxrt10xx/common-hal/busio/I2C.c @@ -110,7 +110,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, if( !GPIO_PinRead(sda->gpio, sda->number) || !GPIO_PinRead(scl->gpio, scl->number)) { common_hal_reset_pin(sda); common_hal_reset_pin(scl); - mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); + mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring")); } #endif diff --git a/ports/mimxrt10xx/mpconfigport.h b/ports/mimxrt10xx/mpconfigport.h index 7496256d0..51e0ef9ff 100644 --- a/ports/mimxrt10xx/mpconfigport.h +++ b/ports/mimxrt10xx/mpconfigport.h @@ -41,8 +41,6 @@ extern uint8_t _ld_default_stack_size; #define CIRCUITPY_DEFAULT_STACK_SIZE ((uint32_t) &_ld_default_stack_size) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_PY_FUNCTION_ATTRS (0) -#define MICROPY_PY_IO (1) -#define MICROPY_PY_UJSON (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk index 76d15e608..c8cba2877 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.mk +++ b/ports/nrf/boards/pca10100/mpconfigboard.mk @@ -25,6 +25,7 @@ CIRCUITPY_RTC = 1 CIRCUITPY_SDCARDIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_ULAB = 0 +CIRCUITPY_BUSDEVICE = 0 MICROPY_PY_ASYNC_AWAIT = 0 SUPEROPT_GC = 0 diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index 4eb6c98c7..6bc05a7f0 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -3,6 +3,8 @@ USB_PID = 0xc051 USB_PRODUCT = "Simmel" USB_MANUFACTURER = "Betrusted" +CIRCUITPY_DEVICES="CDC,MSC,HID" + MCU_CHIP = nrf52833 # SPI_FLASH_FILESYSTEM = 1 @@ -13,11 +15,13 @@ INTERNAL_FLASH_FILESYSTEM = 1 CIRCUITPY_AESIO = 1 CIRCUITPY_AUDIOMP3 = 0 +CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BUSIO = 1 CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 -CIRCUITPY_MSGPACK = 0 CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PIXELBUF = 0 @@ -27,8 +31,8 @@ CIRCUITPY_RTC = 1 CIRCUITPY_SDCARDIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_ULAB = 0 +CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WATCHDOG = 1 -CIRCUITPY_BUSDEVICE = 0 # Enable micropython.native #CIRCUITPY_ENABLE_MPY_NATIVE = 1 diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index 37cb192df..654fa857f 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -131,7 +131,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t * if (!nrf_gpio_pin_read(sda->number) || !nrf_gpio_pin_read(scl->number)) { reset_pin_number(sda->number); reset_pin_number(scl->number); - mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); + mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring")); } #endif diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 012ebc3b5..6ecf7e0ba 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -36,6 +36,7 @@ #include "supervisor/shared/translate.h" #include "nrfx_uarte.h" +#include "nrf_gpio.h" #include <string.h> // expression to examine, and return value in case of failing @@ -98,10 +99,16 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) switch ( event->type ) { case NRFX_UARTE_EVT_RX_DONE: - ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes); + if (ringbuf_num_empty(&self->ringbuf) >= event->data.rxtx.bytes) { + ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes); + // keep receiving + (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1); + } else { + // receive buffer full, suspend + self->rx_paused = true; + nrf_gpio_pin_write(self->rts_pin_number, true); + } - // keep receiving - (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1); break; case NRFX_UARTE_EVT_TX_DONE: @@ -137,8 +144,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer, bool sigint_enabled) { - if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) { - mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device")); + if ((rs485_dir != NULL) || (rs485_invert)) { + mp_raise_ValueError(translate("RS485 Not yet supported on this device")); } // Find a free UART peripheral. @@ -166,16 +173,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_raise_ValueError(translate("Odd parity is not supported")); } + bool hwfc = rts != NULL || cts != NULL; + nrfx_uarte_config_t config = { .pseltxd = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, .pselrxd = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, - .pselcts = NRF_UARTE_PSEL_DISCONNECTED, - .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .pselcts = (cts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : cts->number, + .pselrts = (rts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rts->number, .p_context = self, .baudrate = get_nrf_baud(baudrate), .interrupt_priority = 7, .hal_cfg = { - .hwfc = NRF_UARTE_HWFC_DISABLED, + .hwfc = hwfc ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED, .parity = (parity == BUSIO_UART_PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED } }; @@ -207,9 +216,25 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->tx_pin_number = NO_PIN; } + if ( rts != NULL ) { + self->rts_pin_number = rts->number; + claim_pin(rts); + } else { + self->rts_pin_number = NO_PIN; + } + + if ( cts != NULL ) { + self->cts_pin_number = cts->number; + claim_pin(cts); + } else { + self->cts_pin_number = NO_PIN; + } + self->baudrate = baudrate; self->timeout_ms = timeout * 1000; + self->rx_paused = false; + // Initial wait for incoming byte _VERIFY_ERR(nrfx_uarte_rx(self->uarte, &self->rx_char, 1)); } @@ -223,8 +248,12 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { nrfx_uarte_uninit(self->uarte); reset_pin_number(self->tx_pin_number); reset_pin_number(self->rx_pin_number); + reset_pin_number(self->rts_pin_number); + reset_pin_number(self->cts_pin_number); self->tx_pin_number = NO_PIN; self->rx_pin_number = NO_PIN; + self->rts_pin_number = NO_PIN; + self->cts_pin_number = NO_PIN; ringbuf_free(&self->ringbuf); } } @@ -237,6 +266,13 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t uint64_t start_ticks = supervisor_ticks_ms64(); + // check removed to reduce code size + /* + if (len > ringbuf_capacity(&self->ringbuf)) { + mp_raise_ValueError(translate("Reading >receiver_buffer_size bytes is not supported")); + } + */ + // Wait for all bytes received or timeout while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) { RUN_BACKGROUND_TASKS; @@ -252,6 +288,16 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Copy as much received data as available, up to len bytes. size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len); + // restart reader, if stopped + if (self->rx_paused) { + // the character that did not fit in ringbuf is in rx_char + ringbuf_put_n(&self->ringbuf, &self->rx_char, 1); + // keep receiving + (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1); + nrf_gpio_pin_write(self->rts_pin_number, false); + self->rx_paused = false; + } + NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg)); return rx_bytes; diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index a25116291..2eaf58440 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -42,10 +42,13 @@ typedef struct { uint32_t timeout_ms; ringbuf_t ringbuf; - uint8_t rx_char; // EasyDMA buf + uint8_t rx_char; // EasyDMA buf + bool rx_paused; // set by irq if no space in rbuf uint8_t tx_pin_number; uint8_t rx_pin_number; + uint8_t cts_pin_number; + uint8_t rts_pin_number; } busio_uart_obj_t; void uart_reset(void); diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 4ed42cd82..3ac41a5e4 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -35,11 +35,8 @@ #include "peripherals/nrf/nvm.h" // for FLASH_PAGE_SIZE #define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_IO (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_SYS_STDIO_BUFFER (1) -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UJSON (1) // 24kiB stack #define CIRCUITPY_DEFAULT_STACK_SIZE (24*1024) diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index a604acb47..e1169ce7d 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -84,6 +84,7 @@ INC += -I. \ -isystem sdk/src/rp2_common/hardware_pio/include/ \ -isystem sdk/src/rp2_common/hardware_pll/include/ \ -isystem sdk/src/rp2_common/hardware_resets/include/ \ + -isystem sdk/src/rp2_common/hardware_rtc/include/ \ -isystem sdk/src/rp2_common/hardware_spi/include/ \ -isystem sdk/src/rp2_common/hardware_sync/include/ \ -isystem sdk/src/rp2_common/hardware_timer/include/ \ @@ -98,6 +99,7 @@ INC += -I. \ -isystem sdk/src/rp2_common/pico_platform/include/ \ -isystem sdk/src/rp2_common/pico_runtime/printf/include/ \ -isystem sdk/src/rp2_common/pico_bootrom/include/ \ + -isystem sdk/src/rp2_common/pico_unique_id/include/ \ -Isdk_config \ -I../../lib/tinyusb/src \ -I../../supervisor/shared/usb \ @@ -166,6 +168,7 @@ SRC_SDK := \ src/rp2_common/hardware_irq/irq.c \ src/rp2_common/hardware_pio/pio.c \ src/rp2_common/hardware_pll/pll.c \ + src/rp2_common/hardware_rtc/rtc.c \ src/rp2_common/hardware_spi/spi.c \ src/rp2_common/hardware_sync/sync.c \ src/rp2_common/hardware_timer/timer.c \ @@ -182,6 +185,7 @@ SRC_SDK := \ src/rp2_common/pico_printf/printf.c \ src/rp2_common/pico_runtime/runtime.c \ src/rp2_common/pico_stdio/stdio.c \ + src/rp2_common/pico_unique_id/unique_id.c \ SRC_SDK := $(addprefix sdk/, $(SRC_SDK)) diff --git a/ports/raspberrypi/background.c b/ports/raspberrypi/background.c index c85b83b41..52f2e4fb4 100644 --- a/ports/raspberrypi/background.c +++ b/ports/raspberrypi/background.c @@ -25,20 +25,11 @@ */ #include "background.h" -#include "supervisor/filesystem.h" -#include "supervisor/shared/tick.h" -#include "supervisor/usb.h" - #include "py/runtime.h" -#include "shared-module/network/__init__.h" -#include "supervisor/shared/stack.h" #include "supervisor/port.h" -#if CIRCUITPY_DISPLAYIO -#include "shared-module/displayio/__init__.h" -#endif - void port_start_background_task(void) {} void port_finish_background_task(void) {} -void port_background_task(void) {} +void port_background_task(void) { +} diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk index 69ff56fef..54c130660 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk @@ -7,3 +7,5 @@ CHIP_VARIANT = RP2040 CHIP_FAMILY = rp2 INTERNAL_FLASH_FILESYSTEM = 1 + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c index 38ec75c4a..e1927bc80 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c +++ b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c @@ -16,6 +16,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, @@ -23,6 +24,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, @@ -34,5 +36,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/bs2_default_padded_checksummed.S b/ports/raspberrypi/bs2_default_padded_checksummed.S index d77f4867c..6b7074e3b 100644 --- a/ports/raspberrypi/bs2_default_padded_checksummed.S +++ b/ports/raspberrypi/bs2_default_padded_checksummed.S @@ -1,20 +1,23 @@ -// Padded and checksummed version of: /Users/graham/dev/mu/pico_sdk/cmake-build-debug-mu/src/rp2_common/boot_stage2/bs2_default.bin +// Padded and checksummed version of: /home/pi/pico/pico-examples/build/pico-sdk/src/rp2_common/boot_stage2/bs2_default.bin -.section .boot2, "a" +.cpu cortex-m0plus +.thumb -.byte 0x00, 0xb5, 0x2f, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21, 0x88, 0x43, 0x98, 0x60 -.byte 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2b, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x02, 0x21, 0x59, 0x61 -.byte 0x01, 0x21, 0xf0, 0x22, 0x99, 0x50, 0x28, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20 -.byte 0x00, 0xf0, 0x3e, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21, 0x19, 0x66, 0x00, 0xf0 -.byte 0x2e, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, 0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0 -.byte 0x26, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x29, 0xf8, 0x01, 0x21 -.byte 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x18, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60 -.byte 0x17, 0x49, 0x18, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21 -.byte 0x19, 0x66, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x13, 0x49, 0x11, 0x48, 0x01, 0x60 -.byte 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd1, 0x10, 0x48, 0x00, 0x47, 0x03, 0xb5 -.byte 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd -.byte 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd -.byte 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00 -.byte 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, 0x22, 0x20, 0x00, 0xa0, 0x01, 0x01, 0x00, 0x10 -.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x27, 0x2a, 0x60 +.section .boot2, "ax" + +.byte 0x00, 0xb5, 0x32, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21, 0x88, 0x43, 0x98, 0x60 +.byte 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2e, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x02, 0x21, 0x59, 0x61 +.byte 0x01, 0x21, 0xf0, 0x22, 0x99, 0x50, 0x2b, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20 +.byte 0x00, 0xf0, 0x44, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21, 0x19, 0x66, 0x00, 0xf0 +.byte 0x34, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, 0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0 +.byte 0x2c, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21 +.byte 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60 +.byte 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21 +.byte 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60 +.byte 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x12, 0x48, 0x13, 0x49 +.byte 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a, 0x04, 0x20 +.byte 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66 +.byte 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x02, 0x40 +.byte 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00 +.byte 0xf4, 0x00, 0x00, 0x18, 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0 +.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xb2, 0x4e, 0x7a diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index fa49e375e..26a7f3807 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -90,7 +90,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, if (!gpio_get(sda->number) || !gpio_get(scl->number)) { reset_pin_number(sda->number); reset_pin_number(scl->number); - mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); + mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring")); } #endif diff --git a/ports/raspberrypi/common-hal/busio/UART.c b/ports/raspberrypi/common-hal/busio/UART.c index 71da6cadd..f9a75b499 100644 --- a/ports/raspberrypi/common-hal/busio/UART.c +++ b/ports/raspberrypi/common-hal/busio/UART.c @@ -54,6 +54,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer, bool sigint_enabled) { + mp_raise_NotImplementedError(translate("UART not yet supported")); // Sercom* sercom = NULL; // uint8_t sercom_index = 255; // Unset index diff --git a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c index 06f0cfdd2..b0bc1b96e 100644 --- a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c @@ -76,8 +76,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( digitalio_drive_mode_t drive_mode) { const uint8_t pin = self->pin->number; gpio_set_dir(pin, GPIO_OUT); - // Turn on "strong" pin driving (more current available). See DRVSTR doc in datasheet. - // hri_port_set_PINCFG_DRVSTR_bit(PORT, (enum gpio_port)GPIO_PORT(pin), GPIO_PIN(pin)); + // TODO: Turn on "strong" pin driving (more current available). self->output = true; common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode); @@ -140,18 +139,16 @@ void common_hal_digitalio_digitalinout_set_pull( digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( digitalio_digitalinout_obj_t* self) { - // uint32_t pin = self->pin->number; - // if (self->output) { - // mp_raise_AttributeError(translate("Cannot get pull while in output mode")); - // return PULL_NONE; - // } else { - // if (hri_port_get_PINCFG_PULLEN_bit(PORT, GPIO_PORT(pin), GPIO_PIN(pin)) == 0) { - // return PULL_NONE; - // } if (hri_port_get_OUT_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin)) > 0) { - // return PULL_UP; - // } else { - // return PULL_DOWN; - // } - // } + uint32_t pin = self->pin->number; + if (self->output) { + mp_raise_AttributeError(translate("Cannot get pull while in output mode")); + return PULL_NONE; + } else { + if (gpio_is_pulled_up(pin)) { + return PULL_UP; + } else if (gpio_is_pulled_down(pin)) { + return PULL_DOWN; + } + } return PULL_NONE; } diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.c b/ports/raspberrypi/common-hal/microcontroller/Pin.c index 90c327406..ca5cf5a04 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Pin.c +++ b/ports/raspberrypi/common-hal/microcontroller/Pin.c @@ -26,6 +26,7 @@ #include "py/runtime.h" +#include "common-hal/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/rgb_led_status.h" @@ -46,7 +47,7 @@ bool speaker_enable_in_use; STATIC uint32_t never_reset_pins; void reset_all_pins(void) { - for (size_t i = 0; i < 30; i++) { + for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) { if ((never_reset_pins & (1 << i)) != 0) { continue; } @@ -55,7 +56,7 @@ void reset_all_pins(void) { } void never_reset_pin_number(uint8_t pin_number) { - if (pin_number >= 32) { + if (pin_number >= TOTAL_GPIO_COUNT) { return; } @@ -63,12 +64,7 @@ void never_reset_pin_number(uint8_t pin_number) { } void reset_pin_number(uint8_t pin_number) { - if (pin_number >= 32 -#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX - // Pin 15 is used for Errata so we don't mess with it. - || pin_number == 15 -#endif - ) { + if (pin_number >= TOTAL_GPIO_COUNT) { return; } @@ -139,15 +135,10 @@ void claim_pin(const mcu_pin_obj_t* pin) { } bool pin_number_is_free(uint8_t pin_number) { - if (pin_number >= 30) { + if (pin_number >= TOTAL_GPIO_COUNT) { return false; } -#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX - // Pin 15 is used for Errata so we don't mess with it. - if (pin_number == 15) { - return true; - } -#endif + uint32_t pad_state = padsbank0_hw->io[pin_number]; return (pad_state & PADS_BANK0_GPIO0_IE_BITS) == 0 && (pad_state & PADS_BANK0_GPIO0_OD_BITS) != 0; diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.c b/ports/raspberrypi/common-hal/microcontroller/Processor.c index 0ad3a51e2..e22286ca3 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.c +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.c @@ -25,6 +25,7 @@ */ #include <math.h> +#include <string.h> #include "py/mphal.h" #include "common-hal/microcontroller/Processor.h" @@ -53,12 +54,9 @@ uint32_t common_hal_mcu_processor_get_frequency(void) { } void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { - // TODO: get the unique id from the flash. The chip itself doesn't have one. - // for (int i=0; i<4; i++) { - // for (int k=0; k<4; k++) { - // raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff; - // } - // } + pico_unique_board_id_t retrieved_id; + pico_get_unique_board_id(&retrieved_id); + memcpy(raw_id, retrieved_id.id, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.h b/ports/raspberrypi/common-hal/microcontroller/Processor.h index b7c86e850..afb43f9bd 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.h +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.h @@ -27,7 +27,9 @@ #ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H #define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H -#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 16 +#include "src/rp2_common/pico_unique_id/include/pico/unique_id.h" + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH PICO_UNIQUE_BOARD_ID_SIZE_BYTES #include "py/obj.h" diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.c b/ports/raspberrypi/common-hal/microcontroller/__init__.c index e454ffa1b..bfea8b2d9 100644 --- a/ports/raspberrypi/common-hal/microcontroller/__init__.c +++ b/ports/raspberrypi/common-hal/microcontroller/__init__.c @@ -35,12 +35,16 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/filesystem.h" +#include "supervisor/port.h" #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/translate.h" #include "src/rp2040/hardware_structs/include/hardware/structs/sio.h" #include "src/rp2_common/hardware_sync/include/hardware/sync.h" +#include "hardware/watchdog.h" + void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); } @@ -66,8 +70,11 @@ void common_hal_mcu_enable_interrupts(void) { asm volatile ("cpsie i" : : : "memory"); } +static bool next_reset_to_bootloader = false; + void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { if (runmode == RUNMODE_BOOTLOADER) { + next_reset_to_bootloader = true; } else { } if (runmode == RUNMODE_SAFE_MODE) { @@ -76,10 +83,17 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { } void common_hal_mcu_reset(void) { + filesystem_flush(); + if (next_reset_to_bootloader) { + reset_to_bootloader(); + } else { + reset_cpu(); + } } // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. +#if CIRCUITPY_PROCESSOR_COUNT > 1 static const mcu_processor_obj_t processor0 = { .base = { .type = &mcu_processor_type, @@ -92,7 +106,7 @@ static const mcu_processor_obj_t processor1 = { }, }; -const mp_rom_obj_tuple_t common_hal_mcu_processor_obj = { +const mp_rom_obj_tuple_t common_hal_multi_processor_obj = { {&mp_type_tuple}, CIRCUITPY_PROCESSOR_COUNT, { @@ -100,6 +114,13 @@ const mp_rom_obj_tuple_t common_hal_mcu_processor_obj = { MP_ROM_PTR(&processor1) } }; +#endif + +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; #if CIRCUITPY_NVM && CIRCUITPY_INTERNAL_NVM_SIZE > 0 // The singleton nvm.ByteArray object. @@ -112,6 +133,17 @@ const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { }; #endif +#if CIRCUITPY_WATCHDOG +// The singleton watchdog.WatchDogTimer object. +watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = { + .base = { + .type = &watchdog_watchdogtimer_type, + }, + .timeout = 0.0f, + .mode = WATCHDOGMODE_NONE, +}; +#endif + // This maps MCU pin names to pin objects. const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = { { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, diff --git a/ports/raspberrypi/common-hal/rtc/RTC.c b/ports/raspberrypi/common-hal/rtc/RTC.c new file mode 100644 index 000000000..89c23fc19 --- /dev/null +++ b/ports/raspberrypi/common-hal/rtc/RTC.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright 2020 microDev + * + * 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 "shared-bindings/rtc/RTC.h" + +#include <sys/time.h> + +#include "py/runtime.h" +#include "src/rp2_common/hardware_rtc/include/hardware/rtc.h" + +void common_hal_rtc_init(void) { + rtc_init(); +} + +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + datetime_t t; + rtc_get_datetime(&t); + + tm->tm_year = t.year; + tm->tm_mon = t.month; + tm->tm_mday = t.day; + tm->tm_wday = t.dotw; + tm->tm_hour = t.hour; + tm->tm_min = t.min; + tm->tm_sec = t.sec; + + if (tm->tm_wday == 0) { + tm->tm_wday = 6; + } else { + tm->tm_wday-=1; + } +} + +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + if (tm->tm_wday == 6) { + tm->tm_wday = 0; + } else { + tm->tm_wday+=1; + } + + datetime_t t = { + .year = tm->tm_year, + .month = tm->tm_mon, + .day = tm->tm_mday, + .dotw = tm->tm_wday, + .hour = tm->tm_hour, + .min = tm->tm_min, + .sec = tm->tm_sec + }; + rtc_set_datetime(&t); +} + +int common_hal_rtc_get_calibration(void) { + return 0; +} + +void common_hal_rtc_set_calibration(int calibration) { + mp_raise_NotImplementedError(translate("RTC calibration is not supported on this board")); +} diff --git a/ports/raspberrypi/common-hal/rtc/RTC.h b/ports/raspberrypi/common-hal/rtc/RTC.h new file mode 100644 index 000000000..426a4ec7a --- /dev/null +++ b/ports/raspberrypi/common-hal/rtc/RTC.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * 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_RASPBERRYPI_COMMON_HAL_RTC_RTC_H +#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_RTC_RTC_H + +extern void common_hal_rtc_init(void); + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_RTC_RTC_H diff --git a/ports/raspberrypi/common-hal/rtc/__init__.c b/ports/raspberrypi/common-hal/rtc/__init__.c new file mode 100644 index 000000000..f5e6b6bdd --- /dev/null +++ b/ports/raspberrypi/common-hal/rtc/__init__.c @@ -0,0 +1 @@ +// No RTC module functions diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogMode.c b/ports/raspberrypi/common-hal/watchdog/WatchDogMode.c new file mode 100644 index 000000000..fc4e0e008 --- /dev/null +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogMode.c @@ -0,0 +1 @@ +// No watchdog module functions. diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c new file mode 100644 index 000000000..f23ccda77 --- /dev/null +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c @@ -0,0 +1,83 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * 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 "common-hal/watchdog/WatchDogTimer.h" + +#include "shared-bindings/watchdog/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "src/rp2_common/hardware_watchdog/include/hardware/watchdog.h" + +void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { + watchdog_update(); +} + +void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { + if (self->mode == WATCHDOGMODE_RESET) { + mp_raise_RuntimeError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); + } else { + self->mode = WATCHDOGMODE_NONE; + } +} + +/* +void watchdog_reset(void) { + common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); +} +*/ + +mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { + return self->timeout; +} + +void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_float_t new_timeout) { + // max timeout is 8.388607 sec + // this is rounded down to 8.388 sec + uint64_t timeout = new_timeout * 1000; + if (timeout > 8388) { + mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value")); + } + if ((uint16_t)self->timeout != timeout) { + watchdog_enable(timeout, false); + self->timeout = new_timeout; + } +} + +watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_t *self) { + return self->mode; +} + +void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t new_mode) { + if (self->mode != new_mode) { + if (new_mode == WATCHDOGMODE_RAISE) { + mp_raise_NotImplementedError(translate("RAISE mode is not implemented")); + } else if (new_mode == WATCHDOGMODE_NONE) { + common_hal_watchdog_deinit(self); + } + self->mode = new_mode; + } +} diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h new file mode 100644 index 000000000..ec1e2f659 --- /dev/null +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * 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_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H +#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H + +#include "py/obj.h" +#include "shared-bindings/watchdog/WatchDogMode.h" +#include "shared-bindings/watchdog/WatchDogTimer.h" + +struct _watchdog_watchdogtimer_obj_t { + mp_obj_base_t base; + mp_float_t timeout; + watchdog_watchdogmode_t mode; +}; + +// This needs to be called in order to disable the watchdog +// void watchdog_reset(void); + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/raspberrypi/common-hal/watchdog/__init__.c b/ports/raspberrypi/common-hal/watchdog/__init__.c new file mode 100644 index 000000000..fc4e0e008 --- /dev/null +++ b/ports/raspberrypi/common-hal/watchdog/__init__.c @@ -0,0 +1 @@ +// No watchdog module functions. diff --git a/ports/raspberrypi/link.ld b/ports/raspberrypi/link.ld index d642fd680..b83299dee 100644 --- a/ports/raspberrypi/link.ld +++ b/ports/raspberrypi/link.ld @@ -59,12 +59,11 @@ SECTIONS */ .text : { - __reset_start = .; - KEEP (*(.reset)) - . = ALIGN(256); - __reset_end = .; - ASSERT(__reset_end - __reset_start == 256, "ERROR: reset section should only be 256 bytes"); + __logical_binary_start = .; KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.reset)) /* TODO revisit this now memset/memcpy/float in ROM */ /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from * FLASH ... we will include any thing excluded here in .data below by default */ @@ -246,5 +245,7 @@ SECTIONS /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") /* todo assert on extra code */ } diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index 3fdc8febb..77d1ff080 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -27,7 +27,7 @@ #ifndef __INCLUDED_MPCONFIGPORT_H #define __INCLUDED_MPCONFIGPORT_H -#define MICROPY_PY_UJSON (1) +#define MICROPY_PY_SYS_PLATFORM "RP2040" #define CIRCUITPY_INTERNAL_NVM_SIZE 0 diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index a6211be73..8681e2994 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -14,6 +14,9 @@ ifeq ($(LONGINT_IMPL),LONGLONG) MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong endif +# All raspberrypi ports have longints. +LONGINT_IMPL = MPZ + ifndef CIRCUITPY_RP2PIO CIRCUITPY_RP2PIO = 1 else @@ -32,13 +35,13 @@ CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PULSEIO = 0 # Use PIO interally CIRCUITPY_ROTARYIO = 0 # Use PIO interally -CIRCUITPY_RTC = 0 +CIRCUITPY_WATCHDOG = 1 # Things that are unsupported by the hardware. CIRCUITPY_AUDIOIO = 0 INTERNAL_LIBM = 1 -USB_SERIAL_NUMBER_LENGTH = 32 +USB_SERIAL_NUMBER_LENGTH = 16 USB_NUM_EP = 8 diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk -Subproject 26653ea81e340cacee55025d110c3e014a252a8 +Subproject 55346c953012ef5b32f392fea3b42814db8df2a diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index b2f73c7b4..7c503514a 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -52,6 +52,8 @@ #include "tusb.h" +#include "pico/bootrom.h" +#include "hardware/watchdog.h" extern volatile bool mp_msc_enabled; @@ -94,25 +96,33 @@ void reset_port(void) { reset_spi(); #endif + #if CIRCUITPY_PWMIO + pwmout_reset(); + #endif + #if CIRCUITPY_RP2PIO reset_rp2pio_statemachine(); #endif - #if CIRCUITPY_PWMIO - pwmout_reset(); + #if CIRCUITPY_RTC + rtc_reset(); #endif reset_all_pins(); } void reset_to_bootloader(void) { - // reset(); + reset_usb_boot(0, 0); while (true) {} } void reset_cpu(void) { - // reset(); - while (true) {} + watchdog_reboot(0, SRAM_END, 0); + watchdog_start_tick(12); + + while (true) { + __wfi(); + } } bool port_has_fixed_stack(void) { diff --git a/ports/stm/boards/espruino_pico/mpconfigboard.mk b/ports/stm/boards/espruino_pico/mpconfigboard.mk index 14f9323fd..81c3772e7 100644 --- a/ports/stm/boards/espruino_pico/mpconfigboard.mk +++ b/ports/stm/boards/espruino_pico/mpconfigboard.mk @@ -20,5 +20,6 @@ LD_FILE = boards/STM32F401xd_fs.ld # lto for this port, and if other stuff hasn't been added in the # meantime CIRCUITPY_ULAB = 0 +CIRCUITPY_BUSDEVICE = 0 SUPEROPT_GC = 0 diff --git a/ports/stm/mpconfigport.h b/ports/stm/mpconfigport.h index 9489b4765..7cdab04f6 100644 --- a/ports/stm/mpconfigport.h +++ b/ports/stm/mpconfigport.h @@ -31,9 +31,7 @@ #include <stdint.h> #define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_IO (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_UJSON (1) extern uint8_t _ld_default_stack_size; |
