summaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authormicroDev <70126934+microDev1@users.noreply.github.com>2020-12-30 22:44:22 +0530
committermicroDev <70126934+microDev1@users.noreply.github.com>2020-12-30 22:44:22 +0530
commit28ce5e898864a6205ab3c0483991f27707164954 (patch)
tree0f5f353feb7b8b4f1ce0b6fd8e147e74083d9b26 /ports
parentc7f68022efa1306b0c7cb2fa47dcc84dbca2c605 (diff)
parent48de52c8ab62fae93e1382cb774802828cf92edd (diff)
Merge branch 'main' into touch-s2
Diffstat (limited to 'ports')
-rw-r--r--ports/atmel-samd/boards/stackrduino_m0_pro/board.c37
-rw-r--r--ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.h33
-rw-r--r--ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk58
-rw-r--r--ports/atmel-samd/boards/stackrduino_m0_pro/pins.c40
-rw-r--r--ports/atmel-samd/common-hal/audioio/AudioOut.c4
-rw-r--r--ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c3
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.c3
-rw-r--r--ports/esp32s2/Makefile14
-rw-r--r--ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h2
-rw-r--r--ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h2
-rw-r--r--ports/esp32s2/common-hal/alarm/__init__.c64
-rw-r--r--ports/esp32s2/common-hal/alarm/pin/PinAlarm.c270
-rw-r--r--ports/esp32s2/common-hal/alarm/pin/PinAlarm.h10
-rw-r--r--ports/esp32s2/common-hal/alarm/time/TimeAlarm.c35
-rw-r--r--ports/esp32s2/common-hal/alarm/time/TimeAlarm.h4
-rw-r--r--ports/esp32s2/common-hal/analogio/AnalogIn.h2
-rw-r--r--ports/esp32s2/common-hal/busio/I2C.h2
-rw-r--r--ports/esp32s2/common-hal/busio/SPI.c13
-rw-r--r--ports/esp32s2/common-hal/busio/SPI.h4
-rw-r--r--ports/esp32s2/common-hal/busio/UART.h2
-rw-r--r--ports/esp32s2/common-hal/digitalio/DigitalInOut.c2
-rw-r--r--ports/esp32s2/common-hal/dualbank/__init__.c139
-rw-r--r--ports/esp32s2/common-hal/dualbank/__init__.h32
-rw-r--r--ports/esp32s2/common-hal/microcontroller/Pin.c5
-rw-r--r--ports/esp32s2/common-hal/wifi/Network.c6
-rw-r--r--ports/esp32s2/common-hal/wifi/Radio.c11
m---------ports/esp32s2/esp-idf0
-rw-r--r--ports/esp32s2/mpconfigport.mk1
-rw-r--r--ports/esp32s2/peripherals/pins.h6
-rw-r--r--ports/esp32s2/supervisor/esp_port.h2
-rw-r--r--ports/esp32s2/supervisor/port.c72
-rw-r--r--ports/esp32s2/supervisor/usb.c35
-rw-r--r--ports/litex/boards/fomu/fomu-spi.ld5
-rw-r--r--ports/litex/common-hal/microcontroller/Pin.c3
-rw-r--r--ports/litex/common-hal/microcontroller/__init__.c7
-rw-r--r--ports/litex/mphalport.c15
-rw-r--r--ports/litex/supervisor/port.c6
-rw-r--r--ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h2
-rw-r--r--ports/mimxrt10xx/common-hal/busio/SPI.c9
-rw-r--r--ports/mimxrt10xx/common-hal/busio/UART.c10
-rw-r--r--ports/mimxrt10xx/common-hal/microcontroller/Pin.c3
-rw-r--r--ports/nrf/boards/bastble/README.md4
-rw-r--r--ports/nrf/boards/bastble/board.c41
-rw-r--r--ports/nrf/boards/bastble/mpconfigboard.h25
-rw-r--r--ports/nrf/boards/bastble/mpconfigboard.mk10
-rw-r--r--ports/nrf/boards/bastble/pins.c47
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c11
-rw-r--r--ports/nrf/common-hal/microcontroller/Pin.c3
-rw-r--r--ports/stm/boards/feather_stm32f405_express/mpconfigboard.h2
-rw-r--r--ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.h3
-rw-r--r--ports/stm/boards/stm32f411ce_blackpill/pins.c5
-rw-r--r--ports/stm/common-hal/microcontroller/Pin.c3
-rw-r--r--ports/unix/mphalport.h2
-rw-r--r--ports/unix/unix_mphal.c4
54 files changed, 976 insertions, 157 deletions
diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/board.c b/ports/atmel-samd/boards/stackrduino_m0_pro/board.c
new file mode 100644
index 000000000..84960e73c
--- /dev/null
+++ b/ports/atmel-samd/boards/stackrduino_m0_pro/board.c
@@ -0,0 +1,37 @@
+/*
+ * 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"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.h b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.h
new file mode 100644
index 000000000..f0b2764a4
--- /dev/null
+++ b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.h
@@ -0,0 +1,33 @@
+#define MICROPY_HW_BOARD_NAME "StackRduino M0 PRO"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_HW_LED_STATUS (&pin_PA17)
+#define MICROPY_HW_NEOPIXEL (&pin_PA06)
+
+#define SPI_FLASH_BAUDRATE (8000000)
+
+#define SPI_FLASH_MOSI_PIN &pin_PB22
+#define SPI_FLASH_MISO_PIN &pin_PB03
+#define SPI_FLASH_SCK_PIN &pin_PB23
+#define SPI_FLASH_CS_PIN &pin_PA27
+
+// These are pins not to reset.
+#define MICROPY_PORT_A (PORT_PA06)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA12)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA11)
+#define DEFAULT_UART_BUS_TX (&pin_PA10)
+
+// 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/stackrduino_m0_pro/mpconfigboard.mk b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk
new file mode 100644
index 000000000..704d26514
--- /dev/null
+++ b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk
@@ -0,0 +1,58 @@
+USB_VID = 0x1209
+USB_PID = 0xE3E3
+USB_PRODUCT = "StackRduino M0 PRO"
+USB_MANUFACTURER = "StackRduino"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ"
+LONGINT_IMPL = MPZ
+
+
+CIRCUITPY_BITBANGIO = 0
+CIRCUITPY_FREQUENCYIO = 0
+CIRCUITPY_COUNTIO = 0
+CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_VECTORIO = 0
+CIRCUITPY_BUSDEVICE = 0
+
+CFLAGS_INLINE_LIMIT = 55
+SUPEROPT_GC = 0
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
+ifeq ($(TRANSLATION), ja)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+endif
+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
+ifeq ($(TRANSLATION), pl)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+SUPEROPT_VM = 0
+endif
+ifeq ($(TRANSLATION), fr)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+SUPEROPT_VM = 0
+endif
+ifeq ($(TRANSLATION), pt_BR)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+SUPEROPT_VM = 0
+endif
+ifeq ($(TRANSLATION), es)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+SUPEROPT_VM = 0
+endif
diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/pins.c b/ports/atmel-samd/boards/stackrduino_m0_pro/pins.c
new file mode 100644
index 000000000..95d2eb5a3
--- /dev/null
+++ b/ports/atmel-samd/boards/stackrduino_m0_pro/pins.c
@@ -0,0 +1,40 @@
+#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_A1), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA28) },
+ { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA28) },
+ { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_CHRG_EN), MP_ROM_PTR(&pin_PA13) },
+ { 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/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c
index 5cefba56f..34b718dca 100644
--- a/ports/atmel-samd/common-hal/audioio/AudioOut.c
+++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c
@@ -197,7 +197,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self,
#endif
#ifdef SAM_D5X_E5X
DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI0;
- DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC100K |
+ DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC12M |
DAC_DACCTRL_ENABLE |
DAC_DACCTRL_LEFTADJ;
DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU;
@@ -206,7 +206,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self,
#ifdef SAM_D5X_E5X
if (channel1_enabled) {
DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI1;
- DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC100K |
+ DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC12M |
DAC_DACCTRL_ENABLE |
DAC_DACCTRL_LEFTADJ;
DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU;
diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
index 02d0482dc..f973db90b 100644
--- a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
@@ -82,7 +82,8 @@ void frequencyin_emergency_cancel_capture(uint8_t index) {
#ifdef SAM_D5X_E5X
NVIC_EnableIRQ(EIC_0_IRQn + self->channel);
#endif
- mp_raise_RuntimeError(translate("Frequency captured is above capability. Capture Paused."));
+ // Frequency captured is above capability. Capture paused.
+ // We can't raise an error here; we're in an interrupt handler.
}
void frequencyin_interrupt_handler(uint8_t index) {
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c
index 7dd87a3b2..564d037e0 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.c
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c
@@ -169,6 +169,9 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ if (pin == NULL) {
+ return;
+ }
reset_pin_number(pin->number);
}
diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile
index 3291c7fac..f33a1d2eb 100644
--- a/ports/esp32s2/Makefile
+++ b/ports/esp32s2/Makefile
@@ -106,6 +106,8 @@ INC += -isystem esp-idf/components/heap/include
INC += -isystem esp-idf/components/esp_system/include
INC += -isystem esp-idf/components/spi_flash/include
INC += -isystem esp-idf/components/nvs_flash/include
+INC += -isystem esp-idf/components/app_update/include
+INC += -isystem esp-idf/components/bootloader_support/include
INC += -I$(BUILD)/esp-idf/config
CFLAGS += -DHAVE_CONFIG_H \
@@ -143,7 +145,6 @@ LDFLAGS += -L$(BUILD)/esp-idf/esp-idf/esp32s2 \
-Tesp32s2.peripherals.ld \
-Lesp-idf/components/esp_rom/esp32s2/ld \
-Tesp32s2.rom.ld \
- -Tesp32s2.rom.api.ld \
-Tesp32s2.rom.libgcc.ld \
-Tesp32s2.rom.newlib-data.ld \
-Tesp32s2.rom.newlib-funcs.ld \
@@ -277,7 +278,7 @@ menuconfig: $(BUILD)/esp-idf/config
# qstr builds include headers so we need to make sure they are up to date
$(HEADER_BUILD)/qstr.split: | $(BUILD)/esp-idf/config/sdkconfig.h
-ESP_IDF_COMPONENTS_LINK = freertos log hal esp_system esp_adc_cal esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp_rom esp-tls
+ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp_adc_cal esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp-tls
ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc
@@ -289,11 +290,11 @@ ESP_IDF_WIFI_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_WIFI_COMPONENT
MBEDTLS_COMPONENTS_LINK = crypto tls x509
MBEDTLS_COMPONENTS_LINK_EXPANDED = $(foreach component, $(MBEDTLS_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/library/libmbed$(component).a)
-BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libxt_hal.a
+BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libhal.a
BINARY_WIFI_BLOBS = libcoexist.a libcore.a libespnow.a libmesh.a libnet80211.a libpp.a librtc.a libsmartconfig.a libphy.a
BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/esp32s2/, $(BINARY_WIFI_BLOBS))
-ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/soc/soc/esp32s2/libsoc_esp32s2.a esp-idf/components/xtensa/esp32s2/libxt_hal.a
+ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/soc/soc/esp32s2/libsoc_esp32s2.a
ESP_AUTOGEN_LD = $(BUILD)/esp-idf/esp-idf/esp32s2/esp32s2_out.ld $(BUILD)/esp-idf/esp-idf/esp32s2/ld/esp32s2.project.ld
FLASH_FLAGS = --flash_mode $(CIRCUITPY_ESP_FLASH_MODE) --flash_freq $(CIRCUITPY_ESP_FLASH_FREQ) --flash_size $(CIRCUITPY_ESP_FLASH_SIZE)
@@ -309,7 +310,6 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h
esp-idf/esp32s2/ld/esp32s2.project.ld \
esp-idf/esp_event/libesp_event.a \
esp-idf/esp_netif/libesp_netif.a \
- esp-idf/esp_rom/libesp_rom.a \
esp-idf/esp_system/libesp_system.a \
esp-idf/esp_wifi/libesp_wifi.a \
esp-idf/lwip/liblwip.a \
@@ -337,10 +337,10 @@ $(BUILD)/firmware.uf2: $(BUILD)/circuitpython-firmware.bin
$(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xbfdd4eee -b 0x0000 -c -o $@ $^
flash: $(BUILD)/firmware.bin
- esptool.py --chip esp32s2 -p $(PORT) --no-stub -b 460800 --before=default_reset --after=no_reset write_flash $(FLASH_FLAGS) 0x0000 $^
+ esptool.py --chip esp32s2 -p $(PORT) -b 460800 --before=default_reset --after=no_reset write_flash $(FLASH_FLAGS) 0x0000 $^
flash-circuitpython-only: $(BUILD)/circuitpython-firmware.bin
- esptool.py --chip esp32s2 -p $(PORT) --no-stub -b 460800 --before=default_reset --after=no_reset write_flash $(FLASH_FLAGS) 0x10000 $^
+ esptool.py --chip esp32s2 -p $(PORT) -b 460800 --before=default_reset --after=no_reset write_flash $(FLASH_FLAGS) 0x10000 $^
include $(TOP)/py/mkrules.mk
diff --git a/ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h b/ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h
index be376e5a9..8dfe91271 100644
--- a/ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h
+++ b/ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h
@@ -26,7 +26,7 @@
//Micropython setup
-#define MICROPY_HW_BOARD_NAME "MagTag"
+#define MICROPY_HW_BOARD_NAME "Adafruit MagTag"
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO1)
diff --git a/ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h b/ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h
index 7280aab9c..b25d7d116 100644
--- a/ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h
+++ b/ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h
@@ -26,7 +26,7 @@
//Micropython setup
-#define MICROPY_HW_BOARD_NAME "Metro ESP32S2"
+#define MICROPY_HW_BOARD_NAME "Adafruit Metro ESP32S2"
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO45)
diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c
index 9e5772eac..0b1a7f049 100644
--- a/ports/esp32s2/common-hal/alarm/__init__.c
+++ b/ports/esp32s2/common-hal/alarm/__init__.c
@@ -25,10 +25,12 @@
* THE SOFTWARE.
*/
+#include "py/gc.h"
#include "py/obj.h"
#include "py/objtuple.h"
#include "py/runtime.h"
+#include "shared-bindings/alarm/__init__.h"
#include "shared-bindings/alarm/SleepMemory.h"
#include "shared-bindings/alarm/pin/PinAlarm.h"
#include "shared-bindings/alarm/time/TimeAlarm.h"
@@ -40,10 +42,11 @@
#include "supervisor/port.h"
#include "supervisor/shared/workflow.h"
-#include "common-hal/alarm/__init__.h"
-
#include "esp_sleep.h"
+#include "components/soc/soc/esp32s2/include/soc/rtc_cntl_reg.h"
+#include "components/driver/include/driver/uart.h"
+
// Singleton instance of SleepMemory.
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
.base = {
@@ -53,19 +56,22 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
void alarm_reset(void) {
alarm_sleep_memory_reset();
+ alarm_pin_pinalarm_reset();
alarm_time_timealarm_reset();
alarm_touch_touchalarm_reset();
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
}
STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
+ if (alarm_pin_pinalarm_woke_us_up()) {
+ return ESP_SLEEP_WAKEUP_GPIO;
+ }
if (alarm_time_timealarm_woke_us_up()) {
return ESP_SLEEP_WAKEUP_TIMER;
}
if (alarm_touch_touchalarm_woke_us_up()) {
return ESP_SLEEP_WAKEUP_TOUCHPAD;
}
-
return esp_sleep_get_wakeup_cause();
}
@@ -74,14 +80,16 @@ bool alarm_woken_from_sleep(void) {
}
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
- switch (_get_wakeup_cause()) {
+ esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
+ switch (cause) {
case ESP_SLEEP_WAKEUP_TIMER: {
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
}
- case ESP_SLEEP_WAKEUP_EXT0: {
- // TODO: implement pin alarm wake.
- break;
+ case ESP_SLEEP_WAKEUP_GPIO:
+ case ESP_SLEEP_WAKEUP_EXT0:
+ case ESP_SLEEP_WAKEUP_EXT1: {
+ return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
}
case ESP_SLEEP_WAKEUP_TOUCHPAD:
@@ -102,24 +110,8 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) {
// Set up light sleep or deep sleep alarms.
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
- bool time_alarm_set = false;
- alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL;
-
- for (size_t i = 0; i < n_alarms; i++) {
- if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) {
- mp_raise_NotImplementedError(translate("PinAlarm not yet implemented"));
- } else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) {
- if (time_alarm_set) {
- mp_raise_ValueError(translate("Only one alarm.time alarm can be set."));
- }
- time_alarm = MP_OBJ_TO_PTR(alarms[i]);
- time_alarm_set = true;
- }
- }
-
- if (time_alarm_set) {
- alarm_time_timealarm_set_alarm(time_alarm);
- }
+ alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
+ alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
}
@@ -136,21 +128,16 @@ STATIC void _idle_until_alarm(void) {
}
}
-// Is it safe to do a light sleep? Check whether WiFi is on or there are
-// other ongoing tasks that should not be shut down.
-STATIC bool _light_sleep_ok(void) {
- return !common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) && !supervisor_workflow_active();
-}
-
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
_setup_sleep_alarms(false, n_alarms, alarms);
- // Light sleep can break some functionality so only do it when possible. Otherwise we idle.
- if (_light_sleep_ok()) {
- esp_light_sleep_start();
- } else {
- _idle_until_alarm();
+ // We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
+ _idle_until_alarm();
+
+ if (mp_hal_is_interrupted()) {
+ return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
}
+
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
alarm_reset();
return wake_alarm;
@@ -161,8 +148,13 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
}
void NORETURN alarm_enter_deep_sleep(void) {
+ alarm_pin_pinalarm_prepare_for_deep_sleep();
alarm_touch_touchalarm_prepare_for_deep_sleep();
// The ESP-IDF caches the deep sleep settings and applies them before sleep.
// We don't need to worry about resetting them in the interim.
esp_deep_sleep_start();
}
+
+void common_hal_alarm_gc_collect(void) {
+ gc_collect_ptr(alarm_get_wake_alarm());
+}
diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
index 582a66572..df8d10ef9 100644
--- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
+++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ * 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
@@ -24,30 +25,283 @@
* THE SOFTWARE.
*/
-#include "esp_sleep.h"
+#include "py/runtime.h"
#include "shared-bindings/alarm/pin/PinAlarm.h"
+#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
+#include "supervisor/esp_port.h"
-void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
+#include "components/driver/include/driver/rtc_io.h"
+#include "components/esp32s2/include/esp_sleep.h"
+#include "components/freertos/include/freertos/FreeRTOS.h"
+#include "components/soc/src/esp32s2/include/hal/gpio_ll.h"
+#include "components/xtensa/include/esp_debug_helpers.h"
+
+void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
+ if (edge) {
+ mp_raise_ValueError(translate("Cannot wake on pin edge. Only level."));
+ }
+
+ if (pull && !GPIO_IS_VALID_OUTPUT_GPIO(pin->number)) {
+ mp_raise_ValueError(translate("Cannot pull on input-only pin."));
+ }
self->pin = pin;
self->value = value;
- self->edge = edge;
self->pull = pull;
}
-mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) {
+mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
return self->pin;
}
-bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) {
+bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self) {
return self->value;
}
-bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) {
- return self->edge;
+bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self) {
+ return false;
}
-bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self) {
+bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
return self->pull;
}
+
+gpio_isr_handle_t gpio_interrupt_handle;
+// Low and high are relative to pin number. 32+ is high. <32 is low.
+static volatile uint32_t pin_31_0_status = 0;
+static volatile uint32_t pin_63_32_status = 0;
+void gpio_interrupt(void *arg) {
+ (void) arg;
+
+ gpio_ll_get_intr_status(&GPIO, xPortGetCoreID(), (uint32_t*) &pin_31_0_status);
+ gpio_ll_clear_intr_status(&GPIO, pin_31_0_status);
+ gpio_ll_get_intr_status_high(&GPIO, xPortGetCoreID(), (uint32_t*) &pin_63_32_status);
+ gpio_ll_clear_intr_status_high(&GPIO, pin_63_32_status);
+
+ // disable the interrupts that fired, maybe all of them
+ for (size_t i = 0; i < 32; i++) {
+ uint32_t mask = 1 << i;
+ if ((pin_31_0_status & mask) != 0) {
+ gpio_ll_intr_disable(&GPIO, i);
+ }
+ if ((pin_63_32_status & mask) != 0) {
+ gpio_ll_intr_disable(&GPIO, 32 + i);
+ }
+ }
+ BaseType_t high_task_wakeup;
+ vTaskNotifyGiveFromISR(circuitpython_task, &high_task_wakeup);
+ if (high_task_wakeup) {
+ portYIELD_FROM_ISR();
+ }
+}
+
+bool alarm_pin_pinalarm_woke_us_up(void) {
+ return pin_31_0_status != 0 || pin_63_32_status != 0;
+}
+
+mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
+ // First, check to see if we match any given alarms.
+ uint64_t pin_status = ((uint64_t) pin_63_32_status) << 32 | pin_31_0_status;
+ for (size_t i = 0; i < n_alarms; i++) {
+ if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
+ continue;
+ }
+ alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
+ if ((pin_status & (1ull << alarm->pin->number)) != 0) {
+ return alarms[i];
+ }
+ }
+ esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
+ size_t pin_number = 64;
+ if (cause == ESP_SLEEP_WAKEUP_EXT0) {
+ pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL);
+ } else {
+ if (cause == ESP_SLEEP_WAKEUP_EXT1) {
+ pin_status = esp_sleep_get_ext1_wakeup_status();
+ }
+ // If the cause is GPIO, we've already snagged pin_status in the interrupt.
+ // We'll only get here if we pretended to deep sleep. Light sleep will
+ // pass in existing objects.
+ for (size_t i = 0; i < 64; i++) {
+ if ((pin_status & (1ull << i)) != 0) {
+ pin_number = i;
+ break;
+ }
+ }
+ }
+
+ alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
+ alarm->base.type = &alarm_pin_pinalarm_type;
+ alarm->pin = NULL;
+ // Map the pin number back to a pin object.
+ for (size_t i = 0; i < mcu_pin_globals.map.used; i++) {
+ const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value);
+ if ((size_t) pin_obj->number == pin_number) {
+ alarm->pin = mcu_pin_globals.map.table[i].value;
+ break;
+ }
+ }
+ return alarm;
+}
+
+// These must be static because we need to configure pulls later, right before
+// deep sleep.
+static uint64_t high_alarms = 0;
+static uint64_t low_alarms = 0;
+static uint64_t pull_pins = 0;
+
+void alarm_pin_pinalarm_reset(void) {
+ if (gpio_interrupt_handle != NULL) {
+ esp_intr_free(gpio_interrupt_handle);
+ gpio_interrupt_handle = NULL;
+ }
+ for (size_t i = 0; i < 64; i++) {
+ uint64_t mask = 1ull << i;
+ bool high = (high_alarms & mask) != 0;
+ bool low = (low_alarms & mask) != 0;
+ if (!(high || low)) {
+ continue;
+ }
+ reset_pin_number(i);
+ }
+ high_alarms = 0;
+ low_alarms = 0;
+ pull_pins = 0;
+ pin_63_32_status = 0;
+ pin_31_0_status = 0;
+}
+
+void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
+ // Bitmask of wake up settings.
+ size_t high_count = 0;
+ size_t low_count = 0;
+
+ for (size_t i = 0; i < n_alarms; i++) {
+ // TODO: Check for ULP or touch alarms because they can't coexist with GPIO alarms.
+ if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
+ continue;
+ }
+ alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
+
+ gpio_num_t pin_number = alarm->pin->number;
+ if (alarm->value) {
+ high_alarms |= 1ull << pin_number;
+ high_count++;
+ } else {
+ low_alarms |= 1ull << pin_number;
+ low_count++;
+ }
+ if (alarm->pull) {
+ pull_pins |= 1ull << pin_number;
+ }
+ }
+ if (high_count == 0 && low_count == 0) {
+ return;
+ }
+ if (deep_sleep && low_count > 2 && high_count == 0) {
+ mp_raise_ValueError(translate("Can only alarm on two low pins from deep sleep."));
+ }
+ if (deep_sleep && low_count > 1 && high_count > 0) {
+ mp_raise_ValueError(translate("Can only alarm on one low pin while others alarm high from deep sleep."));
+ }
+ // Only use ext0 and ext1 during deep sleep.
+ if (deep_sleep) {
+ if (high_count > 0) {
+ if (esp_sleep_enable_ext1_wakeup(high_alarms, ESP_EXT1_WAKEUP_ANY_HIGH) != ESP_OK) {
+ mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
+ }
+ }
+ size_t low_pins[2];
+ size_t j = 0;
+ for (size_t i = 0; i < 64; i++) {
+ uint64_t mask = 1ull << i;
+ if ((low_alarms & mask) != 0) {
+ low_pins[j++] = i;
+ }
+ if (j == 2) {
+ break;
+ }
+ }
+ if (low_count > 1) {
+ if (esp_sleep_enable_ext1_wakeup(1ull << low_pins[1], ESP_EXT1_WAKEUP_ALL_LOW) != ESP_OK) {
+ mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
+ }
+ }
+ if (low_count > 0) {
+ if (esp_sleep_enable_ext0_wakeup(low_pins[0], 0) != ESP_OK) {
+ mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
+ }
+ }
+ } else {
+ // Enable GPIO wake up if we're sleeping.
+ esp_sleep_enable_gpio_wakeup();
+ }
+ // Set GPIO interrupts so they wake us from light sleep or from idle via the
+ // interrupt handler above.
+ pin_31_0_status = 0;
+ pin_63_32_status = 0;
+ if (gpio_isr_register(gpio_interrupt, NULL, 0, &gpio_interrupt_handle) != ESP_OK) {
+ mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
+ }
+ for (size_t i = 0; i < 64; i++) {
+ uint64_t mask = 1ull << i;
+ bool high = (high_alarms & mask) != 0;
+ bool low = (low_alarms & mask) != 0;
+ bool pull = (pull_pins & mask) != 0;
+ if (!(high || low)) {
+ continue;
+ }
+ if (rtc_gpio_is_valid_gpio(i)) {
+ rtc_gpio_deinit(i);
+ }
+ gpio_int_type_t interrupt_mode = GPIO_INTR_DISABLE;
+ gpio_pull_mode_t pull_mode = GPIO_FLOATING;
+ if (high) {
+ interrupt_mode = GPIO_INTR_HIGH_LEVEL;
+ pull_mode = GPIO_PULLDOWN_ONLY;
+ }
+ if (low) {
+ interrupt_mode = GPIO_INTR_LOW_LEVEL;
+ pull_mode = GPIO_PULLUP_ONLY;
+ }
+ gpio_set_direction(i, GPIO_MODE_DEF_INPUT);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[i], PIN_FUNC_GPIO);
+ if (pull) {
+ gpio_set_pull_mode(i, pull_mode);
+ size_t j = 0;
+ while (gpio_get_level(i) == false) {
+ j++;
+ }
+ }
+ never_reset_pin_number(i);
+ // Sets interrupt type and wakeup bits.
+ gpio_wakeup_enable(i, interrupt_mode);
+ gpio_intr_enable(i);
+ }
+}
+
+
+void alarm_pin_pinalarm_prepare_for_deep_sleep(void) {
+ if (pull_pins == 0) {
+ return;
+ }
+ for (size_t i = 0; i < 64; i++) {
+ uint64_t mask = 1ull << i;
+ bool pull = (pull_pins & mask) != 0;
+ if (!pull) {
+ continue;
+ }
+ bool high = (high_alarms & mask) != 0;
+ bool low = (low_alarms & mask) != 0;
+ // The pull direction is opposite from alarm value.
+ if (high) {
+ rtc_gpio_pullup_dis(i);
+ rtc_gpio_pulldown_en(i);
+ }
+ if (low) {
+ rtc_gpio_pullup_en(i);
+ rtc_gpio_pulldown_dis(i);
+ }
+ }
+}
diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h
index 0eaa7777f..93672c1f2 100644
--- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h
+++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h
@@ -31,7 +31,11 @@ typedef struct {
mp_obj_base_t base;
mcu_pin_obj_t *pin;
bool value;
- bool all_same_value;
- bool edge;
bool pull;
-} alarm_pin_pin_alarm_obj_t;
+} alarm_pin_pinalarm_obj_t;
+
+void alarm_pin_pinalarm_reset(void);
+void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
+void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
+mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
+bool alarm_pin_pinalarm_woke_us_up(void);
diff --git a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
index 4d0bba238..bcde0ab3c 100644
--- a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
+++ b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
@@ -34,23 +34,23 @@
#include "shared-bindings/alarm/time/TimeAlarm.h"
#include "shared-bindings/time/__init__.h"
-void common_hal_alarm_time_time_alarm_construct(alarm_time_time_alarm_obj_t *self, mp_float_t monotonic_time) {
+void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) {
self->monotonic_time = monotonic_time;
}
-mp_float_t common_hal_alarm_time_time_alarm_get_monotonic_time(alarm_time_time_alarm_obj_t *self) {
+mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self) {
return self->monotonic_time;
}
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
// First, check to see if we match
for (size_t i = 0; i < n_alarms; i++) {
- if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) {
+ if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
return alarms[i];
}
}
- alarm_time_time_alarm_obj_t *timer = m_new_obj(alarm_time_time_alarm_obj_t);
- timer->base.type = &alarm_time_time_alarm_type;
+ alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
+ timer->base.type = &alarm_time_timealarm_type;
// TODO: Set monotonic_time based on the RTC state.
timer->monotonic_time = 0.0f;
return timer;
@@ -63,9 +63,7 @@ STATIC bool woke_up = false;
void timer_callback(void *arg) {
(void) arg;
woke_up = true;
- if (sleeping_circuitpython_task) {
- xTaskNotifyGive(sleeping_circuitpython_task);
- }
+ xTaskNotifyGive(circuitpython_task);
}
bool alarm_time_timealarm_woke_us_up(void) {
@@ -79,7 +77,24 @@ void alarm_time_timealarm_reset(void) {
woke_up = false;
}
-void alarm_time_timealarm_set_alarm(alarm_time_time_alarm_obj_t *self) {
+void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
+ bool timealarm_set = false;
+ alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL;
+
+ for (size_t i = 0; i < n_alarms; i++) {
+ if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
+ continue;
+ }
+ if (timealarm_set) {
+ mp_raise_ValueError(translate("Only one alarm.time alarm can be set."));
+ }
+ timealarm = MP_OBJ_TO_PTR(alarms[i]);
+ timealarm_set = true;
+ }
+ if (!timealarm_set) {
+ return;
+ }
+
if (pretend_sleep_timer != NULL) {
esp_timer_stop(pretend_sleep_timer);
} else {
@@ -94,7 +109,7 @@ void alarm_time_timealarm_set_alarm(alarm_time_time_alarm_obj_t *self) {
// Compute how long to actually sleep, considering the time now.
mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f;
- mp_float_t wakeup_in_secs = MAX(0.0f, self->monotonic_time - now_secs);
+ mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs);
const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000);
esp_sleep_enable_timer_wakeup(sleep_for_us);
diff --git a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.h b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.h
index 04c553009..dfd75524f 100644
--- a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.h
+++ b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.h
@@ -30,11 +30,11 @@
typedef struct {
mp_obj_base_t base;
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
-} alarm_time_time_alarm_obj_t;
+} alarm_time_timealarm_obj_t;
// Find the alarm object that caused us to wake up or create an equivalent one.
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
// Check for the wake up alarm from pretend deep sleep.
bool alarm_time_timealarm_woke_us_up(void);
-void alarm_time_timealarm_set_alarm(alarm_time_time_alarm_obj_t *self);
+void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
void alarm_time_timealarm_reset(void);
diff --git a/ports/esp32s2/common-hal/analogio/AnalogIn.h b/ports/esp32s2/common-hal/analogio/AnalogIn.h
index fed4d0217..b9c4866f2 100644
--- a/ports/esp32s2/common-hal/analogio/AnalogIn.h
+++ b/ports/esp32s2/common-hal/analogio/AnalogIn.h
@@ -29,7 +29,7 @@
#include "common-hal/microcontroller/Pin.h"
-#include "components/hal/include/hal/adc_types.h"
+#include "components/soc/include/hal/adc_types.h"
#include "FreeRTOS.h"
#include "freertos/semphr.h"
#include "py/obj.h"
diff --git a/ports/esp32s2/common-hal/busio/I2C.h b/ports/esp32s2/common-hal/busio/I2C.h
index c39d6d744..1a989e30a 100644
--- a/ports/esp32s2/common-hal/busio/I2C.h
+++ b/ports/esp32s2/common-hal/busio/I2C.h
@@ -29,7 +29,7 @@
#include "common-hal/microcontroller/Pin.h"
-#include "components/hal/include/hal/i2c_types.h"
+#include "components/soc/include/hal/i2c_types.h"
#include "FreeRTOS.h"
#include "freertos/semphr.h"
#include "py/obj.h"
diff --git a/ports/esp32s2/common-hal/busio/SPI.c b/ports/esp32s2/common-hal/busio/SPI.c
index 562881585..c4d54ec81 100644
--- a/ports/esp32s2/common-hal/busio/SPI.c
+++ b/ports/esp32s2/common-hal/busio/SPI.c
@@ -248,12 +248,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
spi_bus_free(self->host_id);
common_hal_reset_pin(self->clock_pin);
- if (self->MOSI_pin != NULL) {
- common_hal_reset_pin(self->MOSI_pin);
- }
- if (self->MISO_pin != NULL) {
- common_hal_reset_pin(self->MISO_pin);
- }
+ common_hal_reset_pin(self->MOSI_pin);
+ common_hal_reset_pin(self->MISO_pin);
self->clock_pin = NULL;
self->MISO_pin = NULL;
self->MOSI_pin = NULL;
@@ -273,7 +269,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
self->bits = bits;
self->target_frequency = baudrate;
self->hal_context.timing_conf = &self->timing_conf;
- esp_err_t result = spi_hal_cal_clock_conf(&self->hal_context,
+ esp_err_t result = spi_hal_get_clock_conf(&self->hal_context,
self->target_frequency,
128 /* duty_cycle */,
self->connected_through_gpio,
@@ -366,7 +362,8 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou
burst_length = sizeof(hal->hw->data_buf);
// When switching to non-DMA, we need to make sure DMA is off. Otherwise,
// the S2 will transmit zeroes instead of our data.
- spi_ll_txdma_disable(hal->hw);
+ hal->hw->dma_out_link.dma_tx_ena = 0;
+ hal->hw->dma_out_link.stop = 1;
}
// This rounds up.
diff --git a/ports/esp32s2/common-hal/busio/SPI.h b/ports/esp32s2/common-hal/busio/SPI.h
index f6c1c344a..d6203feae 100644
--- a/ports/esp32s2/common-hal/busio/SPI.h
+++ b/ports/esp32s2/common-hal/busio/SPI.h
@@ -30,8 +30,8 @@
#include "common-hal/microcontroller/Pin.h"
#include "components/driver/include/driver/spi_common_internal.h"
-#include "components/hal/include/hal/spi_hal.h"
-#include "components/hal/include/hal/spi_types.h"
+#include "components/soc/include/hal/spi_hal.h"
+#include "components/soc/include/hal/spi_types.h"
#include "py/obj.h"
typedef struct {
diff --git a/ports/esp32s2/common-hal/busio/UART.h b/ports/esp32s2/common-hal/busio/UART.h
index 1d7f13511..751fb2e00 100644
--- a/ports/esp32s2/common-hal/busio/UART.h
+++ b/ports/esp32s2/common-hal/busio/UART.h
@@ -29,7 +29,7 @@
#include "common-hal/microcontroller/Pin.h"
-#include "components/hal/include/hal/uart_types.h"
+#include "components/soc/include/hal/uart_types.h"
#include "py/obj.h"
typedef struct {
diff --git a/ports/esp32s2/common-hal/digitalio/DigitalInOut.c b/ports/esp32s2/common-hal/digitalio/DigitalInOut.c
index 152db1e71..a2a0209f9 100644
--- a/ports/esp32s2/common-hal/digitalio/DigitalInOut.c
+++ b/ports/esp32s2/common-hal/digitalio/DigitalInOut.c
@@ -30,7 +30,7 @@
#include "components/driver/include/driver/gpio.h"
-#include "components/hal/include/hal/gpio_hal.h"
+#include "components/soc/include/hal/gpio_hal.h"
void common_hal_digitalio_digitalinout_never_reset(
digitalio_digitalinout_obj_t *self) {
diff --git a/ports/esp32s2/common-hal/dualbank/__init__.c b/ports/esp32s2/common-hal/dualbank/__init__.c
new file mode 100644
index 000000000..1414f131d
--- /dev/null
+++ b/ports/esp32s2/common-hal/dualbank/__init__.c
@@ -0,0 +1,139 @@
+/*
+ * 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 "common-hal/dualbank/__init__.h"
+#include "shared-bindings/dualbank/__init__.h"
+
+#include <string.h>
+
+#include "esp_log.h"
+#include "esp_ota_ops.h"
+
+static const esp_partition_t *update_partition = NULL;
+static esp_ota_handle_t update_handle = 0;
+
+static const char *TAG = "dualbank";
+
+void dualbank_reset(void) {
+ // should use `abort` instead of `end`
+ // but not in idf v4.2
+ // esp_ota_abort(update_handle);
+ if (esp_ota_end(update_handle) == ESP_OK) {
+ update_handle = 0;
+ update_partition = NULL;
+ }
+}
+
+static void __attribute__((noreturn)) task_fatal_error(void) {
+ ESP_LOGE(TAG, "Exiting task due to fatal error...");
+ mp_raise_RuntimeError(translate("Update Failed"));
+}
+
+void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t offset) {
+ esp_err_t err;
+
+ const esp_partition_t *running = esp_ota_get_running_partition();
+ const esp_partition_t *last_invalid = esp_ota_get_last_invalid_partition();
+
+ if (update_partition == NULL) {
+ update_partition = esp_ota_get_next_update_partition(NULL);
+
+ ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
+ running->type, running->subtype, running->address);
+
+ ESP_LOGI(TAG, "Writing partition type %d subtype %d (offset 0x%08x)\n",
+ update_partition->type, update_partition->subtype, update_partition->address);
+
+ assert(update_partition != NULL);
+ }
+
+ if (update_handle == 0) {
+ if (len > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) {
+ esp_app_desc_t new_app_info;
+ memcpy(&new_app_info, &((char *)buf)[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));
+ ESP_LOGI(TAG, "New firmware version: %s", new_app_info.version);
+
+ esp_app_desc_t running_app_info;
+ if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {
+ ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
+ }
+
+ esp_app_desc_t invalid_app_info;
+ if (esp_ota_get_partition_description(last_invalid, &invalid_app_info) == ESP_OK) {
+ ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version);
+ }
+
+ // check new version with running version
+ if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {
+ ESP_LOGW(TAG, "New version is the same as running version.");
+ task_fatal_error();
+ }
+
+ // check new version with last invalid partition
+ if (last_invalid != NULL) {
+ if (memcmp(new_app_info.version, invalid_app_info.version, sizeof(new_app_info.version)) == 0) {
+ ESP_LOGW(TAG, "New version is the same as invalid version.");
+ task_fatal_error();
+ }
+ }
+
+ err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
+ task_fatal_error();
+ }
+ } else {
+ ESP_LOGE(TAG, "received package is not fit len");
+ task_fatal_error();
+ }
+ }
+
+ if (offset == 0) {
+ err = esp_ota_write(update_handle, buf, len);
+ } else {
+ err = esp_ota_write_with_offset(update_handle, buf, len, offset);
+ }
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "esp_ota_write failed (%s)", esp_err_to_name(err));
+ task_fatal_error();
+ }
+}
+
+void common_hal_dualbank_switch(void) {
+ if (esp_ota_end(update_handle) == ESP_OK) {
+ update_handle = 0;
+ update_partition = NULL;
+ }
+ esp_err_t err = esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
+ if (err != ESP_OK) {
+ if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
+ ESP_LOGE(TAG, "Image validation failed, image is corrupted");
+ mp_raise_RuntimeError(translate("Firmware image is invalid"));
+ }
+ ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
+ task_fatal_error();
+ }
+}
diff --git a/ports/esp32s2/common-hal/dualbank/__init__.h b/ports/esp32s2/common-hal/dualbank/__init__.h
new file mode 100644
index 000000000..8b18336c9
--- /dev/null
+++ b/ports/esp32s2/common-hal/dualbank/__init__.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_ESP32S2_COMMON_HAL_DUALBANK___INIT___H
+#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DUALBANK___INIT___H
+
+extern void dualbank_reset(void);
+
+#endif //MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DUALBANK___INIT___H
diff --git a/ports/esp32s2/common-hal/microcontroller/Pin.c b/ports/esp32s2/common-hal/microcontroller/Pin.c
index 81dfa1308..fca89ce8e 100644
--- a/ports/esp32s2/common-hal/microcontroller/Pin.c
+++ b/ports/esp32s2/common-hal/microcontroller/Pin.c
@@ -32,7 +32,7 @@
#include "py/mphal.h"
#include "components/driver/include/driver/gpio.h"
-#include "components/hal/include/hal/gpio_hal.h"
+#include "components/soc/include/hal/gpio_hal.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
@@ -89,6 +89,9 @@ void reset_pin_number(gpio_num_t pin_number) {
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ if (pin == NULL) {
+ return;
+ }
reset_pin_number(pin->number);
}
diff --git a/ports/esp32s2/common-hal/wifi/Network.c b/ports/esp32s2/common-hal/wifi/Network.c
index e90b3d552..2674df065 100644
--- a/ports/esp32s2/common-hal/wifi/Network.c
+++ b/ports/esp32s2/common-hal/wifi/Network.c
@@ -48,3 +48,9 @@ mp_obj_t common_hal_wifi_network_get_rssi(wifi_network_obj_t *self) {
mp_obj_t common_hal_wifi_network_get_channel(wifi_network_obj_t *self) {
return mp_obj_new_int(self->record.primary);
}
+
+mp_obj_t common_hal_wifi_network_get_country(wifi_network_obj_t *self) {
+ const char* cstr = (const char*) self->record.country.cc;
+ // 2 instead of strlen(cstr) as this gives us only the country-code
+ return mp_obj_new_str(cstr, 2);
+}
diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c
index 05506783e..3bc2258a4 100644
--- a/ports/esp32s2/common-hal/wifi/Radio.c
+++ b/ports/esp32s2/common-hal/wifi/Radio.c
@@ -198,6 +198,17 @@ mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self) {
if (esp_wifi_sta_get_ap_info(&self->ap_info.record) != ESP_OK){
return mp_const_none;
} else {
+ if (strlen(self->ap_info.record.country.cc) == 0) {
+ // Workaround to fill country related information in ap_info until ESP-IDF carries a fix
+ // esp_wifi_sta_get_ap_info does not appear to fill wifi_country_t (e.g. country.cc) details
+ // (IDFGH-4437) #6267
+ // Note: It is possible that Wi-Fi APs don't have a CC set, then even after this workaround
+ // the element would remain empty.
+ memset(&self->ap_info.record.country, 0, sizeof(wifi_country_t));
+ if (esp_wifi_get_country(&self->ap_info.record.country) != ESP_OK) {
+ return mp_const_none;
+ }
+ }
memcpy(&ap_info->record, &self->ap_info.record, sizeof(wifi_ap_record_t));
return MP_OBJ_FROM_PTR(ap_info);
}
diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf
-Subproject d06744f5efc382c61cbad8758107cec308feef0
+Subproject ebe7784258d8c10e9cc334ccc00c3fd270746c8
diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk
index b3b2a6d70..2ad8afb51 100644
--- a/ports/esp32s2/mpconfigport.mk
+++ b/ports/esp32s2/mpconfigport.mk
@@ -19,6 +19,7 @@ CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_AUDIOIO = 0
CIRCUITPY_CANIO = 1
CIRCUITPY_COUNTIO = 1
+CIRCUITPY_DUALBANK = 1
CIRCUITPY_FREQUENCYIO = 1
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_ROTARYIO = 1
diff --git a/ports/esp32s2/peripherals/pins.h b/ports/esp32s2/peripherals/pins.h
index dc28385bd..e0f5e7ddf 100644
--- a/ports/esp32s2/peripherals/pins.h
+++ b/ports/esp32s2/peripherals/pins.h
@@ -35,9 +35,9 @@
#include "esp32s2_peripherals_config.h"
#include "esp-idf/config/sdkconfig.h"
-#include "components/hal/include/hal/gpio_types.h"
-#include "components/hal/include/hal/adc_types.h"
-#include "components/hal/include/hal/touch_sensor_types.h"
+#include "components/soc/include/hal/gpio_types.h"
+#include "components/soc/include/hal/adc_types.h"
+#include "components/soc/include/hal/touch_sensor_types.h"
typedef struct {
PIN_PREFIX_FIELDS
diff --git a/ports/esp32s2/supervisor/esp_port.h b/ports/esp32s2/supervisor/esp_port.h
index 1164666cd..8b9e13829 100644
--- a/ports/esp32s2/supervisor/esp_port.h
+++ b/ports/esp32s2/supervisor/esp_port.h
@@ -30,6 +30,6 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
-extern TaskHandle_t sleeping_circuitpython_task;
+extern TaskHandle_t circuitpython_task;
#endif // MICROPY_INCLUDED_ESP32S2_SUPERVISOR_PORT_H
diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c
index 4dc985cfe..213473b8d 100644
--- a/ports/esp32s2/supervisor/port.c
+++ b/ports/esp32s2/supervisor/port.c
@@ -41,6 +41,7 @@
#include "common-hal/busio/I2C.h"
#include "common-hal/busio/SPI.h"
#include "common-hal/busio/UART.h"
+#include "common-hal/dualbank/__init__.h"
#include "common-hal/ps2io/Ps2.h"
#include "common-hal/pulseio/PulseIn.h"
#include "common-hal/pwmio/PWMOut.h"
@@ -54,7 +55,7 @@
#include "peripherals/pcnt.h"
#include "peripherals/timer.h"
#include "peripherals/touch.h"
-#include "components/esp_rom/include/esp_rom_uart.h"
+#include "components/esp_rom/include/esp32s2/rom/ets_sys.h"
#include "components/heap/include/esp_heap_caps.h"
#include "components/xtensa/include/esp_debug_helpers.h"
#include "components/soc/soc/esp32s2/include/soc/cache_memory.h"
@@ -66,13 +67,22 @@ uint32_t* heap;
uint32_t heap_size;
STATIC esp_timer_handle_t _tick_timer;
+STATIC esp_timer_handle_t _sleep_timer;
+
+TaskHandle_t circuitpython_task = NULL;
extern void esp_restart(void) NORETURN;
void tick_timer_cb(void* arg) {
supervisor_tick();
+
+ // CircuitPython's VM is run in a separate FreeRTOS task from timer callbacks. So, we have to
+ // notify the main task every time in case it's waiting for us.
+ xTaskNotifyGive(circuitpython_task);
}
+void sleep_timer_cb(void* arg);
+
safe_mode_t port_init(void) {
esp_timer_create_args_t args;
args.callback = &tick_timer_cb;
@@ -81,9 +91,17 @@ safe_mode_t port_init(void) {
args.name = "CircuitPython Tick";
esp_timer_create(&args, &_tick_timer);
- #ifdef DEBUG
+ args.callback = &sleep_timer_cb;
+ args.arg = NULL;
+ args.dispatch_method = ESP_TIMER_TASK;
+ args.name = "CircuitPython Sleep";
+ esp_timer_create(&args, &_sleep_timer);
+
+ circuitpython_task = xTaskGetCurrentTaskHandle();
+
// Send the ROM output out of the UART. This includes early logs.
- esp_rom_install_channel_putc(1, esp_rom_uart_putc);
+ #ifdef DEBUG
+ ets_install_uart_printf();
#endif
heap = NULL;
@@ -103,11 +121,15 @@ safe_mode_t port_init(void) {
}
esp_reset_reason_t reason = esp_reset_reason();
- if (reason == ESP_RST_BROWNOUT) {
- return BROWNOUT;
- }
- if (reason == ESP_RST_PANIC) {
- return HARD_CRASH;
+ switch (reason) {
+ case ESP_RST_BROWNOUT:
+ return BROWNOUT;
+ case ESP_RST_PANIC:
+ case ESP_RST_INT_WDT:
+ case ESP_RST_WDT:
+ return HARD_CRASH;
+ default:
+ break;
}
return NO_SAFE_MODE;
@@ -123,6 +145,10 @@ void reset_port(void) {
analogout_reset();
#endif
+#if CIRCUITPY_DUALBANK
+ dualbank_reset();
+#endif
+
#if CIRCUITPY_PS2IO
ps2_reset();
#endif
@@ -247,32 +273,24 @@ void port_enable_tick(void) {
// Disable 1/1024 second tick.
void port_disable_tick(void) {
esp_timer_stop(_tick_timer);
-
- // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
- // Tick disable can happen via auto-reload so poke the main task here.
- if (sleeping_circuitpython_task != NULL) {
- xTaskNotifyGive(sleeping_circuitpython_task);
- }
}
-TickType_t sleep_time_duration;
+void sleep_timer_cb(void* arg) {
+ xTaskNotifyGive(circuitpython_task);
+}
void port_interrupt_after_ticks(uint32_t ticks) {
- sleep_time_duration = (ticks * 100)/1024;
+ uint64_t timeout_us = ticks * 1000000ull / 1024;
+ if (esp_timer_start_once(_sleep_timer, timeout_us) != ESP_OK) {
+ esp_timer_stop(_sleep_timer);
+ esp_timer_start_once(_sleep_timer, timeout_us);
+ }
}
+// On the ESP we use FreeRTOS notifications instead of interrupts so this is a
+// bit of a misnomer.
void port_idle_until_interrupt(void) {
- uint32_t notify_value = 0;
-
- if (sleep_time_duration == 0) {
- return;
- }
- sleeping_circuitpython_task = xTaskGetCurrentTaskHandle();
- xTaskNotifyWait(0x01, 0x01, &notify_value, sleep_time_duration );
- sleeping_circuitpython_task = NULL;
- if (notify_value == 1) {
- mp_handle_pending();
- }
+ xTaskNotifyWait(0x01, 0x01, NULL, portMAX_DELAY);
}
// Wrap main in app_main that the IDF expects.
diff --git a/ports/esp32s2/supervisor/usb.c b/ports/esp32s2/supervisor/usb.c
index 2bfcdfb12..16657d407 100644
--- a/ports/esp32s2/supervisor/usb.c
+++ b/ports/esp32s2/supervisor/usb.c
@@ -26,6 +26,7 @@
*/
#include "supervisor/usb.h"
+#include "supervisor/esp_port.h"
#include "lib/utils/interrupt_char.h"
#include "lib/mp-readline/readline.h"
@@ -33,8 +34,7 @@
#include "components/driver/include/driver/periph_ctrl.h"
#include "components/driver/include/driver/gpio.h"
#include "components/esp_rom/include/esp32s2/rom/gpio.h"
-#include "components/esp_rom/include/esp_rom_gpio.h"
-#include "components/hal/esp32s2/include/hal/gpio_ll.h"
+#include "components/soc/src/esp32s2/include/hal/gpio_ll.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -52,8 +52,6 @@
StackType_t usb_device_stack[USBD_STACK_SIZE];
StaticTask_t usb_device_taskdef;
-TaskHandle_t sleeping_circuitpython_task = NULL;
-
// USB Device Driver task
// This top level thread process all usb events and invoke callbacks
void usb_device_task(void* param)
@@ -78,23 +76,20 @@ static void configure_pins (usb_hal_context_t *usb)
* Introduce additional parameters in usb_hal_context_t when adding support
* for USB Host.
*/
- for ( const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin ) {
- if ( (usb->use_external_phy) || (iopin->ext_phy_only == 0) ) {
- esp_rom_gpio_pad_select_gpio(iopin->pin);
- if ( iopin->is_output ) {
- esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false);
- }
- else {
- esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false);
- if ( (iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH) ) {
- gpio_ll_input_enable(&GPIO, iopin->pin);
- }
+ for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
+ if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) {
+ gpio_pad_select_gpio(iopin->pin);
+ if (iopin->is_output) {
+ gpio_matrix_out(iopin->pin, iopin->func, false, false);
+ } else {
+ gpio_matrix_in(iopin->pin, iopin->func, false);
+ gpio_pad_input_enable(iopin->pin);
}
- esp_rom_gpio_pad_unhold(iopin->pin);
+ gpio_pad_unhold(iopin->pin);
}
}
- if ( !usb->use_external_phy ) {
- gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
+ if (!usb->use_external_phy) {
+ gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
}
}
@@ -131,8 +126,6 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char)
mp_keyboard_interrupt();
// CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
// So, we must notify the other task when a CTRL-C is received.
- if (sleeping_circuitpython_task != NULL) {
- xTaskNotifyGive(sleeping_circuitpython_task);
- }
+ xTaskNotifyGive(circuitpython_task);
}
}
diff --git a/ports/litex/boards/fomu/fomu-spi.ld b/ports/litex/boards/fomu/fomu-spi.ld
index 9b6443c67..e7db25b0c 100644
--- a/ports/litex/boards/fomu/fomu-spi.ld
+++ b/ports/litex/boards/fomu/fomu-spi.ld
@@ -51,6 +51,11 @@ SECTIONS
*(.text.tu_edpt_dir)
*(.text.tu_fifo_empty)
*(.text.usbd_edpt_busy)
+ *(.text.usb_irq_handler)
+ *(.text.supervisor_tick)
+ *(.text.port_get_raw_ticks)
+ *(.text.__modsi3)
+ *(.text.__udivsi3)
*(.text.irq_getmask)
*(.text.irq_setmask)
*(.text.irq_pending)
diff --git a/ports/litex/common-hal/microcontroller/Pin.c b/ports/litex/common-hal/microcontroller/Pin.c
index 38601e0d3..4d088a076 100644
--- a/ports/litex/common-hal/microcontroller/Pin.c
+++ b/ports/litex/common-hal/microcontroller/Pin.c
@@ -42,6 +42,9 @@ void reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ if (pin == NULL) {
+ return;
+ }
reset_pin_number(0, pin->number);
}
diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c
index 3c9166114..522a41e2e 100644
--- a/ports/litex/common-hal/microcontroller/__init__.c
+++ b/ports/litex/common-hal/microcontroller/__init__.c
@@ -59,12 +59,15 @@ void common_hal_mcu_delay_us(uint32_t delay) {
volatile uint32_t nesting_count = 0;
+__attribute__((section(".ramtext")))
void common_hal_mcu_disable_interrupts(void) {
- irq_setie(0);
- // __DMB();
+ if (nesting_count == 0) {
+ irq_setie(0);
+ }
nesting_count++;
}
+__attribute__((section(".ramtext")))
void common_hal_mcu_enable_interrupts(void) {
if (nesting_count == 0) {
// This is very very bad because it means there was mismatched disable/enables so we
diff --git a/ports/litex/mphalport.c b/ports/litex/mphalport.c
index 862f16393..c7369dc05 100644
--- a/ports/litex/mphalport.c
+++ b/ports/litex/mphalport.c
@@ -44,16 +44,31 @@ void mp_hal_delay_us(mp_uint_t delay) {
extern void SysTick_Handler(void);
+// This value contains the number of times "common_hal_mcu_disable_interrupts()"
+// has been called without calling "common_hal_mcu_enable_interrupts()". Since
+// this is the interrupt handler, that means we're handling an interrupt, so
+// this value should be `0`.
+//
+// Interrupts should already be disabled when this handler is running, which means
+// this value is logically already `1`. If we didn't do this, then interrupts would
+// be prematurely enabled by interrupt handlers that enable and disable interrupts.
+extern volatile uint32_t nesting_count;
+
__attribute__((section(".ramtext")))
void isr(void) {
uint8_t irqs = irq_pending() & irq_getmask();
+ // Increase the "nesting count". Note: This should be going from 0 -> 1.
+ nesting_count += 1;
#ifdef CFG_TUSB_MCU
if (irqs & (1 << USB_INTERRUPT))
usb_irq_handler();
#endif
if (irqs & (1 << TIMER0_INTERRUPT))
SysTick_Handler();
+
+ // Decrease the "nesting count". Note: This should be going from 1 -> 0.
+ nesting_count -= 1;
}
mp_uint_t cpu_get_regs_and_sp(mp_uint_t *regs) {
diff --git a/ports/litex/supervisor/port.c b/ports/litex/supervisor/port.c
index 4dea02065..04ff1c09b 100644
--- a/ports/litex/supervisor/port.c
+++ b/ports/litex/supervisor/port.c
@@ -32,6 +32,8 @@
#include "irq.h"
#include "csr.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
// Global millisecond tick count. 1024 per second because most RTCs are clocked with 32.768khz
// crystals.
volatile uint64_t raw_ticks = 0;
@@ -129,9 +131,9 @@ uint32_t port_get_saved_word(void) {
uint64_t port_get_raw_ticks(uint8_t* subticks) {
// Reading 64 bits may take two loads, so turn of interrupts while we do it.
- irq_setie(false);
+ common_hal_mcu_disable_interrupts();
uint64_t raw_tick_snapshot = raw_ticks;
- irq_setie(true);
+ common_hal_mcu_enable_interrupts();
return raw_tick_snapshot;
}
diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h b/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h
index e96ec13dd..e027e2b5e 100644
--- a/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h
+++ b/ports/mimxrt10xx/boards/feather_m7_1011/mpconfigboard.h
@@ -1,4 +1,4 @@
-#define MICROPY_HW_BOARD_NAME "Feather MIMXRT1011"
+#define MICROPY_HW_BOARD_NAME "Adafruit Feather MIMXRT1011"
#define MICROPY_HW_MCU_NAME "IMXRT1011DAE5A"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO_00)
diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c
index 8fe1b799d..ce7cbea7e 100644
--- a/ports/mimxrt10xx/common-hal/busio/SPI.c
+++ b/ports/mimxrt10xx/common-hal/busio/SPI.c
@@ -220,12 +220,9 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
never_reset_spi[self->clock->bank_idx - 1] = false;
common_hal_reset_pin(self->clock->pin);
- if (self->mosi != NULL) {
- common_hal_reset_pin(self->mosi->pin);
- }
- if (self->miso != NULL) {
- common_hal_reset_pin(self->miso->pin);
- }
+ common_hal_reset_pin(self->mosi->pin);
+ common_hal_reset_pin(self->miso->pin);
+
self->clock = NULL;
self->mosi = NULL;
self->miso = NULL;
diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c
index db5582d15..03a6e8f3e 100644
--- a/ports/mimxrt10xx/common-hal/busio/UART.c
+++ b/ports/mimxrt10xx/common-hal/busio/UART.c
@@ -295,12 +295,10 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
LPUART_Deinit(self->uart);
gc_free(self->ringbuf);
- if (self->rx) {
- common_hal_reset_pin(self->rx->pin);
- }
- if (self->tx) {
- common_hal_reset_pin(self->tx->pin);
- }
+
+ common_hal_reset_pin(self->rx->pin);
+ common_hal_reset_pin(self->tx->pin);
+
self->rx = NULL;
self->tx = NULL;
diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c
index a005924e2..50970f8e2 100644
--- a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c
+++ b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c
@@ -67,6 +67,9 @@ void reset_all_pins(void) {
// Since i.MX pins need extra register and reset information to reset properly,
// resetting pins by number alone has been removed.
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ if (pin == NULL) {
+ return;
+ }
never_reset_pins[pin->mux_idx] = false;
claimed_pins[pin->mux_idx] = false;
*(uint32_t*)pin->mux_reg = pin->mux_reset;
diff --git a/ports/nrf/boards/bastble/README.md b/ports/nrf/boards/bastble/README.md
new file mode 100644
index 000000000..0af6209bd
--- /dev/null
+++ b/ports/nrf/boards/bastble/README.md
@@ -0,0 +1,4 @@
+# Electronic Cats BastBLE
+
+The [BastBLE](https://electroniccats.com/store/bast-ble/) based on Nordic nRF 52840 and containing
+a powerful Cortex M4F. This board include a external memory QSPI flash.
diff --git a/ports/nrf/boards/bastble/board.c b/ports/nrf/boards/bastble/board.c
new file mode 100644
index 000000000..b6fb04f06
--- /dev/null
+++ b/ports/nrf/boards/bastble/board.c
@@ -0,0 +1,41 @@
+/*
+ * 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 "nrf.h"
+#include "nrf_rtc.h"
+
+void board_init(void) {
+
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/nrf/boards/bastble/mpconfigboard.h b/ports/nrf/boards/bastble/mpconfigboard.h
new file mode 100644
index 000000000..e36227c6b
--- /dev/null
+++ b/ports/nrf/boards/bastble/mpconfigboard.h
@@ -0,0 +1,25 @@
+#include "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "BastBLE"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+
+#if QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 30)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 29)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 28)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 2)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 3)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 26)
+#endif
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P1_10)
+#define DEFAULT_I2C_BUS_SDA (&pin_P1_11)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P1_00)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P1_06)
+#define DEFAULT_SPI_BUS_MISO (&pin_P0_15)
+
+#define DEFAULT_UART_BUS_RX (&pin_P0_09)
+#define DEFAULT_UART_BUS_TX (&pin_P0_10)
diff --git a/ports/nrf/boards/bastble/mpconfigboard.mk b/ports/nrf/boards/bastble/mpconfigboard.mk
new file mode 100644
index 000000000..eca900de7
--- /dev/null
+++ b/ports/nrf/boards/bastble/mpconfigboard.mk
@@ -0,0 +1,10 @@
+USB_VID = 0x1209
+USB_PID = 0x805A
+USB_PRODUCT = "BastBLE"
+USB_MANUFACTURER = "ElectronicCats"
+
+MCU_CHIP = nrf52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q16C"
diff --git a/ports/nrf/boards/bastble/pins.c b/ports/nrf/boards/bastble/pins.c
new file mode 100644
index 000000000..b35dad43d
--- /dev/null
+++ b/ports/nrf/boards/bastble/pins.c
@@ -0,0 +1,47 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_11) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_10) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_00) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_02) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_13) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_06) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_15) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P1_09) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_07) },
+
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_03) },
+
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P1_11) },
+
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P1_10) },
+
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_06) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_00) },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P0_24) },
+
+ { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) },
+
+ // voltage sense battery
+ { MP_ROM_QSTR(MP_QSTR_VBAT), MP_ROM_PTR(&pin_P0_26) },
+
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_10) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_09) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index 537f43f23..53a40f9a6 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -470,7 +470,16 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
ble_drv_add_event_handler(scan_on_ble_evt, self->scan_results);
uint32_t nrf_timeout = SEC_TO_UNITS(timeout, UNIT_10_MS);
- if (timeout <= 0.0001) {
+ if (nrf_timeout > UINT16_MAX) {
+ // 0xffff / 100
+ mp_raise_ValueError(translate("timeout must be < 655.35 secs"));
+ }
+ if (nrf_timeout == 0 && timeout > 0.0f) {
+ // Make sure converted timeout is > 0 if original timeout is > 0.
+ mp_raise_ValueError(translate("non-zero timeout must be > 0.01"));
+ }
+
+ if (nrf_timeout) {
nrf_timeout = BLE_GAP_SCAN_TIMEOUT_UNLIMITED;
}
diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c
index bc7ff831a..23d6e23bf 100644
--- a/ports/nrf/common-hal/microcontroller/Pin.c
+++ b/ports/nrf/common-hal/microcontroller/Pin.c
@@ -134,6 +134,9 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ if (pin == NULL) {
+ return;
+ }
reset_pin_number(pin->number);
}
diff --git a/ports/stm/boards/feather_stm32f405_express/mpconfigboard.h b/ports/stm/boards/feather_stm32f405_express/mpconfigboard.h
index 0d49748c8..e69be6cf9 100644
--- a/ports/stm/boards/feather_stm32f405_express/mpconfigboard.h
+++ b/ports/stm/boards/feather_stm32f405_express/mpconfigboard.h
@@ -26,7 +26,7 @@
//Micropython setup
-#define MICROPY_HW_BOARD_NAME "Feather STM32F405 Express"
+#define MICROPY_HW_BOARD_NAME "Adafruit Feather STM32F405 Express"
#define MICROPY_HW_MCU_NAME "STM32F405RG"
#define FLASH_SIZE (0x100000)
diff --git a/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.h b/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.h
index 83a8bded3..435133954 100644
--- a/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.h
+++ b/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.h
@@ -42,6 +42,9 @@
// #define SPI_FLASH_SCK_PIN (&pin_PA05)
// #define SPI_FLASH_CS_PIN (&pin_PA04)
+#define DEFAULT_I2C_BUS_SCL (&pin_PB06)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB07)
+
#define CIRCUITPY_AUTORELOAD_DELAY_MS (500)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
diff --git a/ports/stm/boards/stm32f411ce_blackpill/pins.c b/ports/stm/boards/stm32f411ce_blackpill/pins.c
index 2f8aab6e8..16946b8be 100644
--- a/ports/stm/boards/stm32f411ce_blackpill/pins.c
+++ b/ports/stm/boards/stm32f411ce_blackpill/pins.c
@@ -35,5 +35,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_C14), MP_ROM_PTR(&pin_PC14) },
{ MP_ROM_QSTR(MP_QSTR_C13), MP_ROM_PTR(&pin_PC13) },
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PC13) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm/common-hal/microcontroller/Pin.c b/ports/stm/common-hal/microcontroller/Pin.c
index 0e333c71c..37c202d86 100644
--- a/ports/stm/common-hal/microcontroller/Pin.c
+++ b/ports/stm/common-hal/microcontroller/Pin.c
@@ -125,6 +125,9 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ if (pin == NULL) {
+ return;
+ }
reset_pin_number(pin->port, pin->number);
}
diff --git a/ports/unix/mphalport.h b/ports/unix/mphalport.h
index 6f2880d4e..4e459ffca 100644
--- a/ports/unix/mphalport.h
+++ b/ports/unix/mphalport.h
@@ -24,12 +24,14 @@
* THE SOFTWARE.
*/
#include <unistd.h>
+#include <stdbool.h>
#ifndef CHAR_CTRL_C
#define CHAR_CTRL_C (3)
#endif
void mp_hal_set_interrupt_char(char c);
+bool mp_hal_is_interrupted(void);
void mp_hal_stdio_mode_raw(void);
void mp_hal_stdio_mode_orig(void);
diff --git a/ports/unix/unix_mphal.c b/ports/unix/unix_mphal.c
index e9494d7ff..77deb3152 100644
--- a/ports/unix/unix_mphal.c
+++ b/ports/unix/unix_mphal.c
@@ -81,6 +81,10 @@ void mp_hal_set_interrupt_char(char c) {
}
}
+bool mp_hal_is_interrupted(void) {
+ return false;
+}
+
#if MICROPY_USE_READLINE == 1
#include <termios.h>