summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
m---------lib/tinyusb0
-rwxr-xr-xmain.c3
-rw-r--r--ports/atmel-samd/Makefile72
-rw-r--r--ports/atmel-samd/background.c7
-rw-r--r--ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/arduino_zero/board.c7
-rw-r--r--ports/atmel-samd/boards/arduino_zero/mpconfigboard.h10
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h40
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h40
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h37
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h38
-rw-r--r--ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h37
-rw-r--r--ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h7
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk3
-rwxr-xr-xports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h38
-rwxr-xr-xports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/gemma_m0/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/board.c7
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h11
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk3
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h43
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h38
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h7
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/meowmeow/mpconfigboard.h6
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h40
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/board.c7
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h19
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk3
-rw-r--r--ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h7
-rw-r--r--ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/trinket_m0/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h42
-rw-r--r--ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/ugame10/mpconfigboard.h39
-rw-r--r--ports/atmel-samd/boards/ugame10/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.c47
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.h3
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.c16
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.h1
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/__init__.c220
-rwxr-xr-xports/atmel-samd/common-hal/supervisor/Runtime.c7
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/Device.c106
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/__init__.c152
-rw-r--r--ports/atmel-samd/external_flash/external_flash.h64
-rw-r--r--ports/atmel-samd/mpconfigport.h10
-rw-r--r--ports/atmel-samd/mpconfigport.mk2
-rw-r--r--ports/atmel-samd/mphalport.c34
-rw-r--r--ports/atmel-samd/mphalport.h2
m---------ports/atmel-samd/peripherals0
-rw-r--r--ports/atmel-samd/reset.c4
-rw-r--r--ports/atmel-samd/supervisor/internal_flash.c (renamed from ports/atmel-samd/internal_flash.c)112
-rw-r--r--ports/atmel-samd/supervisor/internal_flash.h (renamed from ports/atmel-samd/internal_flash.h)19
-rw-r--r--ports/atmel-samd/supervisor/internal_flash_root_pointers.h31
-rw-r--r--ports/atmel-samd/supervisor/port.c39
-rw-r--r--ports/atmel-samd/supervisor/qspi_flash.c (renamed from ports/atmel-samd/external_flash/qspi_flash.c)22
-rw-r--r--ports/atmel-samd/supervisor/serial.c79
-rw-r--r--ports/atmel-samd/supervisor/usb.c59
-rw-r--r--ports/atmel-samd/tick.h2
-rw-r--r--ports/atmel-samd/usb.c326
-rw-r--r--ports/atmel-samd/usb_mass_storage.c338
-rw-r--r--ports/esp8266/Makefile2
-rw-r--r--ports/esp8266/mpconfigport.h2
-rwxr-xr-xports/nrf/Makefile48
-rw-r--r--ports/nrf/README.md2
-rw-r--r--ports/nrf/background.c11
-rw-r--r--ports/nrf/board_busses.c2
-rw-r--r--ports/nrf/boards/feather_nrf52840_express/board.c2
-rw-r--r--ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h23
-rw-r--r--ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk9
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk/board.c2
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h25
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk9
-rw-r--r--ports/nrf/boards/pca10056/board.c2
-rw-r--r--ports/nrf/boards/pca10056/mpconfigboard.h23
-rw-r--r--ports/nrf/boards/pca10056/mpconfigboard.mk9
-rw-r--r--ports/nrf/boards/pca10059/board.c5
-rw-r--r--ports/nrf/boards/pca10059/mpconfigboard.mk5
-rw-r--r--ports/nrf/common-hal/busio/SPI.c18
-rw-r--r--ports/nrf/common-hal/busio/UART.c2
-rw-r--r--ports/nrf/common-hal/digitalio/DigitalInOut.c5
-rw-r--r--ports/nrf/common-hal/microcontroller/Pin.c13
-rw-r--r--ports/nrf/common-hal/microcontroller/Pin.h1
-rw-r--r--ports/nrf/common-hal/microcontroller/Processor.c7
-rw-r--r--ports/nrf/common-hal/pulseio/PulseIn.c2
-rw-r--r--ports/nrf/common-hal/pulseio/PulseOut.c2
-rw-r--r--ports/nrf/common-hal/usb_hid/Device.h94
-rw-r--r--ports/nrf/internal_flash.c226
-rw-r--r--ports/nrf/mpconfigport.h5
-rw-r--r--ports/nrf/mpconfigport.mk1
-rw-r--r--ports/nrf/mphalport.c81
-rw-r--r--ports/nrf/nrfx_config.h3
-rw-r--r--ports/nrf/peripherals/nrf/timers.c2
-rw-r--r--ports/nrf/supervisor/filesystem.c97
-rw-r--r--ports/nrf/supervisor/internal_flash.c121
-rw-r--r--ports/nrf/supervisor/internal_flash.h (renamed from ports/nrf/internal_flash.h)19
-rw-r--r--ports/nrf/supervisor/internal_flash_root_pointers.h31
-rw-r--r--ports/nrf/supervisor/port.c7
-rw-r--r--ports/nrf/supervisor/qspi_flash.c146
-rw-r--r--ports/nrf/supervisor/serial.c48
-rw-r--r--ports/nrf/supervisor/usb.c83
-rw-r--r--ports/nrf/tick.h2
-rw-r--r--ports/nrf/usb/usb_desc.c393
-rw-r--r--ports/nrf/usb/usb_desc.h87
-rw-r--r--py/py.mk4
-rw-r--r--shared-bindings/busio/SPI.h3
-rw-r--r--shared-bindings/usb_hid/Device.h2
-rw-r--r--shared-module/bitbangio/SPI.c3
-rw-r--r--shared-module/storage/__init__.c26
-rw-r--r--shared-module/usb_hid/Device.c (renamed from ports/nrf/common-hal/usb_hid/Device.c)2
-rw-r--r--shared-module/usb_hid/Device.h (renamed from ports/atmel-samd/common-hal/usb_hid/Device.h)28
-rw-r--r--shared-module/usb_hid/__init__.c (renamed from ports/nrf/common-hal/usb_hid/__init__.c)34
-rw-r--r--supervisor/flash.h (renamed from ports/atmel-samd/usb_mass_storage.h)42
-rw-r--r--supervisor/flash_root_pointers.h35
-rw-r--r--supervisor/port.h3
-rw-r--r--supervisor/serial.h10
-rw-r--r--supervisor/shared/external_flash/common_commands.h (renamed from ports/atmel-samd/external_flash/common_commands.h)1
-rw-r--r--supervisor/shared/external_flash/devices.h (renamed from ports/atmel-samd/external_flash/devices.h)68
-rw-r--r--supervisor/shared/external_flash/external_flash.c (renamed from ports/atmel-samd/external_flash/external_flash.c)104
-rw-r--r--supervisor/shared/external_flash/external_flash.h48
-rw-r--r--supervisor/shared/external_flash/external_flash_root_pointers.h35
-rw-r--r--supervisor/shared/external_flash/qspi_flash.c (renamed from ports/atmel-samd/common-hal/storage/__init__.c)50
-rw-r--r--supervisor/shared/external_flash/qspi_flash.h31
-rw-r--r--supervisor/shared/external_flash/spi_flash.c (renamed from ports/atmel-samd/external_flash/spi_flash.c)106
-rw-r--r--supervisor/shared/filesystem.c (renamed from ports/atmel-samd/supervisor/filesystem.c)28
-rw-r--r--supervisor/shared/flash.c123
-rw-r--r--supervisor/shared/micropython.c (renamed from ports/atmel-samd/flash_api.c)43
-rw-r--r--supervisor/shared/rgb_led_status.h2
-rw-r--r--supervisor/shared/serial.c (renamed from ports/nrf/common-hal/storage/__init__.c)41
-rw-r--r--supervisor/shared/status_leds.c62
-rw-r--r--supervisor/shared/status_leds.h (renamed from ports/atmel-samd/flash_api.h)16
-rw-r--r--supervisor/shared/usb/tusb_config.h (renamed from ports/nrf/usb/tusb_config.h)19
-rw-r--r--supervisor/shared/usb/usb.c (renamed from ports/nrf/usb/usb.c)103
-rw-r--r--supervisor/shared/usb/usb_desc.c46
-rw-r--r--supervisor/shared/usb/usb_desc.h (renamed from ports/nrf/usb/usb.h)21
-rw-r--r--supervisor/shared/usb/usb_msc_flash.c (renamed from ports/nrf/usb/usb_msc_flash.c)126
-rw-r--r--supervisor/spi_flash_api.h (renamed from ports/atmel-samd/external_flash/spi_flash_api.h)10
-rw-r--r--supervisor/supervisor.mk72
-rw-r--r--supervisor/usb.h (renamed from ports/atmel-samd/usb.h)26
-rw-r--r--tools/gen_usb_descriptor.py (renamed from ports/atmel-samd/tools/gen_usb_descriptor.py)275
-rw-r--r--tools/hid_report_descriptors.py (renamed from ports/atmel-samd/tools/hid_report_descriptors.py)0
m---------tools/usb_descriptor0
156 files changed, 2209 insertions, 3480 deletions
diff --git a/.gitmodules b/.gitmodules
index 38b6ea5df..1c1f8eb65 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -78,7 +78,7 @@
url = https://github.com/adafruit/nrfx.git
[submodule "lib/tinyusb"]
path = lib/tinyusb
- url = https://github.com/hathach/tinyusb.git
+ url = https://github.com/tannewt/tinyusb.git
branch = develop
[submodule "tools/huffman"]
path = tools/huffman
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject 33c61bfda2c3aada3cb06d36e12d7cf57da0203
+Subproject 299a2f12de2ddb76b9a488b23e7e562058faee9
diff --git a/main.c b/main.c
index c1379c571..ac55b72ba 100755
--- a/main.c
+++ b/main.c
@@ -51,6 +51,7 @@
#include "supervisor/shared/autoreload.h"
#include "supervisor/shared/translate.h"
#include "supervisor/shared/rgb_led_status.h"
+#include "supervisor/shared/status_leds.h"
#include "supervisor/shared/stack.h"
#include "supervisor/serial.h"
@@ -388,6 +389,8 @@ int __attribute__((used)) main(void) {
// initialise the cpu and peripherals
safe_mode_t safe_mode = port_init();
+ // Turn on LEDs
+ init_status_leds();
rgb_led_status_init();
stack_init();
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 7861f4235..552be92be 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -45,16 +45,13 @@ INC += -I. \
-Iasf4/$(CHIP_FAMILY)/hpl/tc \
-Iasf4/$(CHIP_FAMILY)/include \
-Iasf4/$(CHIP_FAMILY)/CMSIS/Include \
- -Iasf4/$(CHIP_FAMILY)/usb \
- -Iasf4/$(CHIP_FAMILY)/usb/class/cdc \
- -Iasf4/$(CHIP_FAMILY)/usb/class/hid \
- -Iasf4/$(CHIP_FAMILY)/usb/class/msc \
- -Iasf4/$(CHIP_FAMILY)/usb/device \
-Iasf4_conf/$(CHIP_FAMILY) \
-Iboards/$(BOARD) \
-Iboards/ \
-Iperipherals/ \
-Ifreetouch \
+ -I../../lib/tinyusb/src \
+ -I../../supervisor/shared/usb \
-I$(BUILD)
BASE_CFLAGS = \
@@ -90,11 +87,15 @@ BASE_CFLAGS = \
# NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt.
ifeq ($(CHIP_FAMILY), samd21)
-CFLAGS = -Os -DNDEBUG
+CFLAGS += -Os -DNDEBUG
+# TinyUSB defines
+CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512
endif
ifeq ($(CHIP_FAMILY), samd51)
-CFLAGS = -Os -DNDEBUG
+CFLAGS += -O0 -DNDEBUG
+# TinyUSB defines
+CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024
endif
#Debugging/Optimization
@@ -104,7 +105,7 @@ ifeq ($(DEBUG), 1)
# You may want to disable -flto if it interferes with debugging.
CFLAGS += -flto
# You may want to enable these flags to make setting breakpoints easier.
-## CFLAGS += -fno-inline -fno-ipa-sra
+ # CFLAGS += -fno-inline -fno-ipa-sra
ifeq ($(CHIP_FAMILY), samd21)
CFLAGS += -DENABLE_MICRO_TRACE_BUFFER
endif
@@ -204,7 +205,6 @@ SRC_ASF := \
hal/src/hal_spi_m_sync.c \
hal/src/hal_timer.c \
hal/src/hal_usart_async.c \
- hal/src/hal_usb_device.c \
hpl/adc/hpl_adc.c \
hpl/core/hpl_init.c \
hpl/dac/hpl_dac.c \
@@ -214,12 +214,6 @@ SRC_ASF := \
hpl/rtc/hpl_rtc.c \
hpl/sercom/hpl_sercom.c \
hpl/systick/hpl_systick.c \
- hpl/usb/hpl_usb.c \
- usb/class/cdc/device/cdcdf_acm.c \
- usb/class/hid/device/hiddf_generic.c \
- usb/class/msc/device/mscdf.c \
- usb/device/usbdc.c \
- usb/usb_protocol.c \
hal/utils/src/utils_list.c \
hal/utils/src/utils_ringbuffer.c \
@@ -246,7 +240,6 @@ SRC_C = \
board_busses.c \
background.c \
fatfs_port.c \
- flash_api.c \
mphalport.c \
reset.c \
peripherals/samd/clocks.c \
@@ -265,8 +258,6 @@ SRC_C = \
peripherals/samd/$(CHIP_FAMILY)/sercom.c \
peripherals/samd/$(CHIP_FAMILY)/timers.c \
tick.c \
- usb.c \
- usb_mass_storage.c \
bindings/samd/__init__.c \
bindings/samd/Clock.c \
boards/$(BOARD)/board.c \
@@ -274,6 +265,8 @@ SRC_C = \
lib/oofatfs/ff.c \
lib/oofatfs/option/ccsbcs.c \
lib/timeutils/timeutils.c \
+ lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd.c \
+ lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal.c \
lib/utils/buffer_helper.c \
lib/utils/context_manager_helpers.c \
lib/utils/interrupt_char.c \
@@ -282,7 +275,6 @@ SRC_C = \
lib/utils/sys_stdio_mphal.c \
lib/libc/string0.c \
lib/mp-readline/readline.c \
- $(BUILD)/autogen_usb_descriptor.c \
freetouch/adafruit_ptc.c \
supervisor/shared/memory.c
@@ -306,19 +298,6 @@ SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
endif # MICROPY_PY_WIZNET5K
endif # MICROPY_PY_NETWORK
-# Choose which flash filesystem impl to use.
-# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive.
-# But that might not be true in the future.)
-ifeq ($(INTERNAL_FLASH_FILESYSTEM),1)
-SRC_C += internal_flash.c
-endif
-ifeq ($(SPI_FLASH_FILESYSTEM),1)
-SRC_C += external_flash/external_flash.c external_flash/spi_flash.c
-endif
-ifeq ($(QSPI_FLASH_FILESYSTEM),1)
-SRC_C += external_flash/external_flash.c external_flash/qspi_flash.c
-endif
-
SRC_COMMON_HAL = \
board/__init__.c \
busio/__init__.c \
@@ -339,7 +318,6 @@ SRC_COMMON_HAL = \
rotaryio/IncrementalEncoder.c \
rtc/__init__.c \
rtc/RTC.c \
- storage/__init__.c \
supervisor/__init__.c \
supervisor/Runtime.c \
time/__init__.c \
@@ -352,10 +330,8 @@ SRC_COMMON_HAL = \
pulseio/PulseIn.c \
pulseio/PulseOut.c \
pulseio/PWMOut.c \
- usb_hid/__init__.c \
- usb_hid/Device.c \
touchio/__init__.c \
- touchio/TouchIn.c \
+ touchio/TouchIn.c
ifeq ($(INTERNAL_LIBM),1)
SRC_LIBM = $(addprefix lib/,\
@@ -412,12 +388,17 @@ SRC_SHARED_MODULE = \
_stage/__init__.c \
_stage/Layer.c \
_stage/Text.c \
+ storage/__init__.c \
os/__init__.c \
random/__init__.c \
- storage/__init__.c \
struct/__init__.c \
uheap/__init__.c \
- ustack/__init__.c
+ ustack/__init__.c \
+ usb_hid/__init__.c \
+ usb_hid/Device.c
+
+ # usb_midi/__init__.c
+ # usb_midi/Port.c
ifeq ($(MICROPY_PY_NETWORK),1)
SRC_SHARED_MODULE += socket/__init__.c network/__init__.c
@@ -489,21 +470,6 @@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin
$(STEPECHO) "Create $@"
$(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -c -o $@ $^
-$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: autogen_usb_descriptor.intermediate
-
-.INTERMEDIATE: autogen_usb_descriptor.intermediate
-
-autogen_usb_descriptor.intermediate: tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD)
- $(STEPECHO) "GEN $@"
- $(Q)install -d $(BUILD)/genhdr
- $(Q)$(PYTHON3) tools/gen_usb_descriptor.py \
- --manufacturer $(USB_MANUFACTURER)\
- --product $(USB_PRODUCT)\
- --vid $(USB_VID)\
- --pid $(USB_PID)\
- --output_c_file $(BUILD)/autogen_usb_descriptor.c\
- --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h
-
deploy: $(BUILD)/firmware.bin
$(ECHO) "Writing $< to the board"
$(BOSSAC) -u $<
diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c
index 3cf6831a3..099cb8b23 100644
--- a/ports/atmel-samd/background.c
+++ b/ports/atmel-samd/background.c
@@ -27,8 +27,7 @@
#include "audio_dma.h"
#include "tick.h"
-#include "usb.h"
-#include "usb_mass_storage.h"
+#include "supervisor/usb.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/network/__init__.h"
@@ -45,8 +44,8 @@ void run_background_tasks(void) {
#if MICROPY_PY_NETWORK
network_module_background();
#endif
- usb_msc_background();
- usb_cdc_background();
+ usb_background();
+
last_finished_tick = ticks_ms;
}
diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h
index ad9dc43b4..1e8d926fd 100644
--- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h
+++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h
@@ -1,12 +1,10 @@
#define MICROPY_HW_BOARD_NAME "Arduino MKR1300"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/arduino_zero/board.c b/ports/atmel-samd/boards/arduino_zero/board.c
index 2dc1683ea..770bc8259 100644
--- a/ports/atmel-samd/boards/arduino_zero/board.c
+++ b/ports/atmel-samd/boards/arduino_zero/board.c
@@ -30,13 +30,6 @@
void board_init(void)
{
- gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_TX, true);
-
- gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_RX, true);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h
index 1382d4736..9a6256c68 100644
--- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h
+++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h
@@ -1,16 +1,14 @@
#define MICROPY_HW_BOARD_NAME "Arduino Zero"
#define MICROPY_HW_MCU_NAME "samd21g18"
-// #define MICROPY_HW_LED_MSC PIN_PA17 // red
-#define MICROPY_HW_LED_TX PIN_PA27
-#define MICROPY_HW_LED_RX PIN_PB03
+// #define MICROPY_HW_LED_MSC &pin_PA17 // red
+#define MICROPY_HW_LED_TX &pin_PA27
+#define MICROPY_HW_LED_RX &pin_PB03
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA27)
+#define MICROPY_PORT_A (PORT_PA27)
#define MICROPY_PORT_B (PORT_PB03)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
index 5077840cb..2ad13e81c 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
@@ -8,52 +8,24 @@
#define SPI_FLASH_BAUDRATE (8000000)
// On-board flash
-#define SPI_FLASH_MOSI_PIN PIN_PA20
-#define SPI_FLASH_MISO_PIN PIN_PA16
-#define SPI_FLASH_SCK_PIN PIN_PA21
-#define SPI_FLASH_CS_PIN PIN_PB22
-
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA20D_SERCOM3_PAD2
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA21D_SERCOM3_PAD3
-#define SPI_FLASH_SERCOM SERCOM3
-#define SPI_FLASH_SERCOM_INDEX 3
-#define SPI_FLASH_MOSI_PAD 2
-#define SPI_FLASH_MISO_PAD 0
-#define SPI_FLASH_SCK_PAD 3
-
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 1
-#define SPI_FLASH_DIPO 0 // same as MISO PAD
+#define SPI_FLASH_MOSI_PIN &pin_PA20
+#define SPI_FLASH_MISO_PIN &pin_PA16
+#define SPI_FLASH_SCK_PIN &pin_PA21
+#define SPI_FLASH_CS_PIN &pin_PB22
// These are pins not to reset.
-// PA24 and PA25 are USB.
-#define MICROPY_PORT_A (PORT_PA16 | PORT_PA20 | PORT_PA21 | PORT_PA24 | PORT_PA25)
-#define MICROPY_PORT_B (PORT_PB22)
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
#define SPEAKER_ENABLE_PIN (&pin_PA30)
-#include "external_flash/devices.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define CALIBRATE_CRYSTALLESS 1
// Explanation of how a user got into safe mode.
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
index 831106adc..e5665afb6 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "CircuitPlayground Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h
index 638a6646c..250300858 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h
@@ -11,52 +11,24 @@
#define SPI_FLASH_BAUDRATE (8000000)
// On-board flash
-#define SPI_FLASH_MOSI_PIN PIN_PA20
-#define SPI_FLASH_MISO_PIN PIN_PA16
-#define SPI_FLASH_SCK_PIN PIN_PA21
-#define SPI_FLASH_CS_PIN PIN_PB22
-
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA20D_SERCOM3_PAD2
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA21D_SERCOM3_PAD3
-#define SPI_FLASH_SERCOM SERCOM3
-#define SPI_FLASH_SERCOM_INDEX 3
-#define SPI_FLASH_MOSI_PAD 2
-#define SPI_FLASH_MISO_PAD 0
-#define SPI_FLASH_SCK_PAD 3
-
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 1
-#define SPI_FLASH_DIPO 0 // same as MISO PAD
+#define SPI_FLASH_MOSI_PIN &pin_PA20
+#define SPI_FLASH_MISO_PIN &pin_PA16
+#define SPI_FLASH_SCK_PIN &pin_PA21
+#define SPI_FLASH_CS_PIN &pin_PB22
// These are pins not to reset.
-// PA24 and PA25 are USB.
-#define MICROPY_PORT_A (PORT_PA16 | PORT_PA20 | PORT_PA21 | PORT_PA24 | PORT_PA25)
-#define MICROPY_PORT_B (PORT_PB22)
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
#define SPEAKER_ENABLE_PIN (&pin_PA30)
-#include "external_flash/devices.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define CALIBRATE_CRYSTALLESS 1
// Explanation of how a user got into safe mode.
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
index 972c4b10d..b07d63984 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "CircuitPlayground Express with Crickit libraries"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
# Turn off longints for Crickit build to make room for additional frozen libs.
LONGINT_IMPL = NONE
diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h
index c8b5c56ee..c28c4aafb 100644
--- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h
@@ -3,12 +3,10 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Adalogger"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h
index dcac9749d..d66efb36f 100644
--- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h
@@ -4,12 +4,10 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Basic"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
index 03d0ba9bd..1f02ee995 100644
--- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
@@ -3,35 +3,16 @@
#define MICROPY_HW_NEOPIXEL (&pin_PA06)
-// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PA08
-#define SPI_FLASH_MISO_PIN PIN_PA14
-#define SPI_FLASH_SCK_PIN PIN_PA09
-#define SPI_FLASH_CS_PIN PIN_PA13
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1
-#define SPI_FLASH_SERCOM SERCOM2
-#define SPI_FLASH_SERCOM_INDEX 2
-#define SPI_FLASH_MOSI_PAD 0
-#define SPI_FLASH_MISO_PAD 2
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0
-#define SPI_FLASH_DIPO 2 // same as MISO pad
+#define SPI_FLASH_MOSI_PIN &pin_PA08
+#define SPI_FLASH_MISO_PIN &pin_PA14
+#define SPI_FLASH_SCK_PIN &pin_PA09
+#define SPI_FLASH_CS_PIN &pin_PA13
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (PORT_PA06)
#define MICROPY_PORT_B ( 0 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -39,14 +20,6 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
index e9f9b09fb..57ce96285 100644
--- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "Feather M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h
index 756462013..b5544e253 100644
--- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h
@@ -3,50 +3,22 @@
#define MICROPY_HW_NEOPIXEL (&pin_PA06)
-// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PA08
-#define SPI_FLASH_MISO_PIN PIN_PA14
-#define SPI_FLASH_SCK_PIN PIN_PA09
-#define SPI_FLASH_CS_PIN PIN_PA13
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1
-#define SPI_FLASH_SERCOM SERCOM2
-#define SPI_FLASH_SERCOM_INDEX 2
-#define SPI_FLASH_MOSI_PAD 0
-#define SPI_FLASH_MISO_PAD 2
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0
-#define SPI_FLASH_DIPO 2 // same as MISO pad
+#define SPI_FLASH_MOSI_PIN &pin_PA08
+#define SPI_FLASH_MISO_PIN &pin_PA14
+#define SPI_FLASH_SCK_PIN &pin_PA09
+#define SPI_FLASH_CS_PIN &pin_PA13
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (PORT_PA06)
#define MICROPY_PORT_B ( 0 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash/external_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
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 7ff5337a3..f773bcb57 100644
--- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "Feather M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h
index 4a530ed29..c385a97ea 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h
@@ -4,12 +4,10 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 RFM69"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h
index 3a6f28c12..1e3a0bda0 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h
@@ -4,12 +4,10 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 RFM9x"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h
index a7a2d7de0..6bf1df156 100644
--- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h
@@ -5,49 +5,22 @@
#define MICROPY_HW_NEOPIXEL (&pin_PA06)
-// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PA08
-#define SPI_FLASH_MISO_PIN PIN_PA14
-#define SPI_FLASH_SCK_PIN PIN_PA09
-#define SPI_FLASH_CS_PIN PIN_PA13
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1
-#define SPI_FLASH_SERCOM SERCOM2
-#define SPI_FLASH_SERCOM_INDEX 2
-#define SPI_FLASH_MOSI_PAD 0
-#define SPI_FLASH_MISO_PAD 2
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0
-#define SPI_FLASH_DIPO 2 // same as MISO pad
+#define SPI_FLASH_MOSI_PIN &pin_PA08
+#define SPI_FLASH_MISO_PIN &pin_PA14
+#define SPI_FLASH_SCK_PIN &pin_PA09
+#define SPI_FLASH_CS_PIN &pin_PA13
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (PORT_PA06)
#define MICROPY_PORT_B ( 0 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash/external_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES S25FL064L
-
-#include "external_flash/external_flash.h"
-
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
index 79bf2d34a..4bae6ffa7 100644
--- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "Feather M0 Supersized"
USB_MANUFACTURER = "Dave Astels"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "S25FL064L"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
index e9e921b4d..98906a844 100644
--- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h
@@ -23,15 +23,8 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES GD25Q16C
-
#define EXTERNAL_FLASH_QSPI_DUAL
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
index bbc5985a9..3f2cb6ce4 100644
--- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
@@ -5,6 +5,9 @@ USB_PRODUCT = "Feather M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
QSPI_FLASH_FILESYSTEM = 1
+
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD51J19A
diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h
index 32c549953..c4e025178 100755
--- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h
@@ -3,50 +3,22 @@
#define MICROPY_HW_NEOPIXEL (&pin_PA22)
-// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PA31
-#define SPI_FLASH_MISO_PIN PIN_PA30
-#define SPI_FLASH_SCK_PIN PIN_PA17
-#define SPI_FLASH_CS_PIN PIN_PA28
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA31D_SERCOM1_PAD3
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA30D_SERCOM1_PAD2
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA17C_SERCOM1_PAD1
-#define SPI_FLASH_SERCOM SERCOM1
-#define SPI_FLASH_SERCOM_INDEX 1
-#define SPI_FLASH_MOSI_PAD 3
-#define SPI_FLASH_MISO_PAD 2
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 2
-#define SPI_FLASH_DIPO 2 // same as MISO pad
+#define SPI_FLASH_MOSI_PIN &pin_PA31
+#define SPI_FLASH_MISO_PIN &pin_PA30
+#define SPI_FLASH_SCK_PIN &pin_PA17
+#define SPI_FLASH_CS_PIN &pin_PA28
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA17 | PORT_PA22 | PORT_PA24 | PORT_PA25 | PORT_PA28 | PORT_PA30 | PORT_PA31)
+#define MICROPY_PORT_A (PORT_PA22)
#define MICROPY_PORT_B ( 0 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash/external_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk
index 42177d274..634a9ede7 100755
--- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "Feather RadioFruit Zigbee"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMR21G18A
diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h
index 1ec217096..08d1803f2 100644
--- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h
+++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h
@@ -18,8 +18,6 @@
#define DEFAULT_UART_BUS_RX (&pin_PA05)
#define DEFAULT_UART_BUS_TX (&pin_PA04)
-#include "internal_flash.h"
-
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
#define IGNORE_PIN_PA03 1
diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/board.c b/ports/atmel-samd/boards/grandcentral_m4_express/board.c
index 360b5d8f9..7599f02b8 100644
--- a/ports/atmel-samd/boards/grandcentral_m4_express/board.c
+++ b/ports/atmel-samd/boards/grandcentral_m4_express/board.c
@@ -29,13 +29,6 @@
#include "hal/include/hal_gpio.h"
void board_init(void) {
- gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_TX, true);
-
- gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_RX, true);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h
index 231bf20e0..0d2d65ba5 100644
--- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h
@@ -5,8 +5,8 @@
// This is for Rev A which is green
-#define MICROPY_HW_LED_TX PIN_PC30
-#define MICROPY_HW_LED_RX PIN_PC31
+#define MICROPY_HW_LED_TX &(pin_PC30)
+#define MICROPY_HW_LED_RX &(pin_PC31)
#define MICROPY_HW_NEOPIXEL (&pin_PC24)
@@ -27,13 +27,6 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES GD25Q64C
-
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PB21)
diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
index 3e8717ecf..2605c9f55 100644
--- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
@@ -5,6 +5,9 @@ USB_PRODUCT = "Grand Central M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
QSPI_FLASH_FILESYSTEM = 1
+
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q64C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD51P20A
diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h
index 8450882b9..5869c01ff 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h
@@ -3,51 +3,24 @@
#define MICROPY_HW_NEOPIXEL (&pin_PA12)
-// Clock rates are off: Saleae reads 12MHz which is the limit even though we set it to the safer 8MHz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PB10
-#define SPI_FLASH_MISO_PIN PIN_PA13
-#define SPI_FLASH_SCK_PIN PIN_PB11
-#define SPI_FLASH_CS_PIN PIN_PA07
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB10D_SERCOM4_PAD2
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA13D_SERCOM4_PAD1
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB11D_SERCOM4_PAD3
-#define SPI_FLASH_SERCOM SERCOM4
-#define SPI_FLASH_SERCOM_INDEX 4
-#define SPI_FLASH_MOSI_PAD 2
-#define SPI_FLASH_MISO_PAD 1
-#define SPI_FLASH_SCK_PAD 3
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0x1
-#define SPI_FLASH_DIPO 1 // same as MISO pad
+#define SPI_FLASH_MOSI_PIN &pin_PB10
+#define SPI_FLASH_MISO_PIN &pin_PA13
+#define SPI_FLASH_SCK_PIN &pin_PB11
+#define SPI_FLASH_CS_PIN &pin_PA07
// These are pins not to reset.
-#define MICROPY_PORT_A ( PORT_PA01 | PORT_PA07 | PORT_PA12 | PORT_PA13 | PORT_PA24 | PORT_PA25 | PORT_PA27 | PORT_PA28)
-#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 | PORT_PB23 )
+// NeoPixel and for the display: Reset, Command or data, and Chip select
+#define MICROPY_PORT_A ( PORT_PA01 | PORT_PA12 | PORT_PA27 | PORT_PA28)
+// Data and Clock for the display
+#define MICROPY_PORT_B ( PORT_PB22 | PORT_PB23 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash/external_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-
-#define EXTERNAL_FLASH_DEVICES W25Q64JV_IQ, \
- GD25Q64C
-
-#include "external_flash/external_flash.h"
-
#define DEFAULT_I2C_BUS_SCL (&pin_PA17)
#define DEFAULT_I2C_BUS_SDA (&pin_PA16)
diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
index 817d93943..37f1bdef0 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "HalloWing M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h
index f56f57c46..4de28d388 100644
--- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h
@@ -5,32 +5,14 @@
#define MICROPY_HW_APA102_MOSI (&pin_PA01)
#define MICROPY_HW_APA102_SCK (&pin_PA00)
-// Saleae reads 12mhz which is the limit even though we set it to the safer 8mhz.
-#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
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB22D_SERCOM5_PAD2
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PB03D_SERCOM5_PAD1
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB23D_SERCOM5_PAD3
-#define SPI_FLASH_SERCOM SERCOM5
-#define SPI_FLASH_SERCOM_INDEX 5
-#define SPI_FLASH_MOSI_PAD 2
-#define SPI_FLASH_MISO_PAD 1
-#define SPI_FLASH_SCK_PAD 3
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 1
-#define SPI_FLASH_DIPO 1 // same as MISO pad
+#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_PA00 | PORT_PA01 | PORT_PA27 | PORT_PA24 | PORT_PA25)
-#define MICROPY_PORT_B (PORT_PB22 | PORT_PB23 | PORT_PB03 )
+#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01)
+#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
// If you change this, then make sure to update the linker scripts as well to
@@ -39,14 +21,6 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES W25Q16FW, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk
index 9f62ae839..8fcf5208f 100644
--- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "ItsyBitsy M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C"
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h
index e47d5390d..5bbfec9ce 100644
--- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h
@@ -25,13 +25,6 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
index 27f5ea2b8..2afff5965 100644
--- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "ItsyBitsy M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD51G19A
diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h
index 3ce00b04f..f07eb9cce 100644
--- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h
+++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h
@@ -1,15 +1,11 @@
#define MICROPY_HW_BOARD_NAME "Meow Meow"
#define MICROPY_HW_MCU_NAME "samd21g18"
-
// These are pins not to reset.
-// PA24 and PA25 are USB.
-#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
index 40ef3ce78..f08d129dc 100644
--- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
@@ -1,37 +1,23 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Metro M0 Express"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_HW_LED_TX PIN_PA27
-//#define MICROPY_HW_LED_RX PIN_PA31
+#define MICROPY_HW_LED_TX &pin_PA27
+// Comment this out if you have trouble connecting over SWD. It's one of the SWD pins.
+#define MICROPY_HW_LED_RX &pin_PA31
#define MICROPY_HW_NEOPIXEL (&pin_PA30)
// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz.
#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_PA13
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB22D_SERCOM5_PAD2
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PB03D_SERCOM5_PAD1
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB23D_SERCOM5_PAD3
-#define SPI_FLASH_SERCOM SERCOM5
-#define SPI_FLASH_SERCOM_INDEX 5
-#define SPI_FLASH_MOSI_PAD 2
-#define SPI_FLASH_MISO_PAD 1
-#define SPI_FLASH_SCK_PAD 3
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 1
-#define SPI_FLASH_DIPO 1 // same as MISO pad
+#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_PA13
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA13 |PORT_PA24 | PORT_PA25 | PORT_PA27 | PORT_PA30 | PORT_PA31)
-#define MICROPY_PORT_B (PORT_PB03 | PORT_PB22 | PORT_PB23)
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
// If you change this, then make sure to update the linker scripts as well to
@@ -40,14 +26,6 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
index 40a0092ac..49a94144b 100644
--- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
@@ -12,3 +12,7 @@ CHIP_FAMILY = samd21
MICROPY_PY_NETWORK = 1
MICROPY_PY_WIZNET5K = 5500
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
diff --git a/ports/atmel-samd/boards/metro_m4_express/board.c b/ports/atmel-samd/boards/metro_m4_express/board.c
index a98385d29..0f60736a2 100644
--- a/ports/atmel-samd/boards/metro_m4_express/board.c
+++ b/ports/atmel-samd/boards/metro_m4_express/board.c
@@ -29,13 +29,6 @@
#include "hal/include/hal_gpio.h"
void board_init(void) {
- gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_TX, true);
-
- gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_RX, true);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
index f1201c8a0..06feb1a22 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
@@ -5,16 +5,16 @@
// This is for Rev F which is green
-#define MICROPY_HW_LED_TX PIN_PA27
-#define MICROPY_HW_LED_RX PIN_PB06
+#define MICROPY_HW_LED_TX (&pin_PA27)
+#define MICROPY_HW_LED_RX (&pin_PB06)
#define MICROPY_HW_NEOPIXEL (&pin_PB22)
// These are pins not to reset.
-// QSPI Data pins and TX LED
-#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 | PORT_PA27)
-// RX LED, QSPI CS, QSPI SCK and NeoPixel pin
-#define MICROPY_PORT_B ( PORT_PB06 | PORT_PB10 | PORT_PB11 | PORT_PB22)
+// 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_PB10 | PORT_PB11 | PORT_PB22)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
@@ -26,13 +26,6 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 3
-#define EXTERNAL_FLASH_DEVICES S25FL116K, S25FL216K, GD25Q16C
-
-#include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 1
#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
index cbc89159f..633856362 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
@@ -5,6 +5,9 @@ USB_PRODUCT = "Metro M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 3
+EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
+
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD51J19A
diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h
index 15979ae77..cbbd4b569 100644
--- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h
+++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h
@@ -15,8 +15,6 @@
// A number of modules are removed for pIRKey to make room for frozen libraries.
#define PIRKEY_M0 (1)
-#include "internal_flash.h"
-
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
#define IGNORE_PIN_PA02 1
diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h
index 1464d100c..6870b86ba 100644
--- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h
@@ -26,13 +26,6 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES GD25Q64C
-
-#include "external_flash/external_flash.h"
-
#define DEFAULT_I2C_BUS_SCL (&pin_PB08)
#define DEFAULT_I2C_BUS_SDA (&pin_PB09)
diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
index 3841a87c7..7094b79be 100644
--- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT = "Trellis M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = GD25Q64C
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD51G19A
diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h
index 9036f8e7b..c311f540c 100644
--- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h
+++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h
@@ -5,12 +5,10 @@
#define MICROPY_HW_APA102_MOSI (&pin_PA00)
#define MICROPY_HW_APA102_SCK (&pin_PA01)
-#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
-#include "internal_flash.h"
-
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000)
diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h
index 8e3fdd7a8..dfbd873b6 100644
--- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h
+++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h
@@ -5,56 +5,24 @@
// #define MICROPY_HW_APA102_MOSI (&pin_PA00)
// #define MICROPY_HW_APA102_SCK (&pin_PA01)
-// Salae reads 12mhz which is the limit even though we set it to the
-// safer 8mhz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PA16
-#define SPI_FLASH_MISO_PIN PIN_PA19
-#define SPI_FLASH_SCK_PIN PIN_PA17
-#define SPI_FLASH_CS_PIN PIN_PA11
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA19D_SERCOM3_PAD3
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA17D_SERCOM3_PAD1
-#define SPI_FLASH_SERCOM SERCOM3
-#define SPI_FLASH_SERCOM_INDEX 3
-#define SPI_FLASH_MOSI_PAD 0
-#define SPI_FLASH_MISO_PAD 3
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0
-#define SPI_FLASH_DIPO 3 // same as MISO pad
-
-#define SPI_FLASH_CS PIN_PA11
+#define SPI_FLASH_MOSI_PIN &pin_PA16
+#define SPI_FLASH_MISO_PIN &pin_PA19
+#define SPI_FLASH_SCK_PIN &pin_PA17
+#define SPI_FLASH_CS_PIN &pin_PA11
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA11 | PORT_PA16 |\
- PORT_PA17 | PORT_PA18 | PORT_PA19 | PORT_PA24 |\
- PORT_PA25)
+#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA18)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
#define CALIBRATE_CRYSTALLESS 1
-#include "external_flash/external_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES W25Q32BV
-
-#include "external_flash/external_flash.h"
-
#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk
index d97aa08ab..c9c196da7 100644
--- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk
@@ -5,6 +5,8 @@ USB_PRODUCT="Trinket M0 Haxpress"
USB_MANUFACTURER="Radomir Dopieralski"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = W25Q32BV
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21E18A
diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.h b/ports/atmel-samd/boards/ugame10/mpconfigboard.h
index ed822952d..c22a3f735 100644
--- a/ports/atmel-samd/boards/ugame10/mpconfigboard.h
+++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.h
@@ -1,53 +1,24 @@
#define MICROPY_HW_BOARD_NAME "uGame10"
#define MICROPY_HW_MCU_NAME "samd21e18"
-// Salae reads 12mhz which is the limit even though we set it to the
-// safer 8mhz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-#define SPI_FLASH_MOSI_PIN PIN_PA16
-#define SPI_FLASH_MISO_PIN PIN_PA19
-#define SPI_FLASH_SCK_PIN PIN_PA17
-#define SPI_FLASH_CS_PIN PIN_PA18
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA19D_SERCOM3_PAD3
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA17D_SERCOM3_PAD1
-#define SPI_FLASH_SERCOM SERCOM3
-#define SPI_FLASH_SERCOM_INDEX 3
-#define SPI_FLASH_MOSI_PAD 0
-#define SPI_FLASH_MISO_PAD 3
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0
-#define SPI_FLASH_DIPO 3 // same as MISO pad
+#define SPI_FLASH_MOSI_PIN &pin_PA16
+#define SPI_FLASH_MISO_PIN &pin_PA19
+#define SPI_FLASH_SCK_PIN &pin_PA17
+#define SPI_FLASH_CS_PIN &pin_PA18
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA16 | PORT_PA17 | PORT_PA18 | PORT_PA19 |\
- PORT_PA24 | PORT_PA25)
+#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
#define CALIBRATE_CRYSTALLESS 1
-#include "external_flash/external_flash.h"
-
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES S25FL216K
-
-#include "external_flash/external_flash.h"
-
#define EXTRA_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \
diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
index 2386531f9..6dc0af9cf 100644
--- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
@@ -6,6 +6,8 @@ USB_PRODUCT = "uGame10"
USB_MANUFACTURER = "Radomir Dopieralski"
SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = S25FL216K
LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21E18A
diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c
index a292f9e3d..4de34c975 100644
--- a/ports/atmel-samd/common-hal/busio/SPI.c
+++ b/ports/atmel-samd/common-hal/busio/SPI.c
@@ -31,6 +31,8 @@
#include "hpl_sercom_config.h"
#include "peripheral_clk_config.h"
+#include "boards/board.h"
+#include "common-hal/microcontroller/Pin.h"
#include "hal/include/hal_gpio.h"
#include "hal/include/hal_spi_m_sync.h"
#include "hal/include/hpl_spi_m_sync.h"
@@ -39,6 +41,43 @@
#include "samd/dma.h"
#include "samd/sercom.h"
+bool never_reset_sercoms[SERCOM_INST_NUM];
+
+void never_reset_sercom(Sercom* sercom) {
+ // Reset all SERCOMs except the ones being used by on-board devices.
+ Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
+ for (int i = 0; i < SERCOM_INST_NUM; i++) {
+ if (sercom_instances[i] == sercom) {
+ never_reset_sercoms[i] = true;
+ break;
+ }
+ }
+}
+
+void reset_sercoms(void) {
+ // Reset all SERCOMs except the ones being used by on-board devices.
+ Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
+ for (int i = 0; i < SERCOM_INST_NUM; i++) {
+ if (never_reset_sercoms[i]) {
+ continue;
+ }
+ #ifdef MICROPY_HW_APA102_SERCOM
+ if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) {
+ continue;
+ }
+ #endif
+ #ifdef CIRCUITPY_DISPLAYIO
+ // TODO(tannewt): Make this dynamic.
+ if (sercom_instances[i] == board_display_obj.bus.spi_desc.dev.prvt) {
+ continue;
+ }
+ #endif
+ // SWRST is same for all modes of SERCOMs.
+ sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1;
+ }
+}
+
+
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
const mcu_pin_obj_t * miso) {
@@ -186,6 +225,14 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
spi_m_sync_enable(&self->spi_desc);
}
+void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
+ never_reset_sercom(self->spi_desc.dev.prvt);
+
+ never_reset_pin_number(self->clock_pin);
+ never_reset_pin_number(self->MOSI_pin);
+ never_reset_pin_number(self->MISO_pin);
+}
+
bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
return self->clock_pin == NO_PIN;
}
diff --git a/ports/atmel-samd/common-hal/busio/SPI.h b/ports/atmel-samd/common-hal/busio/SPI.h
index 2fced6d64..56d163a9d 100644
--- a/ports/atmel-samd/common-hal/busio/SPI.h
+++ b/ports/atmel-samd/common-hal/busio/SPI.h
@@ -42,4 +42,7 @@ typedef struct {
uint8_t MISO_pin;
} busio_spi_obj_t;
+void reset_sercoms(void);
+
+
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c
index 0f179a6c1..7dd9c6b09 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.c
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c
@@ -43,15 +43,19 @@ bool apa102_mosi_in_use;
bool speaker_enable_in_use;
#endif
+#define PORT_COUNT (PORT_BITS / 32 + 1)
+
+STATIC uint32_t never_reset_pins[PORT_COUNT];
+
void reset_all_pins(void) {
- uint32_t pin_mask[PORT_BITS / 32 + 1] = PORT_OUT_IMPLEMENTED;
+ uint32_t pin_mask[PORT_COUNT] = PORT_OUT_IMPLEMENTED;
// Do not full reset USB or SWD lines.
pin_mask[0] &= ~(PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31);
- #ifdef SAMD21
- pin_mask[0] &= ~(PORT_PA31);
- #endif
+ for (uint32_t i = 0; i < PORT_COUNT; i++) {
+ pin_mask[i] &= ~never_reset_pins[i];
+ }
gpio_set_port_direction(GPIO_PORTA, pin_mask[0] & ~MICROPY_PORT_A, GPIO_DIRECTION_OFF);
gpio_set_port_direction(GPIO_PORTB, pin_mask[1] & ~MICROPY_PORT_B, GPIO_DIRECTION_OFF);
@@ -91,6 +95,10 @@ void reset_all_pins(void) {
#endif
}
+void never_reset_pin_number(uint8_t pin_number) {
+ never_reset_pins[GPIO_PORT(pin_number)] |= 1 << GPIO_PIN(pin_number);
+}
+
void reset_pin_number(uint8_t pin_number) {
if (pin_number >= PORT_BITS) {
return;
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h
index dcd80997e..f798ea300 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.h
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h
@@ -43,6 +43,7 @@ void reset_all_pins(void);
// reset_pin_number takes the pin number instead of the pointer so that objects don't
// need to store a full pointer.
void reset_pin_number(uint8_t pin_number);
+void never_reset_pin_number(uint8_t pin_number);
void claim_pin(const mcu_pin_obj_t* pin);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H
diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c
index 746207787..0ca3a0835 100644
--- a/ports/atmel-samd/common-hal/microcontroller/__init__.c
+++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c
@@ -107,7 +107,6 @@ const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
// This maps MCU pin names to pin objects.
STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
-// Pins in datasheet order.
#if defined(PIN_PA00) && !defined(IGNORE_PIN_PA00)
{ MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) },
#endif
@@ -120,24 +119,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
#if defined(PIN_PA03) && !defined(IGNORE_PIN_PA03)
{ MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) },
#endif
-#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04)
- { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) },
-#endif
-#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05)
- { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) },
-#endif
-#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06)
- { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) },
-#endif
-#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07)
- { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) },
-#endif
-#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08)
- { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) },
-#endif
-#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09)
- { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) },
-#endif
#if defined(PIN_PA04) && !defined(IGNORE_PIN_PA04)
{ MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) },
#endif
@@ -162,26 +143,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
#if defined(PIN_PA11) && !defined(IGNORE_PIN_PA11)
{ MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) },
#endif
-#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10)
- { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
-#endif
-#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11)
- { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) },
-#endif
-#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12)
- { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
-#endif
-#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13)
- { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) },
-#endif
-#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14)
- { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) },
-#endif
-
-// Second page.
-#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15)
- { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) },
-#endif
#if defined(PIN_PA12) && !defined(IGNORE_PIN_PA12)
{ MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) },
#endif
@@ -206,12 +167,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
#if defined(PIN_PA19) && !defined(IGNORE_PIN_PA19)
{ MP_ROM_QSTR(MP_QSTR_PA19), MP_ROM_PTR(&pin_PA19) },
#endif
-#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16)
- { MP_ROM_QSTR(MP_QSTR_PB16), MP_ROM_PTR(&pin_PB16) },
-#endif
-#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17)
- { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) },
-#endif
#if defined(PIN_PA20) && !defined(IGNORE_PIN_PA20)
{ MP_ROM_QSTR(MP_QSTR_PA20), MP_ROM_PTR(&pin_PA20) },
#endif
@@ -230,12 +185,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
#if defined(PIN_PA25) && !defined(IGNORE_PIN_PA25)
{ MP_ROM_QSTR(MP_QSTR_PA25), MP_ROM_PTR(&pin_PA25) },
#endif
-#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22)
- { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) },
-#endif
-#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23)
- { MP_ROM_QSTR(MP_QSTR_PB23), MP_ROM_PTR(&pin_PB23) },
-#endif
#if defined(PIN_PA27) && !defined(IGNORE_PIN_PA27)
{ MP_ROM_QSTR(MP_QSTR_PA27), MP_ROM_PTR(&pin_PA27) },
#endif
@@ -248,12 +197,7 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
#if defined(PIN_PA31) && !defined(IGNORE_PIN_PA31)
{ MP_ROM_QSTR(MP_QSTR_PA31), MP_ROM_PTR(&pin_PA31) },
#endif
-#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30)
- { MP_ROM_QSTR(MP_QSTR_PB30), MP_ROM_PTR(&pin_PB30) },
-#endif
-#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31)
- { MP_ROM_QSTR(MP_QSTR_PB31), MP_ROM_PTR(&pin_PB31) },
-#endif
+
#if defined(PIN_PB00) && !defined(IGNORE_PIN_PB00)
{ MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) },
#endif
@@ -266,14 +210,176 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
#if defined(PIN_PB03) && !defined(IGNORE_PIN_PB03)
{ MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) },
#endif
+#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04)
+ { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) },
+#endif
+#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05)
+ { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) },
+#endif
+#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06)
+ { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) },
+#endif
+#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07)
+ { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) },
+#endif
+#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08)
+ { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) },
+#endif
+#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09)
+ { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) },
+#endif
+#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10)
+ { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
+#endif
+#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11)
+ { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) },
+#endif
+#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12)
+ { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
+#endif
+#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13)
+ { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) },
+#endif
+#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14)
+ { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) },
+#endif
+#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15)
+ { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) },
+#endif
+#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16)
+ { MP_ROM_QSTR(MP_QSTR_PB16), MP_ROM_PTR(&pin_PB16) },
+#endif
+#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17)
+ { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) },
+#endif
+#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22)
+ { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) },
+#endif
+#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23)
+ { MP_ROM_QSTR(MP_QSTR_PB23), MP_ROM_PTR(&pin_PB23) },
+#endif
+#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30)
+ { MP_ROM_QSTR(MP_QSTR_PB30), MP_ROM_PTR(&pin_PB30) },
+#endif
+#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31)
+ { MP_ROM_QSTR(MP_QSTR_PB31), MP_ROM_PTR(&pin_PB31) },
+#endif
+
+// These are SAMD51 specific so we assume we want them in RAM
+#if defined(PIN_PC00)
+ { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) },
+#endif
+#if defined(PIN_PC01)
+ { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) },
+#endif
+#if defined(PIN_PC02)
+ { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) },
+#endif
+#if defined(PIN_PC03)
+ { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) },
+#endif
+#if defined(PIN_PC04)
+ { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) },
+#endif
+#if defined(PIN_PC05)
+ { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) },
+#endif
+#if defined(PIN_PC06)
+ { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) },
+#endif
+#if defined(PIN_PC07)
+ { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) },
+#endif
+#if defined(PIN_PC10)
+ { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) },
+#endif
+#if defined(PIN_PC11)
+ { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) },
+#endif
+#if defined(PIN_PC12)
+ { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) },
+#endif
+#if defined(PIN_PC13)
+ { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) },
+#endif
+#if defined(PIN_PC14)
+ { MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14) },
+#endif
+#if defined(PIN_PC15)
+ { MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15) },
+#endif
#if defined(PIN_PC16)
{ MP_ROM_QSTR(MP_QSTR_PC16), MP_ROM_PTR(&pin_PC16) },
#endif
+#if defined(PIN_PC17)
+ { MP_ROM_QSTR(MP_QSTR_PC17), MP_ROM_PTR(&pin_PC17) },
+#endif
#if defined(PIN_PC18)
{ MP_ROM_QSTR(MP_QSTR_PC18), MP_ROM_PTR(&pin_PC18) },
#endif
#if defined(PIN_PC19)
{ MP_ROM_QSTR(MP_QSTR_PC19), MP_ROM_PTR(&pin_PC19) },
#endif
+#if defined(PIN_PC20)
+ { MP_ROM_QSTR(MP_QSTR_PC20), MP_ROM_PTR(&pin_PC20) },
+#endif
+#if defined(PIN_PC21)
+ { MP_ROM_QSTR(MP_QSTR_PC21), MP_ROM_PTR(&pin_PC21) },
+#endif
+#if defined(PIN_PC22)
+ { MP_ROM_QSTR(MP_QSTR_PC22), MP_ROM_PTR(&pin_PC22) },
+#endif
+#if defined(PIN_PC23)
+ { MP_ROM_QSTR(MP_QSTR_PC23), MP_ROM_PTR(&pin_PC23) },
+#endif
+#if defined(PIN_PC24)
+ { MP_ROM_QSTR(MP_QSTR_PC24), MP_ROM_PTR(&pin_PC24) },
+#endif
+#if defined(PIN_PC25)
+ { MP_ROM_QSTR(MP_QSTR_PC25), MP_ROM_PTR(&pin_PC25) },
+#endif
+#if defined(PIN_PC26)
+ { MP_ROM_QSTR(MP_QSTR_PC26), MP_ROM_PTR(&pin_PC26) },
+#endif
+#if defined(PIN_PC27)
+ { MP_ROM_QSTR(MP_QSTR_PC27), MP_ROM_PTR(&pin_PC27) },
+#endif
+#if defined(PIN_PC28)
+ { MP_ROM_QSTR(MP_QSTR_PC28), MP_ROM_PTR(&pin_PC28) },
+#endif
+#if defined(PIN_PC30)
+ { MP_ROM_QSTR(MP_QSTR_PC30), MP_ROM_PTR(&pin_PC30) },
+#endif
+#if defined(PIN_PC31)
+ { MP_ROM_QSTR(MP_QSTR_PC31), MP_ROM_PTR(&pin_PC31) },
+#endif
+
+#if defined(PIN_PD00)
+ { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) },
+#endif
+#if defined(PIN_PD01)
+ { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) },
+#endif
+#if defined(PIN_PD08)
+ { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) },
+#endif
+#if defined(PIN_PD09)
+ { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) },
+#endif
+#if defined(PIN_PD10)
+ { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) },
+#endif
+#if defined(PIN_PD11)
+ { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) },
+#endif
+#if defined(PIN_PD12)
+ { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) },
+#endif
+#if defined(PIN_PD20)
+ { MP_ROM_QSTR(MP_QSTR_PD20), MP_ROM_PTR(&pin_PD20) },
+#endif
+#if defined(PIN_PD21)
+ { MP_ROM_QSTR(MP_QSTR_PD21), MP_ROM_PTR(&pin_PD21) },
+#endif
};
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);
diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.c b/ports/atmel-samd/common-hal/supervisor/Runtime.c
index 2636fe646..ea663f897 100755
--- a/ports/atmel-samd/common-hal/supervisor/Runtime.c
+++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c
@@ -26,13 +26,12 @@
#include <stdbool.h>
#include "shared-bindings/supervisor/Runtime.h"
-#include "usb.h"
+#include "supervisor/serial.h"
bool common_hal_get_serial_connected(void) {
- return (bool) usb_connected();
+ return (bool) serial_connected();
}
bool common_hal_get_serial_bytes_available(void) {
- return (bool) usb_bytes_available();
+ return (bool) serial_bytes_available();
}
-
diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.c b/ports/atmel-samd/common-hal/usb_hid/Device.c
deleted file mode 100644
index 31bace018..000000000
--- a/ports/atmel-samd/common-hal/usb_hid/Device.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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 <string.h>
-
-#include "common-hal/usb_hid/Device.h"
-
-#include "py/runtime.h"
-#include "shared-bindings/microcontroller/__init__.h"
-#include "shared-bindings/usb_hid/Device.h"
-#include "supervisor/shared/translate.h"
-#include "genhdr/autogen_usb_descriptor.h"
-
-#include "tick.h"
-
-#include "usb/class/hid/device/hiddf_generic.h"
-
-static uint32_t usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) {
-
- int32_t status;
-
- // Don't get stuck if USB fails in some way; timeout after a while.
- uint64_t end_ticks = ticks_ms + 2000;
-
- while (ticks_ms < end_ticks) {
- status = usb_d_ep_get_status(self->endpoint, NULL);
- if (status == USB_BUSY) {
- continue;
- }
- if (status == USB_OK) {
- break;
- }
- // Some error. Give up.
- return status;
- }
-
- // Copy the data only when endpoint is ready to send. The previous
- // buffer load gets zero'd out when transaction completes, so if
- // you copy before it's ready, only zeros will get sent.
-
- // Prefix with a report id if one is supplied.
- if (self->report_id > 0) {
- self->report_buffer[0] = self->report_id;
- memcpy(&(self->report_buffer[1]), report, len);
- return hiddf_generic_write(self->report_buffer, len + 1);
- } else {
- memcpy(self->report_buffer, report, len);
- return hiddf_generic_write(self->report_buffer, len);
- }
-
-}
-
-void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) {
- if (len != self->report_length) {
- mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length);
- }
- int32_t status = usb_hid_send_report(self, report, len);
- if (status != ERR_NONE) {
- mp_raise_msg(&mp_type_OSError, status == USB_BUSY ? translate("USB Busy") : translate("USB Error"));
- }
-}
-
-uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) {
- return self->usage_page;
-}
-
-uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) {
- return self->usage;
-}
-
-
-void usb_hid_init() {
-}
-
-void usb_hid_reset() {
- // We don't actually reset. We just set a report that is empty to prevent
- // long keypresses and such.
- uint8_t report[USB_HID_MAX_REPORT_LENGTH] = {0};
-
- for (size_t i = 0; i < USB_HID_NUM_DEVICES; i++) {
- usb_hid_send_report(&usb_hid_devices[i], report, usb_hid_devices[i].report_length);
- }
-}
diff --git a/ports/atmel-samd/common-hal/usb_hid/__init__.c b/ports/atmel-samd/common-hal/usb_hid/__init__.c
deleted file mode 100644
index 770d221c7..000000000
--- a/ports/atmel-samd/common-hal/usb_hid/__init__.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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 "py/obj.h"
-#include "py/mphal.h"
-#include "py/runtime.h"
-
-#include "common-hal/usb_hid/Device.h"
-
-#include "shared-bindings/usb_hid/Device.h"
-
-#include "genhdr/autogen_usb_descriptor.h"
-
-// Buffers are report size + 1 to include the Report ID prefix byte if needed.
-#ifdef USB_HID_REPORT_ID_KEYBOARD
-static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD + 1];
-#endif
-#ifdef USB_HID_REPORT_ID_MOUSE
-static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE + 1];
-#endif
-#ifdef USB_HID_REPORT_ID_CONSUMER
-static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER + 1];
-#endif
-#ifdef USB_HID_REPORT_ID_SYS_CONTROL
-static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL + 1];
-#endif
-#ifdef USB_HID_REPORT_ID_GAMEPAD
-static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD + 1];
-#endif
-#ifdef USB_HID_REPORT_ID_DIGITIZER
-static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER + 1];
-#endif
-
-usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
-#ifdef USB_HID_REPORT_ID_KEYBOARD
- {
- .base = { .type = &usb_hid_device_type },
- .report_buffer = keyboard_report_buffer,
- .endpoint = USB_HID_ENDPOINT_IN,
- .report_id = USB_HID_REPORT_ID_KEYBOARD,
- .report_length = USB_HID_REPORT_LENGTH_KEYBOARD,
- .usage_page = 0x01,
- .usage = 0x06,
- },
-#endif
-#ifdef USB_HID_REPORT_ID_MOUSE
- {
- .base = { .type = &usb_hid_device_type },
- .report_buffer = mouse_report_buffer,
- .endpoint = USB_HID_ENDPOINT_IN,
- .report_id = USB_HID_REPORT_ID_MOUSE,
- .report_length = USB_HID_REPORT_LENGTH_MOUSE,
- .usage_page = 0x01,
- .usage = 0x02,
- },
-#endif
-#ifdef USB_HID_REPORT_ID_CONSUMER
- {
- .base = { .type = &usb_hid_device_type },
- .report_buffer = consumer_report_buffer,
- .endpoint = USB_HID_ENDPOINT_IN,
- .report_id = USB_HID_REPORT_ID_CONSUMER,
- .report_length = USB_HID_REPORT_LENGTH_CONSUMER,
- .usage_page = 0x0C,
- .usage = 0x01,
- },
-#endif
-#ifdef USB_HID_REPORT_ID_SYS_CONTROL
- {
- .base = { .type = &usb_hid_device_type },
- .report_buffer = sys_control_report_buffer,
- .endpoint = USB_HID_ENDPOINT_IN,
- .report_id = USB_HID_REPORT_ID_SYS_CONTROL,
- .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL,
- .usage_page = 0x01,
- .usage = 0x80,
- },
-#endif
-#ifdef USB_HID_REPORT_ID_GAMEPAD
- {
- .base = { .type = &usb_hid_device_type },
- .report_buffer = gamepad_report_buffer,
- .endpoint = USB_HID_ENDPOINT_IN,
- .report_id = USB_HID_REPORT_ID_GAMEPAD,
- .report_length = USB_HID_REPORT_LENGTH_GAMEPAD,
- .usage_page = 0x01,
- .usage = 0x05,
- },
-#endif
-#ifdef USB_HID_REPORT_ID_DIGITIZER
- {
- .base = { .type = &usb_hid_device_type },
- .report_buffer = digitizer_report_buffer,
- .endpoint = USB_HID_ENDPOINT_IN,
- .report_id = USB_HID_REPORT_ID_DIGITIZER,
- .report_length = USB_HID_REPORT_LENGTH_DIGITIZER,
- .usage_page = 0x0D,
- .usage = 0x02,
- },
-#endif
-};
-
-
-mp_obj_tuple_t common_hal_usb_hid_devices = {
- .base = {
- .type = &mp_type_tuple,
- },
- .len = USB_HID_NUM_DEVICES,
- .items = {
-#if USB_HID_NUM_DEVICES >= 1
- (mp_obj_t) &usb_hid_devices[0],
-#endif
-#if USB_HID_NUM_DEVICES >= 2
- (mp_obj_t) &usb_hid_devices[1],
-#endif
-#if USB_HID_NUM_DEVICES >= 3
- (mp_obj_t) &usb_hid_devices[2],
-#endif
-#if USB_HID_NUM_DEVICES >= 4
- (mp_obj_t) &usb_hid_devices[3],
-#endif
-#if USB_HID_NUM_DEVICES >= 5
- (mp_obj_t) &usb_hid_devices[4],
-#endif
-#if USB_HID_NUM_DEVICES >= 6
- (mp_obj_t) &usb_hid_devices[5],
-#endif
- }
-};
diff --git a/ports/atmel-samd/external_flash/external_flash.h b/ports/atmel-samd/external_flash/external_flash.h
deleted file mode 100644
index f8ec5673c..000000000
--- a/ports/atmel-samd/external_flash/external_flash.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_H
-
-#include <stdbool.h>
-
-#include "mpconfigport.h"
-
-// We use this when we can allocate the whole cache in RAM.
-#define FLASH_ROOT_POINTERS \
- uint8_t** flash_ram_cache; \
-
-// Erase sector size.
-#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100)
-
-// These are common across all NOR Flash.
-#define SPI_FLASH_ERASE_SIZE (1 << 12)
-#define SPI_FLASH_PAGE_SIZE (256)
-
-#define SPI_FLASH_SYSTICK_MASK (0x1ff) // 512ms
-#define SPI_FLASH_IDLE_TICK(tick) (((tick) & SPI_FLASH_SYSTICK_MASK) == 2)
-
-void external_flash_init(void);
-uint32_t external_flash_get_block_size(void);
-uint32_t external_flash_get_block_count(void);
-void external_flash_irq_handler(void);
-void external_flash_flush(void);
-bool external_flash_read_block(uint8_t *dest, uint32_t block);
-bool external_flash_write_block(const uint8_t *src, uint32_t block);
-
-// these return 0 on success, non-zero on error
-mp_uint_t external_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
-mp_uint_t external_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
-
-extern const struct _mp_obj_type_t external_flash_type;
-
-struct _fs_user_mount_t;
-void flash_init_vfs(struct _fs_user_mount_t *vfs);
-
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_H
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index a4c763d05..3b95aefa9 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -154,6 +154,7 @@ typedef long mp_off_t;
#define CIRCUITPY_MCU_FAMILY samd21
#define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21"
#define PORT_HEAP_SIZE (16384 + 4096)
+#define SPI_FLASH_MAX_BAUDRATE 8000000
#define CIRCUITPY_DEFAULT_STACK_SIZE 4096
#define MICROPY_CPYTHON_COMPAT (0)
#define MICROPY_MODULE_WEAK_LINKS (0)
@@ -169,6 +170,7 @@ typedef long mp_off_t;
#define CIRCUITPY_MCU_FAMILY samd51
#define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51"
#define PORT_HEAP_SIZE (0x20000) // 128KiB
+#define SPI_FLASH_MAX_BAUDRATE 24000000
#define CIRCUITPY_DEFAULT_STACK_SIZE 8192
#define MICROPY_CPYTHON_COMPAT (1)
#define MICROPY_MODULE_WEAK_LINKS (1)
@@ -421,8 +423,13 @@ extern const struct _mp_obj_module_t wiznet_module;
#define MP_STATE_PORT MP_STATE_VM
+void run_background_tasks(void);
+#define MICROPY_VM_HOOK_LOOP run_background_tasks();
+#define MICROPY_VM_HOOK_RETURN run_background_tasks();
+
#include "peripherals/samd/dma.h"
+#include "supervisor/flash_root_pointers.h"
#if MICROPY_PY_NETWORK
#define NETWORK_ROOT_POINTERS mp_obj_list_t mod_network_nic_list;
#else
@@ -438,9 +445,6 @@ extern const struct _mp_obj_module_t wiznet_module;
mp_obj_t gamepad_singleton; \
NETWORK_ROOT_POINTERS \
-void run_background_tasks(void);
-#define MICROPY_VM_HOOK_LOOP run_background_tasks();
-#define MICROPY_VM_HOOK_RETURN run_background_tasks();
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index d5c9f2ce6..7db581dd6 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -14,6 +14,6 @@ ifeq ($(LONGINT_IMPL),LONGLONG)
MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong
endif
-
INTERNAL_LIBM = 1
+USB_SERIAL_NUMBER_LENGTH = 32
diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c
index a4eca1c74..ac5b0fbca 100644
--- a/ports/atmel-samd/mphalport.c
+++ b/ports/atmel-samd/mphalport.c
@@ -46,43 +46,9 @@
#include "mphalport.h"
#include "reset.h"
#include "tick.h"
-#include "usb.h"
-extern struct usart_module usart_instance;
extern uint32_t common_hal_mcu_processor_get_frequency(void);
-int mp_hal_stdin_rx_chr(void) {
- for (;;) {
- #ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
- #endif
- // if (reload_requested) {
- // return CHAR_CTRL_D;
- // }
- if (usb_bytes_available()) {
- #ifdef MICROPY_HW_LED_RX
- gpio_toggle_pin_level(MICROPY_HW_LED_RX);
- #endif
- return usb_read();
- }
- }
-}
-
-void mp_hal_stdout_tx_strn(const char *str, size_t len) {
- #ifdef MICROPY_HW_LED_TX
- gpio_toggle_pin_level(MICROPY_HW_LED_TX);
- #endif
-
- #ifdef CIRCUITPY_BOOT_OUTPUT_FILE
- if (boot_output_file != NULL) {
- UINT bytes_written = 0;
- f_write(boot_output_file, str, len, &bytes_written);
- }
- #endif
-
- usb_write(str, len);
-}
-
void mp_hal_delay_ms(mp_uint_t delay) {
uint64_t start_tick = ticks_ms;
uint64_t duration = 0;
diff --git a/ports/atmel-samd/mphalport.h b/ports/atmel-samd/mphalport.h
index 3bc824d4e..64269b201 100644
--- a/ports/atmel-samd/mphalport.h
+++ b/ports/atmel-samd/mphalport.h
@@ -41,8 +41,6 @@ static inline mp_uint_t mp_hal_ticks_ms(void) {
volatile uint8_t usb_rx_count;
volatile bool mp_cdc_enabled;
-FIL* boot_output_file;
-
int receive_usb(void);
void mp_hal_set_interrupt_char(int c);
diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals
-Subproject d0dcba251c27f629c0a89b5ced4433dd0a609ca
+Subproject f20fcf642b5654ee68d7d551ea7db39716ef83b
diff --git a/ports/atmel-samd/reset.c b/ports/atmel-samd/reset.c
index ba5bf9ba1..735639cc4 100644
--- a/ports/atmel-samd/reset.c
+++ b/ports/atmel-samd/reset.c
@@ -34,10 +34,6 @@ void reset(void) {
NVIC_SystemReset();
}
-void reset_to_bootloader(void) {
- _bootloader_dbl_tap = DBL_TAP_MAGIC;
- reset();
-}
extern uint32_t _srelocate;
bool bootloader_available(void) {
diff --git a/ports/atmel-samd/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c
index 35eb52da2..6e097b214 100644
--- a/ports/atmel-samd/internal_flash.c
+++ b/ports/atmel-samd/supervisor/internal_flash.c
@@ -23,7 +23,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "internal_flash.h"
+
+#include "supervisor/internal_flash.h"
#include <stdint.h>
#include <string.h>
@@ -42,9 +43,9 @@
#include "supervisor/shared/rgb_led_status.h"
-static struct flash_descriptor internal_flash_desc;
+static struct flash_descriptor supervisor_flash_desc;
-void internal_flash_init(void) {
+void supervisor_flash_init(void) {
// Activity LED for flash writes.
#ifdef MICROPY_HW_LED_MSC
struct port_config pin_conf;
@@ -61,22 +62,22 @@ void internal_flash_init(void) {
#ifdef SAMD21
_pm_enable_bus_clock(PM_BUS_APBB, NVMCTRL);
#endif
- flash_init(&internal_flash_desc, NVMCTRL);
+ flash_init(&supervisor_flash_desc, NVMCTRL);
}
-uint32_t internal_flash_get_block_size(void) {
+uint32_t supervisor_flash_get_block_size(void) {
return FILESYSTEM_BLOCK_SIZE;
}
-uint32_t internal_flash_get_block_count(void) {
+uint32_t supervisor_flash_get_block_count(void) {
return INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS;
}
-void internal_flash_flush(void) {
+void supervisor_flash_flush(void) {
}
void flash_flush(void) {
- internal_flash_flush();
+ supervisor_flash_flush();
}
static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) {
@@ -125,7 +126,7 @@ static int32_t convert_block_to_flash_addr(uint32_t block) {
return -1;
}
-bool internal_flash_read_block(uint8_t *dest, uint32_t block) {
+bool supervisor_flash_read_block(uint8_t *dest, uint32_t block) {
if (block == 0) {
// fake the MBR so we can decide on our own partition table
@@ -150,12 +151,12 @@ bool internal_flash_read_block(uint8_t *dest, uint32_t block) {
// bad block number
return false;
}
- int32_t error_code = flash_read(&internal_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE);
+ int32_t error_code = flash_read(&supervisor_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE);
return error_code == ERR_NONE;
}
}
-bool internal_flash_write_block(const uint8_t *src, uint32_t block) {
+bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) {
if (block == 0) {
// can't write MBR, but pretend we did
return true;
@@ -172,14 +173,14 @@ bool internal_flash_write_block(const uint8_t *src, uint32_t block) {
return false;
}
int32_t error_code;
- error_code = flash_erase(&internal_flash_desc,
+ error_code = flash_erase(&supervisor_flash_desc,
dest,
- FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&internal_flash_desc));
+ FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&supervisor_flash_desc));
if (error_code != ERR_NONE) {
return false;
}
- error_code = flash_append(&internal_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE);
+ error_code = flash_append(&supervisor_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE);
if (error_code != ERR_NONE) {
return false;
}
@@ -191,95 +192,20 @@ bool internal_flash_write_block(const uint8_t *src, uint32_t block) {
}
}
-mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
+mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
for (size_t i = 0; i < num_blocks; i++) {
- if (!internal_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
+ if (!supervisor_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
return 1; // error
}
}
return 0; // success
}
-mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
+mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
for (size_t i = 0; i < num_blocks; i++) {
- if (!internal_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
+ if (!supervisor_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
return 1; // error
}
}
return 0; // success
}
-
-/******************************************************************************/
-// MicroPython bindings
-//
-// Expose the flash as an object with the block protocol.
-
-// there is a singleton Flash object
-STATIC const mp_obj_base_t internal_flash_obj = {&internal_flash_type};
-
-STATIC mp_obj_t internal_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- // check arguments
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
-
- // return singleton object
- return (mp_obj_t)&internal_flash_obj;
-}
-
-STATIC mp_obj_t internal_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
- mp_uint_t ret = internal_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
- return MP_OBJ_NEW_SMALL_INT(ret);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_readblocks_obj, internal_flash_obj_readblocks);
-
-STATIC mp_obj_t internal_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
- mp_uint_t ret = internal_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
- return MP_OBJ_NEW_SMALL_INT(ret);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_writeblocks_obj, internal_flash_obj_writeblocks);
-
-STATIC mp_obj_t internal_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
- mp_int_t cmd = mp_obj_get_int(cmd_in);
- switch (cmd) {
- case BP_IOCTL_INIT: internal_flash_init(); return MP_OBJ_NEW_SMALL_INT(0);
- case BP_IOCTL_DEINIT: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly
- case BP_IOCTL_SYNC: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0);
- case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_count());
- case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_size());
- default: return mp_const_none;
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_ioctl_obj, internal_flash_obj_ioctl);
-
-STATIC const mp_rom_map_elem_t internal_flash_obj_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&internal_flash_obj_readblocks_obj) },
- { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&internal_flash_obj_writeblocks_obj) },
- { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&internal_flash_obj_ioctl_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(internal_flash_obj_locals_dict, internal_flash_obj_locals_dict_table);
-
-const mp_obj_type_t internal_flash_type = {
- { &mp_type_type },
- .name = MP_QSTR_InternalFlash,
- .make_new = internal_flash_obj_make_new,
- .locals_dict = (mp_obj_t)&internal_flash_obj_locals_dict,
-};
-
-void flash_init_vfs(fs_user_mount_t *vfs) {
- vfs->base.type = &mp_fat_vfs_type;
- vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
- vfs->fatfs.drv = vfs;
- vfs->fatfs.part = 1; // flash filesystem lives on first partition
- vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj;
- vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj;
- vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version
- vfs->writeblocks[0] = (mp_obj_t)&internal_flash_obj_writeblocks_obj;
- vfs->writeblocks[1] = (mp_obj_t)&internal_flash_obj;
- vfs->writeblocks[2] = (mp_obj_t)internal_flash_write_blocks; // native version
- vfs->u.ioctl[0] = (mp_obj_t)&internal_flash_obj_ioctl_obj;
- vfs->u.ioctl[1] = (mp_obj_t)&internal_flash_obj;
-}
diff --git a/ports/atmel-samd/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h
index 88c105386..b1074d93f 100644
--- a/ports/atmel-samd/internal_flash.h
+++ b/ports/atmel-samd/supervisor/internal_flash.h
@@ -32,8 +32,6 @@
#include "sam.h"
-#define FLASH_ROOT_POINTERS
-
#ifdef SAMD51
#define TOTAL_INTERNAL_FLASH_SIZE (FLASH_SIZE / 2)
#endif
@@ -49,21 +47,4 @@
#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms
#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2)
-void internal_flash_init(void);
-uint32_t internal_flash_get_block_size(void);
-uint32_t internal_flash_get_block_count(void);
-void internal_flash_irq_handler(void);
-void internal_flash_flush(void);
-bool internal_flash_read_block(uint8_t *dest, uint32_t block);
-bool internal_flash_write_block(const uint8_t *src, uint32_t block);
-
-// these return 0 on success, non-zero on error
-mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
-mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
-
-extern const struct _mp_obj_type_t internal_flash_type;
-
-struct _fs_user_mount_t;
-void flash_init_vfs(struct _fs_user_mount_t *vfs);
-
#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H
diff --git a/ports/atmel-samd/supervisor/internal_flash_root_pointers.h b/ports/atmel-samd/supervisor/internal_flash_root_pointers.h
new file mode 100644
index 000000000..3e9148ce0
--- /dev/null
+++ b/ports/atmel-samd/supervisor/internal_flash_root_pointers.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * 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_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H
+
+#define FLASH_ROOT_POINTERS
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index 45b8ed1a4..9f951b035 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -32,7 +32,6 @@
#include "hal/include/hal_delay.h"
#include "hal/include/hal_gpio.h"
#include "hal/include/hal_init.h"
-#include "hal/include/hal_usb_device.h"
#include "hpl/gclk/hpl_gclk_base.h"
#include "hpl/pm/hpl_pm_base.h"
@@ -48,13 +47,13 @@
#include "common-hal/audiobusio/PDMIn.h"
#include "common-hal/audiobusio/I2SOut.h"
#include "common-hal/audioio/AudioOut.h"
+#include "common-hal/busio/SPI.h"
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/pulseio/PulseIn.h"
#include "common-hal/pulseio/PulseOut.h"
#include "common-hal/pulseio/PWMOut.h"
#include "common-hal/rtc/RTC.h"
#include "common-hal/touchio/TouchIn.h"
-#include "common-hal/usb_hid/Device.h"
#include "samd/cache.h"
#include "samd/clocks.h"
#include "samd/events.h"
@@ -62,8 +61,10 @@
#include "samd/dma.h"
#include "shared-bindings/rtc/__init__.h"
#include "board_busses.h"
+#include "reset.h"
#include "tick.h"
-#include "usb.h"
+
+#include "tusb.h"
#ifdef CIRCUITPY_GAMEPAD_TICKS
#include "shared-module/gamepad/__init__.h"
@@ -225,28 +226,7 @@ safe_mode_t port_init(void) {
}
void reset_port(void) {
- // Reset all SERCOMs except the ones being used by on-board devices.
- Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
- for (int i = 0; i < SERCOM_INST_NUM; i++) {
-#ifdef SPI_FLASH_SERCOM
- if (sercom_instances[i] == SPI_FLASH_SERCOM) {
- continue;
- }
-#endif
-#ifdef MICROPY_HW_APA102_SERCOM
- if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) {
- continue;
- }
-#endif
-#ifdef CIRCUITPY_DISPLAYIO
- // TODO(tannewt): Make this dynamic.
- if (sercom_instances[i] == board_display_obj.bus.spi_desc.dev.prvt) {
- continue;
- }
-#endif
- // SWRST is same for all modes of SERCOMs.
- sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1;
- }
+ reset_sercoms();
#if defined(EXPRESS_BOARD) && !defined(__SAMR21G18A__)
audio_dma_reset();
@@ -290,13 +270,16 @@ void reset_port(void) {
// gpio_set_pin_function(PIN_PB15, GPIO_PIN_FUNCTION_M); // GCLK1, D6
// #endif
- usb_hid_reset();
-
- if (usb_connected()) {
+ if (tud_cdc_connected()) {
save_usb_clock_calibration();
}
}
+void reset_to_bootloader(void) {
+ _bootloader_dbl_tap = DBL_TAP_MAGIC;
+ reset();
+}
+
/**
* \brief Default interrupt handler for unused IRQs.
*/
diff --git a/ports/atmel-samd/external_flash/qspi_flash.c b/ports/atmel-samd/supervisor/qspi_flash.c
index f6dc00d50..eca47b164 100644
--- a/ports/atmel-samd/external_flash/qspi_flash.c
+++ b/ports/atmel-samd/supervisor/qspi_flash.c
@@ -24,14 +24,15 @@
* THE SOFTWARE.
*/
-#include "spi_flash_api.h"
+#include "supervisor/spi_flash_api.h"
#include <stdint.h>
#include <string.h>
#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
-#include "external_flash/common_commands.h"
+#include "supervisor/shared/external_flash/common_commands.h"
+#include "supervisor/shared/external_flash/qspi_flash.h"
#include "samd/cache.h"
#include "samd/dma.h"
@@ -225,18 +226,7 @@ void spi_flash_init(void) {
}
void spi_flash_init_device(const external_flash_device* device) {
- // Verify that QSPI mode is enabled.
- uint8_t status;
- spi_flash_read_command(CMD_READ_STATUS2, &status, 1);
-
- // Bit 1 is Quad Enable
- if ((status & 0x2) == 0) {
- uint8_t full_status[2] = {0x0, 0x2};
- spi_flash_command(CMD_ENABLE_WRITE);
- if (device->write_status_register_split) {
- spi_flash_write_command(CMD_WRITE_STATUS_BYTE2, full_status + 1, 1);
- } else {
- spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2);
- }
- }
+ check_quad_enable(device);
+
+ // TODO(tannewt): Adjust the speed for the found device.
}
diff --git a/ports/atmel-samd/supervisor/serial.c b/ports/atmel-samd/supervisor/serial.c
deleted file mode 100644
index 4917dfb5b..000000000
--- a/ports/atmel-samd/supervisor/serial.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 <string.h>
-
-#include "supervisor/serial.h"
-
-#include "common-hal/usb_hid/Device.h"
-
-#include "usb.h"
-#include "genhdr/autogen_usb_descriptor.h"
-
-// Serial number as hex characters. This writes directly to the USB
-// descriptor.
-void load_serial_number(void) {
- char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'};
- #ifdef SAMD21
- uint32_t* addresses[4] = {(uint32_t *) 0x0080A00C, (uint32_t *) 0x0080A040,
- (uint32_t *) 0x0080A044, (uint32_t *) 0x0080A048};
- #endif
- #ifdef SAMD51
- uint32_t* addresses[4] = {(uint32_t *) 0x008061FC, (uint32_t *) 0x00806010,
- (uint32_t *) 0x00806014, (uint32_t *) 0x00806018};
- #endif
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 8; j++) {
- uint8_t nibble = (*(addresses[i]) >> j * 4) & 0xf;
- // Strings are UTF-16-LE encoded.
- serial_number[i * 16 + j * 2] = nibble_to_hex[nibble];
- serial_number[i * 16 + j * 2 + 1] = 0;
- }
- }
-}
-
-void serial_init(void) {
- load_serial_number();
- init_usb();
- usb_hid_init();
-}
-
-bool serial_connected(void) {
- return usb_connected();
-}
-
-char serial_read(void) {
- return usb_read();
-}
-
-bool serial_bytes_available(void) {
- return usb_bytes_available();
-}
-
-void serial_write(const char* text) {
- usb_write(text, strlen(text));
-}
diff --git a/ports/atmel-samd/supervisor/usb.c b/ports/atmel-samd/supervisor/usb.c
new file mode 100644
index 000000000..d13ca0ef1
--- /dev/null
+++ b/ports/atmel-samd/supervisor/usb.c
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017, 2018 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 "atmel_start_pins.h"
+#include "hpl/pm/hpl_pm_base.h"
+#include "hpl/gclk/hpl_gclk_base.h"
+#include "hal_gpio.h"
+
+void init_usb_hardware(void) {
+ #ifdef SAMD21
+ _pm_enable_bus_clock(PM_BUS_APBB, USB);
+ _pm_enable_bus_clock(PM_BUS_AHB, USB);
+ _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
+ #endif
+
+ #ifdef SAMD51
+ hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN);
+ hri_mclk_set_AHBMASK_USB_bit(MCLK);
+ hri_mclk_set_APBBMASK_USB_bit(MCLK);
+ #endif
+
+ gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT);
+ gpio_set_pin_level(PIN_PA24, false);
+ gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF);
+ gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT);
+ gpio_set_pin_level(PIN_PA25, false);
+ gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF);
+ #ifdef SAMD21
+ gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM);
+ gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP);
+ #endif
+ #ifdef SAMD51
+ gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM);
+ gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP);
+ #endif
+}
diff --git a/ports/atmel-samd/tick.h b/ports/atmel-samd/tick.h
index 80e7bc9af..c8c8d739a 100644
--- a/ports/atmel-samd/tick.h
+++ b/ports/atmel-samd/tick.h
@@ -26,7 +26,7 @@
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_TICK_H
#define MICROPY_INCLUDED_ATMEL_SAMD_TICK_H
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
extern volatile uint64_t ticks_ms;
diff --git a/ports/atmel-samd/usb.c b/ports/atmel-samd/usb.c
deleted file mode 100644
index 1f1ba550f..000000000
--- a/ports/atmel-samd/usb.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * This file is part of the Micro Python 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 "usb.h"
-
-#include <stdint.h>
-
-// We must include this early because it sets values used in the ASF4 includes
-// below.
-#include "py/mpconfig.h"
-
-#include "hal/include/hal_gpio.h"
-#include "usb/class/cdc/device/cdcdf_acm.h"
-#include "usb/class/hid/device/hiddf_generic.h"
-#include "usb/class/composite/device/composite_desc.h"
-#include "usb/class/msc/device/mscdf.h"
-#include "peripheral_clk_config.h"
-#include "hpl/pm/hpl_pm_base.h"
-#include "hpl/gclk/hpl_gclk_base.h"
-
-#include "lib/utils/interrupt_char.h"
-#include "genhdr/autogen_usb_descriptor.h"
-#include "reset.h"
-#include "usb_mass_storage.h"
-
-#include "supervisor/shared/autoreload.h"
-
-extern struct usbd_descriptors descriptor_bounds;
-
-// Store received characters on our own so that we can filter control characters
-// and act immediately on CTRL-C for example.
-
-// Receive buffer
-static uint8_t usb_rx_buf[USB_RX_BUF_SIZE];
-
-// Receive buffer head
-static volatile uint8_t usb_rx_buf_head = 0;
-
-// Receive buffer tail
-static volatile uint8_t usb_rx_buf_tail = 0;
-
-// Number of bytes in receive buffer
-volatile uint8_t usb_rx_count = 0;
-
-volatile bool mp_cdc_enabled = false;
-volatile bool usb_transmitting = false;
-
-/** Ctrl endpoint buffer */
-COMPILER_ALIGNED(4) static uint8_t ctrl_buffer[64];
-
-static void init_hardware(void) {
- #ifdef SAMD21
- _pm_enable_bus_clock(PM_BUS_APBB, USB);
- _pm_enable_bus_clock(PM_BUS_AHB, USB);
- _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
- #endif
-
- #ifdef SAMD51
- hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, CONF_GCLK_USB_SRC | GCLK_PCHCTRL_CHEN);
- hri_mclk_set_AHBMASK_USB_bit(MCLK);
- hri_mclk_set_APBBMASK_USB_bit(MCLK);
- #endif
-
- usb_d_init();
-
- gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(PIN_PA24, false);
- gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF);
- gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(PIN_PA25, false);
- gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF);
- #ifdef SAMD21
- gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM);
- gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP);
- #endif
- #ifdef SAMD51
- gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM);
- gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP);
- #endif
-}
-
-#define CDC_BULKOUT_SIZE CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ
-COMPILER_ALIGNED(4) uint8_t cdc_packet_buffer[CDC_BULKOUT_SIZE];
-static volatile bool pending_read;
-
-static int32_t start_read(void) {
- pending_read = true;
- int32_t result = cdcdf_acm_read(cdc_packet_buffer, CDC_BULKOUT_SIZE);
- if (result != ERR_NONE) {
- pending_read = false;
- }
- return result;
-}
-
-static bool read_complete(const uint8_t ep, const enum usb_xfer_code rc, const uint32_t count) {
- if (rc != USB_XFER_DONE) {
- return false; // No errors.
- }
- pending_read = false;
- volatile hal_atomic_t flags;
- atomic_enter_critical(&flags);
- // If our buffer can't fit the data received, then error out.
- if (count > (uint8_t) (USB_RX_BUF_SIZE - usb_rx_count)) {
- atomic_leave_critical(&flags);
- return true;
- }
-
- for (uint16_t i = 0; i < count; i++) {
- uint8_t c = cdc_packet_buffer[i];
- if (c == mp_interrupt_char) {
- mp_keyboard_interrupt();
- // If interrupted, flush all the input.
- usb_rx_count = 0;
- usb_rx_buf_head = 0;
- usb_rx_buf_tail = 0;
- break;
- } else {
- // The count of characters present in receive buffer is
- // incremented.
- usb_rx_count++;
- usb_rx_buf[usb_rx_buf_tail] = c;
- usb_rx_buf_tail++;
- if (usb_rx_buf_tail == USB_RX_BUF_SIZE) {
- // Reached the end of buffer, revert back to beginning of
- // buffer.
- usb_rx_buf_tail = 0;
- }
- }
- }
- atomic_leave_critical(&flags);
-
- /* No error. */
- return false;
-}
-
-static bool write_complete(const uint8_t ep,
- const enum usb_xfer_code rc,
- const uint32_t count) {
- if (rc != USB_XFER_DONE) {
- return false; // No errors.
- }
- // This is called after writes are finished.
-
- usb_transmitting = false;
-
- /* No error. */
- return false;
-}
-
-volatile bool reset_on_disconnect = false;
-volatile bool cdc_connected = false;
-
-static bool usb_device_cb_state_c(usb_cdc_control_signal_t state)
-{
- cdc_connected = state.rs232.DTR;
- if (state.rs232.DTR) {
- } else if (!state.rs232.DTR && reset_on_disconnect) {
- reset_to_bootloader();
- }
-
- /* No error. */
- return false;
-}
-
-static bool usb_device_cb_line_coding_c(const usb_cdc_line_coding_t* coding)
-{
- reset_on_disconnect = coding->dwDTERate == 1200;
- /* Ok to change. */
- return true;
-}
-
-void init_usb(void) {
- init_hardware();
-
- mp_cdc_enabled = false;
-
- usbdc_init(ctrl_buffer);
-
- /* usbdc_register_function inside */
- cdcdf_acm_init();
- pending_read = false;
-
- mscdf_init(1);
- mscdf_register_callback(MSCDF_CB_INQUIRY_DISK, (FUNC_PTR)usb_msc_inquiry_info);
- mscdf_register_callback(MSCDF_CB_GET_DISK_CAPACITY, (FUNC_PTR)usb_msc_get_capacity);
- mscdf_register_callback(MSCDF_CB_START_READ_DISK, (FUNC_PTR)usb_msc_new_read);
- mscdf_register_callback(MSCDF_CB_START_WRITE_DISK, (FUNC_PTR)usb_msc_new_write);
- mscdf_register_callback(MSCDF_CB_EJECT_DISK, (FUNC_PTR)usb_msc_disk_eject);
- mscdf_register_callback(MSCDF_CB_TEST_DISK_READY, (FUNC_PTR)usb_msc_disk_is_ready);
- mscdf_register_callback(MSCDF_CB_XFER_BLOCKS_DONE, (FUNC_PTR)usb_msc_xfer_done);
- mscdf_register_callback(MSCDF_CB_IS_WRITABLE, (FUNC_PTR)usb_msc_disk_is_writable);
-
- hiddf_generic_init(hid_report_descriptor, sizeof(hid_report_descriptor));
-
- usbdc_start(&descriptor_bounds);
-
- usbdc_attach();
-
-
-}
-
-static bool cdc_enabled(void) {
- if (!cdcdf_acm_is_enabled()) {
- mp_cdc_enabled = false;
- return false;
- }
- if (!mp_cdc_enabled) {
- cdcdf_acm_register_callback(CDCDF_ACM_CB_READ, (FUNC_PTR)read_complete);
- cdcdf_acm_register_callback(CDCDF_ACM_CB_WRITE, (FUNC_PTR)write_complete);
- cdcdf_acm_register_callback(CDCDF_ACM_CB_STATE_C, (FUNC_PTR)usb_device_cb_state_c);
- cdcdf_acm_register_callback(CDCDF_ACM_CB_LINE_CODING_C, (FUNC_PTR)usb_device_cb_line_coding_c);
- mp_cdc_enabled = true;
- }
-
- return true;
-}
-
-bool usb_bytes_available(void) {
- // Check if the buffer has data, but not enough
- // space to hold another read.
- if (usb_rx_count > USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE) {
- return true;
- }
- // Buffer has enough room
- if (cdc_enabled() && !pending_read) {
- start_read();
- }
- // Buffer is empty and/or no new data is available
- if (usb_rx_count == 0) {
- return false;
- }
- return usb_rx_count > 0;
-}
-
-int usb_read(void) {
- if (!cdc_enabled() || usb_rx_count == 0) {
- return 0;
- }
-
- // Copy from head.
- int data;
- CRITICAL_SECTION_ENTER();
- data = usb_rx_buf[usb_rx_buf_head];
- usb_rx_buf_head++;
- usb_rx_count--;
- if (usb_rx_buf_head == USB_RX_BUF_SIZE) {
- usb_rx_buf_head = 0;
- }
- CRITICAL_SECTION_LEAVE();
-
- return data;
-}
-
-// TODO(tannewt): See if we can disable the internal CDC IN cache since we
-// we manage this one ourselves.
-#define CDC_BULKIN_SIZE CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ
-COMPILER_ALIGNED(4) uint8_t cdc_output_buffer[CDC_BULKIN_SIZE];
-
-void usb_write(const char* buffer, uint32_t len) {
- if (!cdc_enabled()) {
- return;
- }
- if (!cdc_connected) {
- // TODO(tannewt): Should we write to a file instead?
- return;
- }
- uint8_t * output_buffer;
- uint32_t output_len;
- while (len > 0) {
- while (usb_transmitting) {}
- output_buffer = (uint8_t *) buffer;
- output_len = len;
- // Use our own cache in two different cases:
- // * When we're at the end of a transmission and we'll return before
- // the given buffer is actually transferred to the USB device.
- // * When our given buffer isn't aligned on word boundaries.
- if (output_len <= CDC_BULKIN_SIZE || ((uint32_t) buffer) % 4 != 0) {
- output_buffer = cdc_output_buffer;
- output_len = output_len > CDC_BULKIN_SIZE ? CDC_BULKIN_SIZE : output_len;
- memcpy(cdc_output_buffer, buffer, output_len);
- } else {
- output_len = CDC_BULKIN_SIZE;
- }
- usb_transmitting = true;
- cdcdf_acm_write(output_buffer, output_len);
- buffer += output_len * sizeof(char);
- len -= output_len;
- }
-}
-
-bool usb_connected(void) {
- return cdc_enabled();
-}
-
-// Poll for input if keyboard interrupts are enabled,
-// so that we can check for the interrupt char. read_complete() does the checking.
-// also make sure we have enough room in the local buffer
-void usb_cdc_background() {
- //
- if (mp_interrupt_char != -1 && cdc_enabled() && !pending_read && (usb_rx_count < USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE)) {
- start_read();
- }
-}
diff --git a/ports/atmel-samd/usb_mass_storage.c b/ports/atmel-samd/usb_mass_storage.c
deleted file mode 100644
index 9b6715158..000000000
--- a/ports/atmel-samd/usb_mass_storage.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 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 <string.h>
-
-#include "usb_mass_storage.h"
-#include "supervisor/shared/autoreload.h"
-
-#include "hal/utils/include/err_codes.h"
-#include "hal/utils/include/utils.h"
-#include "usb/class/msc/device/mscdf.h"
-
-#include "extmod/vfs.h"
-#include "extmod/vfs_fat.h"
-#include "lib/oofatfs/ff.h"
-#include "lib/oofatfs/diskio.h"
-#include "lib/oofatfs/ffconf.h"
-#include "py/mpconfig.h"
-#include "py/mphal.h"
-#include "py/mpstate.h"
-#include "py/misc.h"
-
-// The root FS is always at the end of the list.
-static fs_user_mount_t* get_vfs(int lun) {
- // TODO(tannewt): Return the mount which matches the lun where 0 is the end
- // and is counted in reverse.
- if (lun > 0) {
- return NULL;
- }
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- if (current_mount == NULL) {
- return NULL;
- }
- while (current_mount->next != NULL) {
- current_mount = current_mount->next;
- }
- return current_mount->obj;
-}
-
-/* Inquiry Information */
-// This is designed to handle the common case where we have an internal file
-// system and an optional SD card.
-COMPILER_ALIGNED(4) static uint8_t inquiry_info[2][36];
-
-/* Capacities of Disk */
-COMPILER_ALIGNED(4) static uint8_t format_capa[2][8];
-
-/**
- * \brief Eject Disk
- * \param[in] lun logic unit number
- * \return Operation status.
- */
-int32_t usb_msc_disk_eject(uint8_t lun) {
- if (lun > 1) {
- return ERR_NOT_FOUND;
- }
- fs_user_mount_t* current_mount = get_vfs(lun);
- // Return ERR_NOT_READY if not ready, otherwise ERR_NONE.
- if (current_mount == NULL) {
- return ERR_NOT_FOUND;
- }
- // TODO(tannewt): Should we flush here?
- return ERR_NONE;
-}
-
-/**
- * \brief Inquiry whether Disk is writable. ERR_DENIED if it is not writable.
- * ERR_NONE if it is. ERR_NOT_FOUND if its missing.
- * \param[in] lun logic unit number
- * \return Operation status.
- */
-int32_t usb_msc_disk_is_writable(uint8_t lun) {
- if (lun > 1) {
- return ERR_NOT_FOUND;
- }
-
- fs_user_mount_t* vfs = get_vfs(lun);
- if (vfs == NULL) {
- return ERR_NOT_FOUND;
- }
- if (vfs->writeblocks[0] == MP_OBJ_NULL ||
- (vfs->flags & FSUSER_USB_WRITABLE) == 0) {
- return ERR_DENIED;
- }
- return ERR_NONE;
-}
-
-/**
- * \brief Inquiry whether Disk is ready
- * \param[in] lun logic unit number
- * \return Operation status.
- */
-int32_t usb_msc_disk_is_ready(uint8_t lun) {
- if (lun > 1) {
- return ERR_NOT_FOUND;
- }
-
- fs_user_mount_t* current_mount = get_vfs(lun);
- if (current_mount == NULL) {
- return ERR_NOT_FOUND;
- }
- return ERR_NONE;
-}
-
-/**
- * \brief Callback invoked when inquiry data command received
- * \param[in] lun logic unit number
- * \return Operation status.
- */
-uint8_t *usb_msc_inquiry_info(uint8_t lun) {
- if (lun > 1) {
- return NULL;
- } else {
- for (uint8_t i = 0; i < 36; i++) {
- inquiry_info[lun][i] = 0;
- }
- inquiry_info[lun][0] = SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS;
- // connected, direct access
- inquiry_info[lun][1] = SCSI_INQ_RMB; // removable medium
- inquiry_info[lun][2] = SCSI_INQ_VER_SPC; // SBC version of SCSI primary commands
- inquiry_info[lun][3] = SCSI_INQ_RSP_SPC2;// SPC-2 response format
- inquiry_info[lun][4] = 31; // 31 bytes following
- return &inquiry_info[lun][0];
- }
-}
-
-/**
- * \brief Callback invoked when read format capacities command received
- * \param[in] lun logic unit number
- */
-uint8_t *usb_msc_get_capacity(uint8_t lun) {
- if (lun > 1) {
- return NULL;
- } else {
- fs_user_mount_t * vfs = get_vfs(lun);
- uint32_t last_valid_sector = 0;
- uint32_t sector_size = 0;
- if (vfs == NULL ||
- disk_ioctl(vfs, GET_SECTOR_COUNT, &last_valid_sector) != RES_OK ||
- disk_ioctl(vfs, GET_SECTOR_SIZE, &sector_size) != RES_OK) {
- return NULL;
- }
- // Subtract one from the sector count to get the last valid sector.
- last_valid_sector--;
-
- format_capa[lun][0] = (uint8_t)(last_valid_sector >> 24);
- format_capa[lun][1] = (uint8_t)(last_valid_sector >> 16);
- format_capa[lun][2] = (uint8_t)(last_valid_sector >> 8);
- format_capa[lun][3] = (uint8_t)(last_valid_sector >> 0);
- format_capa[lun][4] = (uint8_t)(sector_size >> 24);
- format_capa[lun][5] = (uint8_t)(sector_size >> 16);
- format_capa[lun][6] = (uint8_t)(sector_size >> 8);
- format_capa[lun][7] = (uint8_t)(sector_size >> 0);
-
- // 8 byte response. First 4 bytes are last block address. Second 4
- // bytes are sector size.
- return &format_capa[lun][0];
- }
-}
-
-// USB transfer state.
-volatile bool usb_busy;
-volatile bool active_read;
-volatile bool active_write;
-volatile uint8_t active_lun;
-volatile uint32_t active_addr;
-volatile uint32_t active_nblocks;
-volatile bool sector_loaded;
-COMPILER_ALIGNED(4) uint8_t sector_buffer[512];
-
-/**
- * \brief Callback invoked when a new read blocks command received
- * \param[in] lun logic unit number
- * \param[in] addr start address of disk to be read
- * \param[in] nblocks block amount to be read
- * \return Operation status.
- */
-int32_t usb_msc_new_read(uint8_t lun, uint32_t addr, uint32_t nblocks) {
- if (lun > 1) {
- return ERR_NOT_FOUND;
- }
-
- // Store transfer info so we can service it in the "background".
- active_lun = lun;
- active_addr = addr;
- active_nblocks = nblocks;
- active_read = true;
-
- return ERR_NONE;
-}
-
-/**
- * \brief Callback invoked when a new write blocks command received
- * \param[in] lun logic unit number
- * \param[in] addr start address of disk to be written
- * \param[in] nblocks block amount to be written
- * \return Operation status.
- */
-int32_t usb_msc_new_write(uint8_t lun, uint32_t addr, uint32_t nblocks) {
- if (lun > 1) {
- return ERR_NOT_FOUND;
- }
-
- fs_user_mount_t * vfs = get_vfs(lun);
- // This is used to determine the writeability of the disk from USB.
- if (vfs == NULL) {
- return ERR_NOT_FOUND;
- }
- if (vfs->writeblocks[0] == MP_OBJ_NULL ||
- (vfs->flags & FSUSER_USB_WRITABLE) == 0) {
- return ERR_DENIED;
- }
-
- // Store transfer info so we can service it in the "background".
- active_lun = lun;
- active_addr = addr;
- active_nblocks = nblocks;
- active_write = true;
- sector_loaded = false;
-
- // Return ERR_DENIED when the file system is read-only to the USB host.
-
- return ERR_NONE;
-}
-
-/**
- * \brief Callback invoked when a blocks transfer is done
- * \param[in] lun logic unit number
- * \return Operation status.
- */
-int32_t usb_msc_xfer_done(uint8_t lun) {
- if (lun > 1) {
- return ERR_DENIED;
- }
-
- CRITICAL_SECTION_ENTER();
- if (active_read) {
- active_addr += 1;
- active_nblocks--;
- if (active_nblocks == 0) {
- active_read = false;
- }
- }
-
- if (active_write) {
- sector_loaded = true;
- }
- usb_busy = false;
- CRITICAL_SECTION_LEAVE();
-
- return ERR_NONE;
-}
-
-// The start_read callback begins a read transaction which we accept
-// but delay our response until the "main thread" calls
-// usb_msc_background. Once it does, we read immediately from the
-// drive into our cache and trigger the USB DMA to output the
-// sector. Once the sector is transmitted, xfer_done will be called.
-void usb_msc_background(void) {
- // Check USB busy first because we never want to queue another transfer if it is. Checking
- // active_read or active_write first leaves the possibility that they are true, an xfer done
- // interrupt occurs (setting them false), turning off usb_busy and causing us to queue a
- // spurious transfer.
- if (usb_busy) {
- return;
- }
- if (active_read) {
- fs_user_mount_t * vfs = get_vfs(active_lun);
- disk_read(vfs, sector_buffer, active_addr, 1);
- CRITICAL_SECTION_ENTER();
- int32_t result = mscdf_xfer_blocks(true, sector_buffer, 1);
- usb_busy = result == ERR_NONE;
- CRITICAL_SECTION_LEAVE();
- }
- if (active_write) {
- if (sector_loaded) {
- fs_user_mount_t * vfs = get_vfs(active_lun);
- disk_write(vfs, sector_buffer, active_addr, 1);
- // Since by getting here we assume the mount is read-only to
- // MicroPython let's update the cached FatFs sector if it's the one
- // we just wrote.
- #if _MAX_SS != _MIN_SS
- if (vfs->ssize == FILESYSTEM_BLOCK_SIZE) {
- #else
- // The compiler can optimize this away.
- if (_MAX_SS == FILESYSTEM_BLOCK_SIZE) {
- #endif
- if (active_addr == vfs->fatfs.winsect && active_addr > 0) {
- memcpy(vfs->fatfs.win,
- sector_buffer,
- FILESYSTEM_BLOCK_SIZE);
- }
- }
- sector_loaded = false;
- active_addr += 1;
- active_nblocks--;
- }
- // Load more blocks from USB if they are needed.
- if (active_nblocks > 0) {
- // Turn off interrupts because with them on,
- // usb_msc_xfer_done could be called before we update
- // usb_busy. If that happened, we'd overwrite the fact that
- // the transfer actually already finished.
- CRITICAL_SECTION_ENTER();
- int32_t result = mscdf_xfer_blocks(false, sector_buffer, 1);
- usb_busy = result == ERR_NONE;
- CRITICAL_SECTION_LEAVE();
- } else {
- mscdf_xfer_blocks(false, NULL, 0);
- active_write = false;
- // This write is complete, start the autoreload clock.
- autoreload_start();
- }
- }
-}
diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile
index 3b6cc1fb4..03d5a65cb 100644
--- a/ports/esp8266/Makefile
+++ b/ports/esp8266/Makefile
@@ -119,7 +119,6 @@ SRC_COMMON_HAL = \
multiterminal/__init__.c \
neopixel_write/__init__.c \
os/__init__.c \
- storage/__init__.c \
time/__init__.c \
board/__init__.c
@@ -147,7 +146,6 @@ SRC_SHARED_MODULE = \
multiterminal/__init__.c \
os/__init__.c \
random/__init__.c \
- storage/__init__.c \
struct/__init__.c
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h
index eca3f525d..435f2c5cd 100644
--- a/ports/esp8266/mpconfigport.h
+++ b/ports/esp8266/mpconfigport.h
@@ -162,7 +162,6 @@ extern const struct _mp_obj_module_t esp_module;
extern const struct _mp_obj_module_t network_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t random_module;
-extern const struct _mp_obj_module_t storage_module;
extern const struct _mp_obj_module_t struct_module;
extern const struct _mp_obj_module_t mp_module_lwip;
extern const struct _mp_obj_module_t mp_module_machine;
@@ -194,7 +193,6 @@ extern const struct _mp_obj_module_t neopixel_write_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
- { MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index 25ddebc57..8d0d6d000 100755
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -29,6 +29,10 @@ FROZEN_MPY_DIR = freeze
# include py core make definitions
include ../../py/py.mk
+ifneq ($(MCU_SUB_VARIANT),nrf52840)
+USB = FALSE
+endif
+
include $(TOP)/supervisor/supervisor.mk
FATFS_DIR = lib/oofatfs
@@ -51,7 +55,7 @@ INC += -I./bluetooth
INC += -I./peripherals
INC += -I../../lib/mp-readline
INC += -I../../lib/tinyusb/src
-INC += -I./usb
+INC += -I../../supervisor/shared/usb
NRF_DEFINES += -DCONFIG_GPIO_AS_PINRESET
@@ -68,6 +72,9 @@ LDFLAGS += -Xlinker -Map=$(@:.elf=.map)
LDFLAGS += -mthumb -mabi=aapcs -T $(LD_FILE) -L boards/
LDFLAGS += -Wl,--gc-sections
+# TinyUSB defines
+CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096
+
#Debugging/Optimization
ifeq ($(DEBUG), 1)
#ASMFLAGS += -g -gtabs+
@@ -94,10 +101,16 @@ SRC_NRFX = $(addprefix nrfx/,\
drivers/src/nrfx_uarte.c \
)
+ifdef EXTERNAL_FLASH_DEVICES
+ ifeq ($(QSPI_FLASH_FILESYSTEM),1)
+ SRC_NRFX += nrfx/drivers/src/nrfx_qspi.c
+ endif
+endif
+
+
SRC_C += \
background.c \
fatfs_port.c \
- internal_flash.c \
mphalport.c \
tick.c \
board_busses.c \
@@ -147,7 +160,6 @@ SRC_COMMON_HAL += \
pulseio/PulseIn.c \
pulseio/PulseOut.c \
pulseio/__init__.c \
- storage/__init__.c \
supervisor/Runtime.c \
supervisor/__init__.c \
time/__init__.c \
@@ -185,14 +197,9 @@ SRC_BINDINGS_ENUMS += \
bleio/UUIDType.c
endif
-SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
- $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
- $(addprefix common-hal/, $(SRC_COMMON_HAL))
-
SRC_SHARED_MODULE = \
os/__init__.c \
random/__init__.c \
- storage/__init__.c \
struct/__init__.c \
gamepad/__init__.c \
gamepad/GamePad.c \
@@ -201,44 +208,36 @@ SRC_SHARED_MODULE = \
bitbangio/OneWire.c \
bitbangio/SPI.c \
busio/OneWire.c \
+ storage/__init__.c
# uheap/__init__.c \
ustack/__init__.c
-SRC_SHARED_BINDINGS = \
- struct/__init__.c \
- gamepad/__init__.c \
- gamepad/GamePad.c \
- bitbangio/__init__.c \
- bitbangio/I2C.c \
- bitbangio/SPI.c \
- bitbangio/OneWire.c \
- random/__init__.c \
-
# USB source files for nrf52840
ifeq ($(MCU_SUB_VARIANT),nrf52840)
SRC_C += \
- usb/usb.c \
- usb/usb_msc_flash.c \
- usb/usb_desc.c \
lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c \
lib/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c \
lib/tinyusb/src/common/tusb_fifo.c \
+ lib/tinyusb/src/device/control.c \
lib/tinyusb/src/device/usbd.c \
lib/tinyusb/src/class/msc/msc_device.c \
lib/tinyusb/src/class/cdc/cdc_device.c \
lib/tinyusb/src/class/hid/hid_device.c \
lib/tinyusb/src/tusb.c \
-SRC_COMMON_HAL += \
+SRC_SHARED_MODULE += \
usb_hid/__init__.c \
usb_hid/Device.c \
endif
+SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
+ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
+ $(addprefix common-hal/, $(SRC_COMMON_HAL))
-SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_BINDINGS)) \
+SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE))
SRC_S = supervisor/cpu.s
@@ -346,9 +345,10 @@ dfu-gen: $(BUILD)/dfu-package.zip
$(BUILD)/dfu-package.zip: $(BUILD)/$(OUTPUT_FILENAME).hex
$(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip
+# You must have $^ here because it deduplicates entries in $(OBJ)
$(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ)
$(ECHO) "LINK $@"
- $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) -Wl,--start-group $(LIBS) -Wl,--end-group
+ $(Q)$(CC) $(LDFLAGS) -o $@ $^ -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@
# List of sources for qstr extraction
diff --git a/ports/nrf/README.md b/ports/nrf/README.md
index 4bd865400..34e58cb78 100644
--- a/ports/nrf/README.md
+++ b/ports/nrf/README.md
@@ -61,7 +61,7 @@ To build and flash issue the following command inside the ports/nrf/ folder:
First prepare the bluetooth folder by downloading Bluetooth LE stacks and headers:
- ./drivers/bluetooth/download_ble_stack.sh
+ ./bluetooth/download_ble_stack.sh
If the Bluetooth stacks has been downloaded, compile the target with the following command:
diff --git a/ports/nrf/background.c b/ports/nrf/background.c
index d19604f68..f614b6bd0 100644
--- a/ports/nrf/background.c
+++ b/ports/nrf/background.c
@@ -24,11 +24,12 @@
* THE SOFTWARE.
*/
-#include "tusb.h"
+#ifdef NRF52840
+#include "supervisor/usb.h"
+#endif
void run_background_tasks(void) {
-#ifdef NRF52840_XXAA
- tusb_task();
- tud_cdc_write_flush();
-#endif
+ #ifdef NRF52840
+ usb_background();
+ #endif
}
diff --git a/ports/nrf/board_busses.c b/ports/nrf/board_busses.c
index 91f0def6d..6d5cbd041 100644
--- a/ports/nrf/board_busses.c
+++ b/ports/nrf/board_busses.c
@@ -30,8 +30,8 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/translate.h"
-#include "mpconfigboard.h"
#include "nrf/pins.h"
+#include "py/mpconfig.h"
#include "py/runtime.h"
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
diff --git a/ports/nrf/boards/feather_nrf52840_express/board.c b/ports/nrf/boards/feather_nrf52840_express/board.c
index a6d050fce..4421970ee 100644
--- a/ports/nrf/boards/feather_nrf52840_express/board.c
+++ b/ports/nrf/boards/feather_nrf52840_express/board.c
@@ -25,10 +25,8 @@
*/
#include "boards/board.h"
-#include "usb.h"
void board_init(void) {
- usb_init();
}
bool board_requests_safe_mode(void) {
diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
index bd6d4b244..68914c626 100644
--- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
+++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
@@ -25,6 +25,8 @@
* THE SOFTWARE.
*/
+#include "nrfx/hal/nrf_gpio.h"
+
#define FEATHER52840
#define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express"
@@ -33,12 +35,12 @@
#define MICROPY_HW_NEOPIXEL (&pin_P0_13)
-#define MICROPY_QSPI_DATA0 (&pin_P1_09)
-#define MICROPY_QSPI_DATA1 (&pin_P0_11)
-#define MICROPY_QSPI_DATA2 (&pin_P0_12)
-#define MICROPY_QSPI_DATA3 (&pin_P0_14)
-#define MICROPY_QSPI_SCK (&pin_P0_08)
-#define MICROPY_QSPI_CS (&pin_P1_08)
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 9)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 11)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 12)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 14)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 8)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8)
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
@@ -49,14 +51,7 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-// TODO #include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-#define EXTERNAL_FLASH_DEVICES GD25Q16C
-
-#define EXTERNAL_FLASH_QSPI_DUAL
-
-// TODO include "external_flash/external_flash.h"
+#define EXTERNAL_FLASH_QSPI_DUAL (1)
#define BOARD_HAS_CRYSTAL 1
diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
index caf580ec4..f03109319 100644
--- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
+++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
@@ -1,3 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x802A
+USB_PRODUCT = "Feather nRF52840 Express"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52840
@@ -14,3 +19,7 @@ else
endif
NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q64C"
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c
index a6d050fce..4421970ee 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c
@@ -25,10 +25,8 @@
*/
#include "boards/board.h"
-#include "usb.h"
void board_init(void) {
- usb_init();
}
bool board_requests_safe_mode(void) {
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h
index b33fb2dd6..40b6487ec 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h
@@ -25,18 +25,20 @@
* THE SOFTWARE.
*/
+#include "nrfx/hal/nrf_gpio.h"
+
#define MAKERDIARYNRF52840MDK
#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDK"
-#define MICROPY_QSPI_DATA0 (&pin_P1_05)
-#define MICROPY_QSPI_DATA1 (&pin_P1_04)
-#define MICROPY_QSPI_DATA2 (&pin_P1_02)
-#define MICROPY_QSPI_DATA3 (&pin_P1_01)
-#define MICROPY_QSPI_SCK (&pin_P1_03)
-#define MICROPY_QSPI_CS (&pin_P1_06)
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 5)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 4)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 2)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 1)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 3)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8)
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
@@ -47,17 +49,6 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-// TODO #include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 1
-// Datasheet for when this is implemented:
-// http://www.mxic.com.tw/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf
-#define EXTERNAL_FLASH_DEVICES MX25R6435F
-
-#define EXTERNAL_FLASH_QSPI_DUAL
-
-// TODO include "external_flash/external_flash.h"
-
#define BOARD_HAS_CRYSTAL 0
#define DEFAULT_UART_BUS_RX (&pin_P0_19)
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk
index caf580ec4..84dff0bc4 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk
@@ -1,3 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x802A
+USB_PRODUCT = "nRF52840-MDK"
+USB_MANUFACTURER = "makerdiary"
+
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52840
@@ -14,3 +19,7 @@ else
endif
NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "MX25R6435F"
diff --git a/ports/nrf/boards/pca10056/board.c b/ports/nrf/boards/pca10056/board.c
index a6d050fce..4421970ee 100644
--- a/ports/nrf/boards/pca10056/board.c
+++ b/ports/nrf/boards/pca10056/board.c
@@ -25,10 +25,8 @@
*/
#include "boards/board.h"
-#include "usb.h"
void board_init(void) {
- usb_init();
}
bool board_requests_safe_mode(void) {
diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h
index 00a73005c..83c3f66c1 100644
--- a/ports/nrf/boards/pca10056/mpconfigboard.h
+++ b/ports/nrf/boards/pca10056/mpconfigboard.h
@@ -24,6 +24,8 @@
* THE SOFTWARE.
*/
+#include "nrfx/hal/nrf_gpio.h"
+
#define MICROPY_HW_BOARD_NAME "PCA10056 nRF52840-DK"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "nRF52840-DK"
@@ -40,3 +42,24 @@
#define DEFAULT_UART_BUS_RX (&pin_P1_01)
#define DEFAULT_UART_BUS_TX (&pin_P1_02)
+
+// Flash operation mode is determined by MICROPY_QSPI_DATAn pin configuration.
+// A pin config is valid if it is defined and its value is not 0xFF.
+// Quad mode: If all DATA0 --> DATA3 are valid
+// Dual mode: If DATA0 and DATA1 are valid while either DATA2 and/or DATA3 are invalid
+// Single mode: If only DATA0 is valid
+#ifdef QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17)
+#endif
+
+#ifdef SPI_FLASH_FILESYSTEM
+#define SPI_FLASH_MOSI_PIN &pin_P0_20
+#define SPI_FLASH_MISO_PIN &pin_P0_21
+#define SPI_FLASH_SCK_PIN &pin_P0_19
+#define SPI_FLASH_CS_PIN &pin_P0_17
+#endif
diff --git a/ports/nrf/boards/pca10056/mpconfigboard.mk b/ports/nrf/boards/pca10056/mpconfigboard.mk
index caf580ec4..49c708cff 100644
--- a/ports/nrf/boards/pca10056/mpconfigboard.mk
+++ b/ports/nrf/boards/pca10056/mpconfigboard.mk
@@ -1,3 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x802A
+USB_PRODUCT = "PCA10056"
+USB_MANUFACTURER = "Nordic Semiconductor"
+
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52840
@@ -14,3 +19,7 @@ else
endif
NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "MX25R6435F"
diff --git a/ports/nrf/boards/pca10059/board.c b/ports/nrf/boards/pca10059/board.c
index cbb4ef3b6..4421970ee 100644
--- a/ports/nrf/boards/pca10059/board.c
+++ b/ports/nrf/boards/pca10059/board.c
@@ -24,14 +24,9 @@
* THE SOFTWARE.
*/
-#include <string.h>
-#include <stdbool.h>
#include "boards/board.h"
-#include "nrfx.h"
-#include "usb.h"
void board_init(void) {
- usb_init();
}
bool board_requests_safe_mode(void) {
diff --git a/ports/nrf/boards/pca10059/mpconfigboard.mk b/ports/nrf/boards/pca10059/mpconfigboard.mk
index f399927fd..030c9a823 100644
--- a/ports/nrf/boards/pca10059/mpconfigboard.mk
+++ b/ports/nrf/boards/pca10059/mpconfigboard.mk
@@ -1,3 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x802A
+USB_PRODUCT = "PCA10059"
+USB_MANUFACTURER = "Nordic Semiconductor"
+
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52840
diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c
index f094b7f24..19bd4d1ba 100644
--- a/ports/nrf/common-hal/busio/SPI.c
+++ b/ports/nrf/common-hal/busio/SPI.c
@@ -59,12 +59,30 @@ STATIC spim_peripheral_t spim_peripherals[] = {
#endif
};
+STATIC bool never_reset[4];
+
void spi_reset(void) {
for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) {
+ if (never_reset[i]) {
+ continue;
+ }
nrf_spim_disable(spim_peripherals[i].spim.p_reg);
}
}
+void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
+ for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) {
+ if (self->spim_peripheral == &spim_peripherals[i]) {
+ never_reset[i] = true;
+
+ never_reset_pin_number(self->clock_pin_number);
+ never_reset_pin_number(self->MOSI_pin_number);
+ never_reset_pin_number(self->MISO_pin_number);
+ break;
+ }
+ }
+}
+
// Convert frequency to clock-speed-dependent value. Choose the next lower baudrate if in between
// available baudrates.
static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) {
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index b9e79381a..516a7747d 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -27,7 +27,7 @@
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/busio/UART.h"
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#include "py/gc.h"
#include "py/mperrno.h"
#include "py/runtime.h"
diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.c b/ports/nrf/common-hal/digitalio/DigitalInOut.c
index f05cf568f..0836962c6 100644
--- a/ports/nrf/common-hal/digitalio/DigitalInOut.c
+++ b/ports/nrf/common-hal/digitalio/DigitalInOut.c
@@ -30,6 +30,11 @@
#include "nrf_gpio.h"
+void common_hal_digitalio_digitalinout_never_reset(
+ digitalio_digitalinout_obj_t *self) {
+ never_reset_pin_number(self->pin->number);
+}
+
digitalinout_result_t common_hal_digitalio_digitalinout_construct(
digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) {
claim_pin(pin);
diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c
index 7a069eeda..0522bfef3 100644
--- a/ports/nrf/common-hal/microcontroller/Pin.c
+++ b/ports/nrf/common-hal/microcontroller/Pin.c
@@ -45,13 +45,18 @@ bool speaker_enable_in_use;
// Bit mask of claimed pins on each of up to two ports. nrf52832 has one port; nrf52840 has two.
STATIC uint32_t claimed_pins[GPIO_COUNT];
+STATIC uint32_t never_reset_pins[GPIO_COUNT];
void reset_all_pins(void) {
+ return;
for (size_t i = 0; i < GPIO_COUNT; i++) {
- claimed_pins[i] = 0;
+ claimed_pins[i] = never_reset_pins[i];
}
for (uint32_t pin = 0; pin < NUMBER_OF_PINS; ++pin) {
+ if (!(never_reset_pins[nrf_pin_port(pin)] & (1 << nrf_relative_pin_number(pin)))) {
+ continue;
+ }
nrf_gpio_cfg_default(pin);
}
@@ -72,6 +77,7 @@ void reset_all_pins(void) {
// Mark pin as free and return it to a quiescent state.
void reset_pin_number(uint8_t pin_number) {
+ return;
if (pin_number == NO_PIN) {
return;
}
@@ -108,6 +114,11 @@ void reset_pin_number(uint8_t pin_number) {
#endif
}
+
+void never_reset_pin_number(uint8_t pin_number) {
+ never_reset_pins[nrf_pin_port(pin_number)] |= 1 << nrf_relative_pin_number(pin_number);
+}
+
void claim_pin(const mcu_pin_obj_t* pin) {
// Set bit in claimed_pins bitmask.
claimed_pins[nrf_pin_port(pin->number)] |= 1 << nrf_relative_pin_number(pin->number);
diff --git a/ports/nrf/common-hal/microcontroller/Pin.h b/ports/nrf/common-hal/microcontroller/Pin.h
index 2cdf440b5..61be8bc35 100644
--- a/ports/nrf/common-hal/microcontroller/Pin.h
+++ b/ports/nrf/common-hal/microcontroller/Pin.h
@@ -44,6 +44,7 @@ void reset_all_pins(void);
// need to store a full pointer.
void reset_pin_number(uint8_t pin);
void claim_pin(const mcu_pin_obj_t* pin);
+void never_reset_pin_number(uint8_t pin_number);
// Lower 5 bits of a pin number are the pin number in a port.
// upper bits (just one bit for current chips) is port number.
diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c
index 2ce3e8bf5..e4d9439c9 100644
--- a/ports/nrf/common-hal/microcontroller/Processor.c
+++ b/ports/nrf/common-hal/microcontroller/Processor.c
@@ -72,12 +72,7 @@ uint32_t common_hal_mcu_processor_get_frequency(void) {
}
void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
-
- uint32_t* id_addresses[2] = {(uint32_t *) 0x060, (uint32_t *) 0x064};
-
for (int i=0; i<2; i++) {
- for (int k=0; k<4; k++) {
- raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff;
- }
+ ((uint32_t*) raw_id)[i] = NRF_FICR->DEVICEID[i];
}
}
diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c
index 950cc877d..3d6d266af 100644
--- a/ports/nrf/common-hal/pulseio/PulseIn.c
+++ b/ports/nrf/common-hal/pulseio/PulseIn.c
@@ -28,7 +28,7 @@
#include <stdint.h>
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#include "py/gc.h"
#include "py/runtime.h"
diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c
index 044c4d3a8..be5deca9f 100644
--- a/ports/nrf/common-hal/pulseio/PulseOut.c
+++ b/ports/nrf/common-hal/pulseio/PulseOut.c
@@ -28,7 +28,7 @@
#include <stdint.h>
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#include "nrf/pins.h"
#include "nrf/timers.h"
#include "py/gc.h"
diff --git a/ports/nrf/common-hal/usb_hid/Device.h b/ports/nrf/common-hal/usb_hid/Device.h
deleted file mode 100644
index 612423715..000000000
--- a/ports/nrf/common-hal/usb_hid/Device.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 hathach 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 COMMON_HAL_USB_HID_DEVICE_H
-#define COMMON_HAL_USB_HID_DEVICE_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "py/obj.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-// 1 to enable device, 0 to disable
-#define USB_HID_DEVICE_KEYBOARD 1
-#define USB_HID_DEVICE_MOUSE 1
-#define USB_HID_DEVICE_CONSUMER 1
-#define USB_HID_DEVICE_SYS_CONTROL 1
-#define USB_HID_DEVICE_GAMEPAD 1
-#define USB_HID_DEVICE_DIGITIZER 0 // not supported yet
-
-enum {
- USB_HID_REPORT_ID_UNUSED = 0,
-
-#if USB_HID_DEVICE_KEYBOARD
- USB_HID_REPORT_ID_KEYBOARD,
-#endif
-
-#if USB_HID_DEVICE_MOUSE
- USB_HID_REPORT_ID_MOUSE,
-#endif
-
-#if USB_HID_DEVICE_CONSUMER
- USB_HID_REPORT_ID_CONSUMER,
-#endif
-
-#if USB_HID_DEVICE_SYS_CONTROL
- USB_HID_REPORT_ID_SYS_CONTROL,
-#endif
-
-#if USB_HID_DEVICE_GAMEPAD
- USB_HID_REPORT_ID_GAMEPAD,
-#endif
-
-#if USB_HID_DEVICE_DIGITIZER
- USB_HID_REPORT_ID_DIGITIZER,
-#endif
-};
-
-#define USB_HID_NUM_DEVICES (USB_HID_DEVICE_KEYBOARD + USB_HID_DEVICE_MOUSE + USB_HID_DEVICE_CONSUMER + \
- USB_HID_DEVICE_SYS_CONTROL + USB_HID_DEVICE_GAMEPAD + USB_HID_DEVICE_DIGITIZER )
-
-typedef struct {
- mp_obj_base_t base;
- uint8_t* report_buffer;
- uint8_t report_id;
- uint8_t report_length;
- uint8_t usage_page;
- uint8_t usage;
-} usb_hid_device_obj_t;
-
-
-extern usb_hid_device_obj_t usb_hid_devices[];
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* COMMON_HAL_USB_HID_DEVICE_H */
diff --git a/ports/nrf/internal_flash.c b/ports/nrf/internal_flash.c
deleted file mode 100644
index 812ef4d3f..000000000
--- a/ports/nrf/internal_flash.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "internal_flash.h"
-
-#include <stdint.h>
-#include <string.h>
-
-#include "extmod/vfs.h"
-#include "extmod/vfs_fat.h"
-#include "py/mphal.h"
-#include "py/obj.h"
-#include "py/runtime.h"
-#include "lib/oofatfs/ff.h"
-#include "supervisor/shared/rgb_led_status.h"
-
-#include "nrf_nvmc.h"
-
-#ifdef BLUETOOTH_SD
-#include "nrf_sdm.h"
-#endif
-
-// defined in linker
-extern uint32_t __fatfs_flash_start_addr[];
-extern uint32_t __fatfs_flash_length[];
-
-#define NO_CACHE 0xffffffff
-#define FL_PAGE_SZ 4096
-
-uint8_t _flash_cache[FL_PAGE_SZ] __attribute__((aligned(4)));
-uint32_t _flash_page_addr = NO_CACHE;
-
-
-/*------------------------------------------------------------------*/
-/* Internal Flash API
- *------------------------------------------------------------------*/
-static inline uint32_t lba2addr(uint32_t block) {
- return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE;
-}
-
-void internal_flash_init(void) {
- // Activity LED for flash writes.
-#ifdef MICROPY_HW_LED_MSC
- struct port_config pin_conf;
- port_get_config_defaults(&pin_conf);
-
- pin_conf.direction = PORT_PIN_DIR_OUTPUT;
- port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf);
- port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
-#endif
-}
-
-uint32_t internal_flash_get_block_size(void) {
- return FILESYSTEM_BLOCK_SIZE;
-}
-
-uint32_t internal_flash_get_block_count(void) {
- return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ;
-}
-
-// TODO support flashing with SD enabled
-void internal_flash_flush(void) {
- if (_flash_page_addr == NO_CACHE) return;
-
- // Skip if data is the same
- if (memcmp(_flash_cache, (void *)_flash_page_addr, FL_PAGE_SZ) != 0) {
-// _is_flashing = true;
- nrf_nvmc_page_erase(_flash_page_addr);
- nrf_nvmc_write_words(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t));
- }
-
- _flash_page_addr = NO_CACHE;
-}
-
-mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
- uint32_t src = lba2addr(block);
- memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks);
- return 0; // success
-}
-
-mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
-
-#ifdef MICROPY_HW_LED_MSC
- port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
-#endif
-
- while (num_blocks) {
- uint32_t const addr = lba2addr(lba);
- uint32_t const page_addr = addr & ~(FL_PAGE_SZ - 1);
-
- uint32_t count = 8 - (lba % 8); // up to page boundary
- count = MIN(num_blocks, count);
-
- if (page_addr != _flash_page_addr) {
- internal_flash_flush();
-
- // writing previous cached data, skip current data until flashing is done
- // tinyusb stack will invoke write_block() with the same parameters later on
- // if ( _is_flashing ) return;
-
- _flash_page_addr = page_addr;
- memcpy(_flash_cache, (void *)page_addr, FL_PAGE_SZ);
- }
-
- memcpy(_flash_cache + (addr & (FL_PAGE_SZ - 1)), src, count * FILESYSTEM_BLOCK_SIZE);
-
- // adjust for next run
- lba += count;
- src += count * FILESYSTEM_BLOCK_SIZE;
- num_blocks -= count;
- }
-
-#ifdef MICROPY_HW_LED_MSC
- port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
-#endif
-
- return 0; // success
-}
-
-/******************************************************************************/
-// MicroPython bindings
-//
-// Expose the flash as an object with the block protocol.
-
-// there is a singleton Flash object
-STATIC const mp_obj_base_t internal_flash_obj = {&internal_flash_type};
-
-STATIC mp_obj_t internal_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- // check arguments
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
-
- // return singleton object
- return (mp_obj_t)&internal_flash_obj;
-}
-
-STATIC mp_obj_t internal_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
- mp_uint_t ret = internal_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
- return MP_OBJ_NEW_SMALL_INT(ret);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_readblocks_obj, internal_flash_obj_readblocks);
-
-STATIC mp_obj_t internal_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
- mp_uint_t ret = internal_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
- return MP_OBJ_NEW_SMALL_INT(ret);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_writeblocks_obj, internal_flash_obj_writeblocks);
-
-STATIC mp_obj_t internal_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
- mp_int_t cmd = mp_obj_get_int(cmd_in);
- switch (cmd) {
- case BP_IOCTL_INIT: internal_flash_init(); return MP_OBJ_NEW_SMALL_INT(0);
- case BP_IOCTL_DEINIT: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly
- case BP_IOCTL_SYNC: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0);
- case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_count());
- case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_size());
- default: return mp_const_none;
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_ioctl_obj, internal_flash_obj_ioctl);
-
-STATIC const mp_rom_map_elem_t internal_flash_obj_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&internal_flash_obj_readblocks_obj) },
- { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&internal_flash_obj_writeblocks_obj) },
- { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&internal_flash_obj_ioctl_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(internal_flash_obj_locals_dict, internal_flash_obj_locals_dict_table);
-
-const mp_obj_type_t internal_flash_type = {
- { &mp_type_type },
- .name = MP_QSTR_InternalFlash,
- .make_new = internal_flash_obj_make_new,
- .locals_dict = (mp_obj_t)&internal_flash_obj_locals_dict,
-};
-
-/*------------------------------------------------------------------*/
-/* Flash API
- *------------------------------------------------------------------*/
-
-void flash_init_vfs(fs_user_mount_t *vfs) {
- vfs->base.type = &mp_fat_vfs_type;
- vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
- vfs->fatfs.drv = vfs;
-
-// vfs->fatfs.part = 1; // flash filesystem lives on first partition
- vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj;
- vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj;
- vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version
-
- vfs->writeblocks[0] = (mp_obj_t)&internal_flash_obj_writeblocks_obj;
- vfs->writeblocks[1] = (mp_obj_t)&internal_flash_obj;
- vfs->writeblocks[2] = (mp_obj_t)internal_flash_write_blocks; // native version
-
- vfs->u.ioctl[0] = (mp_obj_t)&internal_flash_obj_ioctl_obj;
- vfs->u.ioctl[1] = (mp_obj_t)&internal_flash_obj;
-}
-
-void flash_flush(void) {
- internal_flash_flush();
-}
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index 8b193fb59..c9c03427f 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -58,7 +58,7 @@
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
#define MICROPY_FATFS_USE_LABEL (1)
#define MICROPY_FATFS_RPATH (2)
-#define MICROPY_FATFS_MULTI_PARTITION (0)
+#define MICROPY_FATFS_MULTI_PARTITION (1)
#define MICROPY_FATFS_NUM_PERSISTENT (1)
//#define MICROPY_FATFS_MAX_SS (4096)
@@ -216,9 +216,12 @@ extern const struct _mp_obj_module_t bleio_module;
#define MP_STATE_PORT MP_STATE_VM
+#include "supervisor/flash_root_pointers.h"
+
#define MICROPY_PORT_ROOT_POINTERS \
const char *readline_hist[8]; \
mp_obj_t gamepad_singleton; \
+ FLASH_ROOT_POINTERS \
// We need to provide a declaration/definition of alloca()
#include <alloca.h>
diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk
index 17304b783..f43e29fce 100644
--- a/ports/nrf/mpconfigport.mk
+++ b/ports/nrf/mpconfigport.mk
@@ -5,3 +5,4 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
INTERNAL_LIBM = (1)
+USB_SERIAL_NUMBER_LENGTH = 16
diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c
index e9a8722c6..73f38bada 100644
--- a/ports/nrf/mphalport.c
+++ b/ports/nrf/mphalport.c
@@ -31,86 +31,6 @@
#include "py/mpstate.h"
#include "py/gc.h"
-#if (MICROPY_PY_BLE_NUS == 0)
-
-#if !defined( NRF52840_XXAA)
-int mp_hal_stdin_rx_chr(void) {
- uint8_t data;
- nrfx_uarte_rx(&serial_instance, &data, 1);
- return data;
-}
-
-bool mp_hal_stdin_any(void) {
- return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY);
-}
-
-void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
- if (len == 0) {
- return;
- }
-
- // EasyDMA can only access SRAM
- uint8_t * tx_buf = (uint8_t*) str;
- if ( !nrfx_is_in_ram(str) ) {
- tx_buf = (uint8_t *) gc_alloc(len, false, false);
- memcpy(tx_buf, str, len);
- }
-
- nrfx_uarte_tx(&serial_instance, tx_buf, len);
-
- if ( !nrfx_is_in_ram(str) ) {
- gc_free(tx_buf);
- }
-}
-
-#else
-
-#include "tusb.h"
-
-int mp_hal_stdin_rx_chr(void) {
- for (;;) {
- #ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
- #endif
- // if (reload_requested) {
- // return CHAR_CTRL_D;
- // }
-
- if (tud_cdc_available()) {
- #ifdef MICROPY_HW_LED_RX
- gpio_toggle_pin_level(MICROPY_HW_LED_RX);
- #endif
- return tud_cdc_read_char();
- }
- }
-
- return 0;
-}
-
-bool mp_hal_stdin_any(void) {
- return tud_cdc_available() > 0;
-}
-
-void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
-
- #ifdef MICROPY_HW_LED_TX
- gpio_toggle_pin_level(MICROPY_HW_LED_TX);
- #endif
-
- #ifdef CIRCUITPY_BOOT_OUTPUT_FILE
- if (boot_output_file != NULL) {
- UINT bytes_written = 0;
- f_write(boot_output_file, str, len, &bytes_written);
- }
- #endif
-
- tud_cdc_write(str, len);
-}
-
-#endif // USB
-
-#endif // MICROPY_PY_BLE_NUS
-
/*------------------------------------------------------------------*/
/* delay
*------------------------------------------------------------------*/
@@ -129,4 +49,3 @@ void mp_hal_delay_ms(mp_uint_t delay) {
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
-
diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h
index 69b8e6a0c..1d3085e2b 100644
--- a/ports/nrf/nrfx_config.h
+++ b/ports/nrf/nrfx_config.h
@@ -37,6 +37,9 @@
#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 7
#define NRFX_SPIM_MISO_PULL_CFG 1
+// QSPI
+#define NRFX_QSPI_ENABLED 1
+
// TWI aka. I2C; enable TWIM0 and TWIM1 (no conflict with SPIM choices)
#define NRFX_TWIM_ENABLED 1
#define NRFX_TWIM0_ENABLED 1
diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c
index 0027d526f..7f7a003d3 100644
--- a/ports/nrf/peripherals/nrf/timers.c
+++ b/ports/nrf/peripherals/nrf/timers.c
@@ -31,7 +31,7 @@
#include "nrfx.h"
#include "nrfx_timer.h"
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#include "py/runtime.h"
STATIC nrfx_timer_t nrfx_timers[] = {
diff --git a/ports/nrf/supervisor/filesystem.c b/ports/nrf/supervisor/filesystem.c
deleted file mode 100644
index b6611417d..000000000
--- a/ports/nrf/supervisor/filesystem.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 "extmod/vfs_fat.h"
-#include "lib/oofatfs/ff.h"
-#include "lib/oofatfs/diskio.h"
-
-#include "py/mpstate.h"
-
-#include "internal_flash.h"
-
-static mp_vfs_mount_t _mp_vfs;
-static fs_user_mount_t _internal_vfs;
-
-
-void filesystem_init(bool create_allowed, bool force_create) {
- // init the vfs object
- fs_user_mount_t *int_vfs = &_internal_vfs;
- int_vfs->flags = 0;
- flash_init_vfs(int_vfs);
-
- // try to mount the flash
- FRESULT res = f_mount(&int_vfs->fatfs);
-
- if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) {
- // no filesystem so create a fresh one
- uint8_t working_buf[_MAX_SS];
- res = f_mkfs(&int_vfs->fatfs, FM_FAT | FM_SFD, 4096, working_buf, sizeof(working_buf));
- // Flush the new file system to make sure its repaired immediately.
- flash_flush();
- if (res != FR_OK) {
- return;
- }
-
- // set label
- f_setlabel(&int_vfs->fatfs, "CIRCUITPY");
-
- // create lib folder
- f_mkdir(&int_vfs->fatfs, "/lib");
-
- flash_flush();
- } else if (res != FR_OK) {
- return;
- }
-
- mp_vfs_mount_t *mp_vfs = &_mp_vfs;
- mp_vfs->str = "/";
- mp_vfs->len = 1;
- mp_vfs->obj = MP_OBJ_FROM_PTR(int_vfs);
- mp_vfs->next = NULL;
- MP_STATE_VM(vfs_mount_table) = mp_vfs;
-
- // The current directory is used as the boot up directory.
- // It is set to the internal flash filesystem by default.
- MP_STATE_PORT(vfs_cur) = mp_vfs;
-}
-
-void filesystem_flush(void) {
- flash_flush();
-}
-
-void filesystem_writable_by_python(bool writable) {
- fs_user_mount_t *vfs = &_internal_vfs;
-
- if (writable) {
- vfs->flags |= FSUSER_USB_WRITABLE;
- } else {
- vfs->flags &= ~FSUSER_USB_WRITABLE;
- }
-}
-
-bool filesystem_present(void) {
- return true;
-}
diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c
new file mode 100644
index 000000000..a648afa17
--- /dev/null
+++ b/ports/nrf/supervisor/internal_flash.c
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "supervisor/flash.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
+#include "py/mphal.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+#include "lib/oofatfs/ff.h"
+
+#include "nrf_nvmc.h"
+
+#ifdef BLUETOOTH_SD
+#include "nrf_sdm.h"
+#endif
+
+// defined in linker
+extern uint32_t __fatfs_flash_start_addr[];
+extern uint32_t __fatfs_flash_length[];
+
+#define NO_CACHE 0xffffffff
+#define FL_PAGE_SZ 4096
+
+uint8_t _flash_cache[FL_PAGE_SZ] __attribute__((aligned(4)));
+uint32_t _flash_page_addr = NO_CACHE;
+
+
+/*------------------------------------------------------------------*/
+/* Internal Flash API
+ *------------------------------------------------------------------*/
+static inline uint32_t lba2addr(uint32_t block) {
+ return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE;
+}
+
+void supervisor_flash_init(void) {
+}
+
+uint32_t supervisor_flash_get_block_size(void) {
+ return FILESYSTEM_BLOCK_SIZE;
+}
+
+uint32_t supervisor_flash_get_block_count(void) {
+ return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ;
+}
+
+// TODO support flashing with SD enabled
+void supervisor_flash_flush(void) {
+ if (_flash_page_addr == NO_CACHE) return;
+
+ // Skip if data is the same
+ if (memcmp(_flash_cache, (void *)_flash_page_addr, FL_PAGE_SZ) != 0) {
+// _is_flashing = true;
+ nrf_nvmc_page_erase(_flash_page_addr);
+ nrf_nvmc_write_words(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t));
+ }
+
+ _flash_page_addr = NO_CACHE;
+}
+
+mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
+ uint32_t src = lba2addr(block);
+ memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks);
+ return 0; // success
+}
+
+mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
+ while (num_blocks) {
+ uint32_t const addr = lba2addr(lba);
+ uint32_t const page_addr = addr & ~(FL_PAGE_SZ - 1);
+
+ uint32_t count = 8 - (lba % 8); // up to page boundary
+ count = MIN(num_blocks, count);
+
+ if (page_addr != _flash_page_addr) {
+ supervisor_flash_flush();
+
+ // writing previous cached data, skip current data until flashing is done
+ // tinyusb stack will invoke write_block() with the same parameters later on
+ // if ( _is_flashing ) return;
+
+ _flash_page_addr = page_addr;
+ memcpy(_flash_cache, (void *)page_addr, FL_PAGE_SZ);
+ }
+
+ memcpy(_flash_cache + (addr & (FL_PAGE_SZ - 1)), src, count * FILESYSTEM_BLOCK_SIZE);
+
+ // adjust for next run
+ lba += count;
+ src += count * FILESYSTEM_BLOCK_SIZE;
+ num_blocks -= count;
+ }
+
+ return 0; // success
+}
diff --git a/ports/nrf/internal_flash.h b/ports/nrf/supervisor/internal_flash.h
index 3811815e2..adcb9bbc2 100644
--- a/ports/nrf/internal_flash.h
+++ b/ports/nrf/supervisor/internal_flash.h
@@ -29,7 +29,7 @@
#include <stdbool.h>
#include <stdint.h>
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#define FLASH_ROOT_POINTERS
@@ -39,21 +39,4 @@
#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms
#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2)
-void internal_flash_init(void);
-uint32_t internal_flash_get_block_size(void);
-uint32_t internal_flash_get_block_count(void);
-void internal_flash_irq_handler(void);
-void internal_flash_flush(void);
-
-// these return 0 on success, non-zero on error
-mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
-mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
-
-extern const struct _mp_obj_type_t internal_flash_type;
-
-struct _fs_user_mount_t;
-
-void flash_init_vfs(struct _fs_user_mount_t *vfs);
-void flash_flush(void);
-
#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H
diff --git a/ports/nrf/supervisor/internal_flash_root_pointers.h b/ports/nrf/supervisor/internal_flash_root_pointers.h
new file mode 100644
index 000000000..cc6074585
--- /dev/null
+++ b/ports/nrf/supervisor/internal_flash_root_pointers.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * 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_NRF_INTERNAL_FLASH_ROOT_POINTERS_H
+#define MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H
+
+#define FLASH_ROOT_POINTERS
+
+#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H
diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c
index f98b05f5a..fcb3ae55c 100644
--- a/ports/nrf/supervisor/port.c
+++ b/ports/nrf/supervisor/port.c
@@ -89,6 +89,13 @@ void reset_port(void) {
reset_all_pins();
}
+void reset_to_bootloader(void) {
+ enum { DFU_MAGIC_SERIAL = 0x4e };
+
+ NRF_POWER->GPREGRET = DFU_MAGIC_SERIAL;
+ NVIC_SystemReset();
+}
+
void HardFault_Handler(void)
{
diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c
new file mode 100644
index 000000000..24b06c420
--- /dev/null
+++ b/ports/nrf/supervisor/qspi_flash.c
@@ -0,0 +1,146 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach for Adafruit Industries
+ * Copyright (c) 2018 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/spi_flash_api.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "py/mpconfig.h" // for EXTERNAL_FLASH_QSPI_DUAL
+#include "nrfx_qspi.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+
+#include "supervisor/shared/external_flash/common_commands.h"
+#include "supervisor/shared/external_flash/qspi_flash.h"
+
+bool spi_flash_command(uint8_t command) {
+ nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ .opcode = 0,
+ .length = 0,
+ .io2_level = true,
+ .io3_level = true,
+ .wipwait = false,
+ .wren = false
+ };
+ cinstr_cfg.opcode = command;
+ cinstr_cfg.length = 1;
+ nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
+ return true;
+}
+
+bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) {
+ nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ .opcode = command,
+ .length = length + 1,
+ .io2_level = true,
+ .io3_level = true,
+ .wipwait = false,
+ .wren = false
+ };
+ nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response);
+ return true;
+}
+
+bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
+ nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ .opcode = command,
+ .length = length + 1,
+ .io2_level = true,
+ .io3_level = true,
+ .wipwait = false,
+ .wren = false // We do this manually.
+ };
+ nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL);
+ return true;
+}
+
+bool spi_flash_sector_command(uint8_t command, uint32_t address) {
+ if (command != CMD_SECTOR_ERASE) {
+ return false;
+ }
+ return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS;
+}
+
+bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
+ return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS;
+}
+
+bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
+ nrfx_qspi_read(data, length, address);
+ return true;
+}
+
+void spi_flash_init(void) {
+ // Init QSPI flash
+ nrfx_qspi_config_t qspi_cfg = {
+ .xip_offset = 0,
+ .pins = {
+ .sck_pin = MICROPY_QSPI_SCK,
+ .csn_pin = MICROPY_QSPI_CS,
+ .io0_pin = MICROPY_QSPI_DATA0,
+ .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED,
+ .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED,
+ .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED,
+
+ },
+ .prot_if = {
+ .readoc = NRF_QSPI_READOC_FASTREAD,
+ .writeoc = NRF_QSPI_WRITEOC_PP,
+ .addrmode = NRF_QSPI_ADDRMODE_24BIT,
+ .dpmconfig = false
+ },
+ .phy_if = {
+ .sck_freq = NRF_QSPI_FREQ_32MDIV16,
+ .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns
+ .spi_mode = NRF_QSPI_MODE_0,
+ .dpmen = false
+ },
+ .irq_priority = 7,
+ };
+
+#if EXTERNAL_FLASH_QSPI_DUAL
+ qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1;
+ qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ2O;
+ qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
+#else
+ qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1;
+ qspi_cfg.pins.io2_pin = MICROPY_QSPI_DATA2;
+ qspi_cfg.pins.io3_pin = MICROPY_QSPI_DATA3;
+ qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
+ qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO;
+#endif
+
+ // No callback for blocking API
+ nrfx_qspi_init(&qspi_cfg, NULL, NULL);
+}
+
+void spi_flash_init_device(const external_flash_device* device) {
+ check_quad_enable(device);
+
+ // TODO(tannewt): Adjust the speed for the found device.
+}
diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c
index c7744fd79..6fd89eb3e 100644
--- a/ports/nrf/supervisor/serial.c
+++ b/ports/nrf/supervisor/serial.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2017, 2018 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
@@ -26,9 +26,12 @@
#include "py/mphal.h"
+#include "supervisor/serial.h"
+
#if (MICROPY_PY_BLE_NUS == 1)
#include "ble_uart.h"
#else
+#include <string.h>
#include "nrf_gpio.h"
#include "nrfx_uarte.h"
#endif
@@ -89,39 +92,36 @@ bool serial_connected(void) {
}
char serial_read(void) {
- return (char) mp_hal_stdin_rx_chr();
+ uint8_t data;
+ nrfx_uarte_rx(&serial_instance, &data, 1);
+ return data;
}
bool serial_bytes_available(void) {
- return mp_hal_stdin_any();
+ return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY);
}
-void serial_write(const char *text) {
- mp_hal_stdout_tx_str(text);
-}
-
-#else
-
-#include "tusb.h"
-
-void serial_init(void) {
- // usb is already initialized in board_init()
+void serial_write(const char* text) {
+ serial_write_substring(text, strlen(text));
}
-bool serial_connected(void) {
- return tud_cdc_connected();
-}
+void serial_write_substring(const char *text, uint32_t len) {
+ if (len == 0) {
+ return;
+ }
-char serial_read(void) {
- return (char) tud_cdc_read_char();
-}
+ // EasyDMA can only access SRAM
+ uint8_t * tx_buf = (uint8_t*) text;
+ if ( !nrfx_is_in_ram(text) ) {
+ tx_buf = (uint8_t *) m_malloc(len, false);
+ memcpy(tx_buf, text, len);
+ }
-bool serial_bytes_available(void) {
- return tud_cdc_available() > 0;
-}
+ nrfx_uarte_tx(&serial_instance, tx_buf, len);
-void serial_write(const char* text) {
- tud_cdc_write(text, strlen(text));
+ if ( !nrfx_is_in_ram(text) ) {
+ m_free(tx_buf);
+ }
}
#endif
diff --git a/ports/nrf/supervisor/usb.c b/ports/nrf/supervisor/usb.c
new file mode 100644
index 000000000..a67c9311a
--- /dev/null
+++ b/ports/nrf/supervisor/usb.c
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach 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 "nrfx.h"
+#include "nrfx_power.h"
+#include "tick.h"
+#include "supervisor/usb.h"
+#include "lib/utils/interrupt_char.h"
+#include "lib/mp-readline/readline.h"
+
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_sdm.h"
+#include "nrf_soc.h"
+#endif
+
+/* tinyusb function that handles power event (detected, ready, removed)
+ * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
+ */
+extern void tusb_hal_nrf_power_event(uint32_t event);
+
+void init_usb_hardware(void) {
+
+ // USB power may already be ready at this time -> no event generated
+ // We need to invoke the handler based on the status initially
+ uint32_t usb_reg;
+
+#ifdef SOFTDEVICE_PRESENT
+ uint8_t sd_en = false;
+ (void) sd_softdevice_is_enabled(&sd_en);
+
+ if ( sd_en ) {
+ sd_power_usbdetected_enable(true);
+ sd_power_usbpwrrdy_enable(true);
+ sd_power_usbremoved_enable(true);
+
+ sd_power_usbregstatus_get(&usb_reg);
+ }else
+#endif
+ {
+ // Power module init
+ const nrfx_power_config_t pwr_cfg = { 0 };
+ nrfx_power_init(&pwr_cfg);
+
+ // Register tusb function as USB power handler
+ const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
+ nrfx_power_usbevt_init(&config);
+
+ nrfx_power_usbevt_enable();
+
+ usb_reg = NRF_POWER->USBREGSTATUS;
+ }
+
+ if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) {
+ tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
+ }
+
+ if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) {
+ tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
+ }
+}
diff --git a/ports/nrf/tick.h b/ports/nrf/tick.h
index 73f17d703..838e9fbea 100644
--- a/ports/nrf/tick.h
+++ b/ports/nrf/tick.h
@@ -26,7 +26,7 @@
#ifndef MICROPY_INCLUDED_NRF_TICK_H
#define MICROPY_INCLUDED_NRF_TICK_H
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#include <stdint.h>
diff --git a/ports/nrf/usb/usb_desc.c b/ports/nrf/usb/usb_desc.c
deleted file mode 100644
index 10d603528..000000000
--- a/ports/nrf/usb/usb_desc.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 hathach 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 "usb_desc.h"
-#include "common-hal/usb_hid/Device.h"
-
-//--------------------------------------------------------------------+
-// MACRO TYPEDEF CONSTANT ENUM DECLARATION
-//--------------------------------------------------------------------+
-#define USB_VID 0x239A
-
-/* Note: different class combination e.g CDC and (CDC + MSC) should have different
- * PID since Host OS will "remembered" device driver after the first plug */
-#define USB_PID 0x802A
-
-/*------------- Interface Numbering -------------*/
-enum {
- ITF_NUM_CDC = 0 ,
- ITF_NUM_CDC_DATA ,
- ITF_NUM_MSC ,
- ITF_NUM_HID_GEN ,
- ITF_NUM_TOTAL
-};
-
-enum {
- ITF_STR_LANGUAGE = 0 ,
- ITF_STR_MANUFACTURER ,
- ITF_STR_PRODUCT ,
- ITF_STR_SERIAL ,
- ITF_STR_CDC ,
- ITF_STR_MSC ,
- ITF_STR_HID
-};
-
-/*------------- Endpoint Numbering & Size -------------*/
-#define _EP_IN(x) (0x80 | (x))
-#define _EP_OUT(x) (x)
-
-// CDC
-#define EP_CDC_NOTIF _EP_IN ( ITF_NUM_CDC+1 )
-#define EP_CDC_NOTIF_SIZE 8
-
-#define EP_CDC_OUT _EP_OUT( ITF_NUM_CDC+2 )
-#define EP_CDC_IN _EP_IN ( ITF_NUM_CDC+2 )
-
-// Mass Storage
-#define EP_MSC_OUT _EP_OUT( ITF_NUM_MSC+1 )
-#define EP_MSC_IN _EP_IN ( ITF_NUM_MSC+1 )
-
-// HID composite = keyboard + mouse + gamepad + etc ...
-#define EP_HID_GEN _EP_IN ( ITF_NUM_HID_GEN+1 )
-#define EP_HID_GEN_SIZE 16
-
-//--------------------------------------------------------------------+
-// STRING DESCRIPTORS
-//--------------------------------------------------------------------+
-
-uint16_t usb_desc_str_serial[1+16] = { TUD_DESC_STR_HEADER(16) };
-
-// array of pointer to string descriptors
-uint16_t const * const string_desc_arr [] =
-{
- // 0 index is supported language = English
- TUD_DESC_STRCONV(0x0409),
-
- // 1 Manufacturer
- TUD_DESC_STRCONV('A','d','a','f','r','u','i','t',' ','I','n','d','u','s','t','r','i','e','s'),
-
- // 2 Product
- TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','n','R','F','5','2'),
-
- // 3 Serials TODO use chip ID
- usb_desc_str_serial,
-
- // 4 CDC Interface
- TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','S','e','r','i','a','l'),
-
- // 5 MSC Interface
- TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','S','t','o','r','a','g','e'),
-
- // 6 HID Interface
- TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','H','I','D'),
-
- // Custom Interface
-// TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','C','u','s','t','o','m')
-};
-
-
-//--------------------------------------------------------------------+
-// Device Descriptor
-//--------------------------------------------------------------------+
-tusb_desc_device_t const usb_desc_dev =
-{
- .bLength = sizeof(tusb_desc_device_t),
- .bDescriptorType = TUSB_DESC_DEVICE,
- .bcdUSB = 0x0200,
-
- #if CFG_TUD_CDC
- // Use Interface Association Descriptor (IAD) for CDC
- // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
- .bDeviceClass = TUSB_CLASS_MISC,
- .bDeviceSubClass = MISC_SUBCLASS_COMMON,
- .bDeviceProtocol = MISC_PROTOCOL_IAD,
- #else
- .bDeviceClass = 0x00,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
- #endif
-
- .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE,
-
- .idVendor = USB_VID,
- .idProduct = USB_PID,
- .bcdDevice = 0x0100,
-
- .iManufacturer = 0x01,
- .iProduct = 0x02,
- .iSerialNumber = 0x03,
-
- .bNumConfigurations = 0x01 // TODO multiple configurations
-};
-
-//--------------------------------------------------------------------+
-// HID Report Descriptor
-//--------------------------------------------------------------------+
-uint8_t const usb_desc_hid_generic_report[] =
-{
-#if USB_HID_DEVICE_KEYBOARD
- HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(USB_HID_REPORT_ID_KEYBOARD), ),
-#endif
-
-#if USB_HID_DEVICE_MOUSE
- HID_REPORT_DESC_MOUSE( HID_REPORT_ID(USB_HID_REPORT_ID_MOUSE), ),
-#endif
-
-#if USB_HID_DEVICE_CONSUMER
- HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(USB_HID_REPORT_ID_CONSUMER), ),
-#endif
-
-#if USB_HID_DEVICE_SYS_CONTROL
- HID_REPORT_DESC_SYSTEM_CONTROL( HID_REPORT_ID(USB_HID_REPORT_ID_SYS_CONTROL ), ),
-#endif
-
-#if USB_HID_DEVICE_GAMEPAD
- HID_REPORT_DESC_GAMEPAD( HID_REPORT_ID(USB_HID_REPORT_ID_GAMEPAD ), )
-#endif
-
-};
-
-//--------------------------------------------------------------------+
-// Configuration Descriptor
-//--------------------------------------------------------------------+
-usb_desc_cfg_t const usb_desc_cfg =
-{
- .config =
- {
- .bLength = sizeof(tusb_desc_configuration_t),
- .bDescriptorType = TUSB_DESC_CONFIGURATION,
- .wTotalLength = sizeof(usb_desc_cfg_t),
- .bNumInterfaces = ITF_NUM_TOTAL,
- .bConfigurationValue = 1,
- .iConfiguration = 0x00,
- .bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
- .bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
- },
-
- // IAD points to CDC Interfaces
- .cdc =
- {
- .iad =
- {
- .bLength = sizeof(tusb_desc_interface_assoc_t),
- .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION,
-
- .bFirstInterface = ITF_NUM_CDC,
- .bInterfaceCount = 2,
-
- .bFunctionClass = TUSB_CLASS_CDC,
- .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
- .bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
- .iFunction = 0
- },
-
- //------------- CDC Communication Interface -------------//
- .comm_itf =
- {
- .bLength = sizeof(tusb_desc_interface_t),
- .bDescriptorType = TUSB_DESC_INTERFACE,
- .bInterfaceNumber = ITF_NUM_CDC,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = TUSB_CLASS_CDC,
- .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
- .bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
- .iInterface = ITF_STR_CDC
- },
-
- .header =
- {
- .bLength = sizeof(cdc_desc_func_header_t),
- .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
- .bDescriptorSubType = CDC_FUNC_DESC_HEADER,
- .bcdCDC = 0x0120
- },
-
- .call =
- {
- .bLength = sizeof(cdc_desc_func_call_management_t),
- .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
- .bDescriptorSubType = CDC_FUNC_DESC_CALL_MANAGEMENT,
- .bmCapabilities = { 0 },
- .bDataInterface = ITF_NUM_CDC+1,
- },
-
- .acm =
- {
- .bLength = sizeof(cdc_desc_func_acm_t),
- .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
- .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
- .bmCapabilities = { // 0x02
- .support_line_request = 1,
- }
- },
-
- .union_func =
- {
- .bLength = sizeof(cdc_desc_func_union_t), // plus number of
- .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
- .bDescriptorSubType = CDC_FUNC_DESC_UNION,
- .bControlInterface = ITF_NUM_CDC,
- .bSubordinateInterface = ITF_NUM_CDC+1,
- },
-
- .ep_notif =
- {
- .bLength = sizeof(tusb_desc_endpoint_t),
- .bDescriptorType = TUSB_DESC_ENDPOINT,
- .bEndpointAddress = EP_CDC_NOTIF,
- .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
- .wMaxPacketSize = { .size = EP_CDC_NOTIF_SIZE },
- .bInterval = 0x10
- },
-
- //------------- CDC Data Interface -------------//
- .data_itf =
- {
- .bLength = sizeof(tusb_desc_interface_t),
- .bDescriptorType = TUSB_DESC_INTERFACE,
- .bInterfaceNumber = ITF_NUM_CDC+1,
- .bAlternateSetting = 0x00,
- .bNumEndpoints = 2,
- .bInterfaceClass = TUSB_CLASS_CDC_DATA,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 0,
- .iInterface = 0x00
- },
-
- .ep_out =
- {
- .bLength = sizeof(tusb_desc_endpoint_t),
- .bDescriptorType = TUSB_DESC_ENDPOINT,
- .bEndpointAddress = EP_CDC_OUT,
- .bmAttributes = { .xfer = TUSB_XFER_BULK },
- .wMaxPacketSize = { .size = CFG_TUD_CDC_EPSIZE },
- .bInterval = 0
- },
-
- .ep_in =
- {
- .bLength = sizeof(tusb_desc_endpoint_t),
- .bDescriptorType = TUSB_DESC_ENDPOINT,
- .bEndpointAddress = EP_CDC_IN,
- .bmAttributes = { .xfer = TUSB_XFER_BULK },
- .wMaxPacketSize = { .size = CFG_TUD_CDC_EPSIZE },
- .bInterval = 0
- },
- },
-
- //------------- Mass Storage-------------//
- .msc =
- {
- .itf =
- {
- .bLength = sizeof(tusb_desc_interface_t),
- .bDescriptorType = TUSB_DESC_INTERFACE,
- .bInterfaceNumber = ITF_NUM_MSC,
- .bAlternateSetting = 0x00,
- .bNumEndpoints = 2,
- .bInterfaceClass = TUSB_CLASS_MSC,
- .bInterfaceSubClass = MSC_SUBCLASS_SCSI,
- .bInterfaceProtocol = MSC_PROTOCOL_BOT,
- .iInterface = ITF_STR_MSC
- },
-
- .ep_out =
- {
- .bLength = sizeof(tusb_desc_endpoint_t),
- .bDescriptorType = TUSB_DESC_ENDPOINT,
- .bEndpointAddress = EP_MSC_OUT,
- .bmAttributes = { .xfer = TUSB_XFER_BULK },
- .wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE},
- .bInterval = 1
- },
-
- .ep_in =
- {
- .bLength = sizeof(tusb_desc_endpoint_t),
- .bDescriptorType = TUSB_DESC_ENDPOINT,
- .bEndpointAddress = EP_MSC_IN,
- .bmAttributes = { .xfer = TUSB_XFER_BULK },
- .wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE},
- .bInterval = 1
- }
- },
-
- //------------- HID Generic Multiple report -------------//
- .hid_generic =
- {
- .itf =
- {
- .bLength = sizeof(tusb_desc_interface_t),
- .bDescriptorType = TUSB_DESC_INTERFACE,
- .bInterfaceNumber = ITF_NUM_HID_GEN,
- .bAlternateSetting = 0x00,
- .bNumEndpoints = 1,
- .bInterfaceClass = TUSB_CLASS_HID,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 0,
- .iInterface = ITF_STR_HID
- },
-
- .hid_desc =
- {
- .bLength = sizeof(tusb_hid_descriptor_hid_t),
- .bDescriptorType = HID_DESC_TYPE_HID,
- .bcdHID = 0x0111,
- .bCountryCode = HID_Local_NotSupported,
- .bNumDescriptors = 1,
- .bReportType = HID_DESC_TYPE_REPORT,
- .wReportLength = sizeof(usb_desc_hid_generic_report)
- },
-
- .ep_in =
- {
- .bLength = sizeof(tusb_desc_endpoint_t),
- .bDescriptorType = TUSB_DESC_ENDPOINT,
- .bEndpointAddress = EP_HID_GEN,
- .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
- .wMaxPacketSize = { .size = EP_HID_GEN_SIZE },
- .bInterval = 0x0A
- }
- }
-};
-
-
-// tud_desc_set is required by tinyusb stack
-tud_desc_set_t tud_desc_set =
-{
- .device = &usb_desc_dev,
- .config = &usb_desc_cfg,
- .string_arr = (uint8_t const **) string_desc_arr,
- .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]),
-
- .hid_report =
- {
- .generic = usb_desc_hid_generic_report,
- .boot_keyboard = NULL,
- .boot_mouse = NULL
- }
-};
diff --git a/ports/nrf/usb/usb_desc.h b/ports/nrf/usb/usb_desc.h
deleted file mode 100644
index 19f3f6d5b..000000000
--- a/ports/nrf/usb/usb_desc.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 hathach 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 USB_DESC_H_
-#define USB_DESC_H_
-
-#include "tusb.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*------------- Configuration Descriptor -------------*/
-typedef struct ATTR_PACKED
-{
- tusb_desc_configuration_t config;
-
- //------------- CDC -------------//
- struct ATTR_PACKED
- {
- tusb_desc_interface_assoc_t iad;
-
- //CDC Control Interface
- tusb_desc_interface_t comm_itf;
- cdc_desc_func_header_t header;
- cdc_desc_func_call_management_t call;
- cdc_desc_func_acm_t acm;
- cdc_desc_func_union_t union_func;
- tusb_desc_endpoint_t ep_notif;
-
- //CDC Data Interface
- tusb_desc_interface_t data_itf;
- tusb_desc_endpoint_t ep_out;
- tusb_desc_endpoint_t ep_in;
- }cdc;
-
- //------------- Mass Storage -------------//
- struct ATTR_PACKED
- {
- tusb_desc_interface_t itf;
- tusb_desc_endpoint_t ep_out;
- tusb_desc_endpoint_t ep_in;
- } msc;
-
- //------------- HID -------------//
- struct ATTR_PACKED
- {
- tusb_desc_interface_t itf;
- tusb_hid_descriptor_hid_t hid_desc;
- tusb_desc_endpoint_t ep_in;
- } hid_generic;
-
-} usb_desc_cfg_t;
-
-
-// Descriptors set used by tinyusb stack
-extern tud_desc_set_t tud_desc_set;
-
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* USB_DESC_H_ */
diff --git a/py/py.mk b/py/py.mk
index 9874dde4d..c640e6cff 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -307,7 +307,7 @@ $(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEF
# qstr data
$(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h
$(STEPECHO) "GEN $@"
- $(PYTHON3) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
+ $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
# Adding an order only dependency on $(HEADER_BUILD) causes $(HEADER_BUILD) to get
# created before we run the script to generate the .h
@@ -315,7 +315,7 @@ $(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrd
# the lines in "" and then unwrap after the preprocessor is finished.
$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h
$(STEPECHO) "GEN $@"
- $(PYTHON3) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
+ $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
$(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h
diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h
index 555f32c92..2d12b8b76 100644
--- a/shared-bindings/busio/SPI.h
+++ b/shared-bindings/busio/SPI.h
@@ -61,4 +61,7 @@ extern bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_o
// Return actual SPI bus frequency.
uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self);
+// This is used by the supervisor to claim SPI devices indefinitely.
+extern void common_hal_busio_spi_never_reset(busio_spi_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H
diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h
index 2bc553c4a..cb9a64b5e 100644
--- a/shared-bindings/usb_hid/Device.h
+++ b/shared-bindings/usb_hid/Device.h
@@ -27,7 +27,7 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H
-#include "common-hal/usb_hid/Device.h"
+#include "shared-module/usb_hid/Device.h"
const mp_obj_type_t usb_hid_device_type;
diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c
index 9e4508355..6d3a28523 100644
--- a/shared-module/bitbangio/SPI.c
+++ b/shared-module/bitbangio/SPI.c
@@ -24,8 +24,7 @@
* THE SOFTWARE.
*/
-#include "mpconfigport.h"
-
+#include "py/mpconfig.h"
#include "py/obj.h"
#include "py/runtime.h"
diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c
index edce286b1..f09edd785 100644
--- a/shared-module/storage/__init__.c
+++ b/shared-module/storage/__init__.c
@@ -32,8 +32,12 @@
#include "py/mperrno.h"
#include "py/obj.h"
#include "py/runtime.h"
+#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/os/__init__.h"
#include "shared-bindings/storage/__init__.h"
+#include "supervisor/filesystem.h"
+#include "supervisor/flash.h"
+#include "supervisor/usb.h"
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
if (vfs == MP_VFS_NONE) {
@@ -138,3 +142,25 @@ void common_hal_storage_umount_path(const char* mount_path) {
mp_obj_t common_hal_storage_getmount(const char *mount_path) {
return storage_object_from_path(mount_path);
}
+
+void common_hal_storage_remount(const char *mount_path, bool readonly) {
+ if (strcmp(mount_path, "/") != 0) {
+ mp_raise_OSError(MP_EINVAL);
+ }
+
+ #ifdef USB_AVAILABLE
+ // TODO(dhalbert): is this is a good enough check? It checks for
+ // CDC enabled. There is no "MSC enabled" check.
+ if (usb_enabled()) {
+ mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active."));
+ }
+ #endif
+
+ supervisor_flash_set_usb_writable(readonly);
+}
+
+void common_hal_storage_erase_filesystem(void) {
+ filesystem_init(false, true); // Force a re-format.
+ common_hal_mcu_reset();
+ // We won't actually get here, since we're resetting.
+}
diff --git a/ports/nrf/common-hal/usb_hid/Device.c b/shared-module/usb_hid/Device.c
index 6acb2717f..820e14ad0 100644
--- a/ports/nrf/common-hal/usb_hid/Device.c
+++ b/shared-module/usb_hid/Device.c
@@ -26,9 +26,9 @@
#include <string.h>
#include "tick.h"
-#include "common-hal/usb_hid/Device.h"
#include "py/runtime.h"
#include "shared-bindings/usb_hid/Device.h"
+#include "shared-module/usb_hid/Device.h"
#include "supervisor/shared/translate.h"
#include "tusb.h"
diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.h b/shared-module/usb_hid/Device.h
index b81c0e709..10f2ee897 100644
--- a/ports/atmel-samd/common-hal/usb_hid/Device.h
+++ b/shared-module/usb_hid/Device.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2018 hathach 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 +24,32 @@
* THE SOFTWARE.
*/
-#ifndef COMMON_HAL_USB_HID_DEVICE_H
-#define COMMON_HAL_USB_HID_DEVICE_H
+#ifndef SHARED_MODULE_USB_HID_DEVICE_H
+#define SHARED_MODULE_USB_HID_DEVICE_H
#include <stdint.h>
#include <stdbool.h>
#include "py/obj.h"
-#include "genhdr/autogen_usb_descriptor.h"
+#ifdef __cplusplus
+ extern "C" {
+#endif
-typedef struct {
+typedef struct {
mp_obj_base_t base;
uint8_t* report_buffer;
- uint8_t endpoint;
- uint8_t report_id; // If non-zero, prefix report with given id.
- uint8_t report_length; // Length not including Report ID.
+ uint8_t report_id;
+ uint8_t report_length;
uint8_t usage_page;
uint8_t usage;
-
} usb_hid_device_obj_t;
-extern usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES];
-void usb_hid_init(void);
-void usb_hid_reset(void);
+extern usb_hid_device_obj_t usb_hid_devices[];
+
+#ifdef __cplusplus
+ }
+#endif
-#endif // COMMON_HAL_USB_HID_DEVICE_H
+#endif /* SHARED_MODULE_USB_HID_DEVICE_H */
diff --git a/ports/nrf/common-hal/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c
index 00fc8bd00..f14fdd41e 100644
--- a/ports/nrf/common-hal/usb_hid/__init__.c
+++ b/shared-module/usb_hid/__init__.c
@@ -28,43 +28,37 @@
#include "py/mphal.h"
#include "py/runtime.h"
-#include "common-hal/usb_hid/Device.h"
+#include "genhdr/autogen_usb_descriptor.h"
+#include "shared-module/usb_hid/Device.h"
#include "shared-bindings/usb_hid/Device.h"
#include "tusb.h"
-#define USB_HID_REPORT_LENGTH_KEYBOARD 8
-#define USB_HID_REPORT_LENGTH_MOUSE 4
-#define USB_HID_REPORT_LENGTH_CONSUMER 2
-#define USB_HID_REPORT_LENGTH_SYS_CONTROL 1
-#define USB_HID_REPORT_LENGTH_GAMEPAD 6
-#define USB_HID_REPORT_LENGTH_DIGITIZER 5
-
-#if USB_HID_DEVICE_KEYBOARD
+#ifdef USB_HID_REPORT_ID_KEYBOARD
static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD];
#endif
-#if USB_HID_DEVICE_MOUSE
+#ifdef USB_HID_REPORT_ID_MOUSE
static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE];
#endif
-#if USB_HID_DEVICE_CONSUMER
+#ifdef USB_HID_REPORT_ID_CONSUMER
static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER];
#endif
-#if USB_HID_DEVICE_SYS_CONTROL
+#ifdef USB_HID_REPORT_ID_SYS_CONTROL
static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL];
#endif
-#if USB_HID_DEVICE_GAMEPAD
+#ifdef USB_HID_REPORT_ID_GAMEPAD
static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD];
#endif
-#if USB_HID_DEVICE_DIGITIZER
+#ifdef USB_HID_REPORT_ID_DIGITIZER
static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER];
#endif
usb_hid_device_obj_t usb_hid_devices[] = {
-#if USB_HID_DEVICE_KEYBOARD
+#ifdef USB_HID_REPORT_ID_KEYBOARD
{
.base = { .type = &usb_hid_device_type } ,
.report_buffer = keyboard_report_buffer ,
@@ -75,7 +69,7 @@ usb_hid_device_obj_t usb_hid_devices[] = {
},
#endif
-#if USB_HID_DEVICE_MOUSE
+#ifdef USB_HID_REPORT_ID_MOUSE
{
.base = { .type = &usb_hid_device_type } ,
.report_buffer = mouse_report_buffer ,
@@ -86,7 +80,7 @@ usb_hid_device_obj_t usb_hid_devices[] = {
},
#endif
-#if USB_HID_DEVICE_CONSUMER
+#ifdef USB_HID_REPORT_ID_CONSUMER
{
.base = { .type = &usb_hid_device_type } ,
.report_buffer = consumer_report_buffer ,
@@ -97,7 +91,7 @@ usb_hid_device_obj_t usb_hid_devices[] = {
},
#endif
-#if USB_HID_DEVICE_SYS_CONTROL
+#ifdef USB_HID_REPORT_ID_SYS_CONTROL
{
.base = { .type = &usb_hid_device_type } ,
.report_buffer = sys_control_report_buffer ,
@@ -108,7 +102,7 @@ usb_hid_device_obj_t usb_hid_devices[] = {
},
#endif
-#if USB_HID_DEVICE_GAMEPAD
+#ifdef USB_HID_REPORT_ID_GAMEPAD
{
.base = { .type = &usb_hid_device_type } ,
.report_buffer = gamepad_report_buffer ,
@@ -119,7 +113,7 @@ usb_hid_device_obj_t usb_hid_devices[] = {
},
#endif
-#if USB_HID_DEVICE_DIGITIZER
+#ifdef USB_HID_REPORT_ID_DIGITIZER
{
.base = { .type = &usb_hid_device_type } ,
.report_buffer = digitizer_report_buffer ,
diff --git a/ports/atmel-samd/usb_mass_storage.h b/supervisor/flash.h
index 767a6779c..ae6a44fd0 100644
--- a/ports/atmel-samd/usb_mass_storage.h
+++ b/supervisor/flash.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,26 +23,32 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#ifndef MICROPY_INCLUDED_SUPERVISOR_FLASH_H
+#define MICROPY_INCLUDED_SUPERVISOR_FLASH_H
-// This adapts the ASF4 USB mass storage API to MicroPython's VFS API so we can
-// expose all VFS block devices as Lun's over USB mass storage control.
+#include <stdint.h>
+#include <stdbool.h>
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H
+#include "py/mpconfig.h"
-#include <stdint.h>
+#ifdef EXTERNAL_FLASH_DEVICE_COUNT
+#include "supervisor/shared/external_flash/external_flash.h"
+#else
+#include "supervisor/internal_flash.h"
+#endif
+
+void supervisor_flash_set_usb_writable(bool usb_writable);
+void supervisor_flash_init(void);
+uint32_t supervisor_flash_get_block_size(void);
+uint32_t supervisor_flash_get_block_count(void);
+void supervisor_flash_flush(void);
-// "background" task that actually manages loading to and from the file systems.
-void usb_msc_background(void);
+// these return 0 on success, non-zero on error
+mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
+mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
-// Callbacks that hook into ASF4's USB stack.
-int32_t usb_msc_disk_eject(uint8_t lun);
-int32_t usb_msc_disk_is_writable(uint8_t lun);
-int32_t usb_msc_disk_is_ready(uint8_t lun);
-int32_t usb_msc_new_read(uint8_t lun, uint32_t addr, uint32_t nblocks);
-int32_t usb_msc_new_write(uint8_t lun, uint32_t addr, uint32_t nblocks);
-int32_t usb_msc_xfer_done(uint8_t lun);
-uint8_t *usb_msc_inquiry_info(uint8_t lun);
-uint8_t *usb_msc_get_capacity(uint8_t lun);
+struct _fs_user_mount_t;
+void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs);
+void supervisor_flash_flush(void);
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H
+#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H
diff --git a/supervisor/flash_root_pointers.h b/supervisor/flash_root_pointers.h
new file mode 100644
index 000000000..634ae58d3
--- /dev/null
+++ b/supervisor/flash_root_pointers.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * 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_SUPERVISOR_FLASH_ROOT_POINTERS_H
+#define MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H
+
+#ifdef EXTERNAL_FLASH_DEVICE_COUNT
+#include "supervisor/shared/external_flash/external_flash_root_pointers.h"
+#else
+#include "supervisor/internal_flash_root_pointers.h"
+#endif
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H
diff --git a/supervisor/port.h b/supervisor/port.h
index f30d87b47..dd4a82209 100644
--- a/supervisor/port.h
+++ b/supervisor/port.h
@@ -57,6 +57,9 @@ void reset_port(void);
// Reset the rest of the board.
void reset_board(void);
+// Reset to the bootloader
+void reset_to_bootloader(void);
+
#ifdef NRF52_SERIES
void HardFault_Handler(void);
#endif
diff --git a/supervisor/serial.h b/supervisor/serial.h
index 9446ee71c..84b3062a3 100644
--- a/supervisor/serial.h
+++ b/supervisor/serial.h
@@ -30,8 +30,18 @@
#include <stdbool.h>
#include <stdint.h>
+#include "py/mpconfig.h"
+
+#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
+#include "lib/oofatfs/ff.h"
+
+FIL* boot_output_file;
+#endif
+
void serial_init(void);
void serial_write(const char* text);
+// Only writes up to given length. Does not check for null termination at all.
+void serial_write_substring(const char* text, uint32_t length);
char serial_read(void);
bool serial_bytes_available(void);
bool serial_connected(void);
diff --git a/ports/atmel-samd/external_flash/common_commands.h b/supervisor/shared/external_flash/common_commands.h
index d82d2c046..cc0da2175 100644
--- a/ports/atmel-samd/external_flash/common_commands.h
+++ b/supervisor/shared/external_flash/common_commands.h
@@ -28,6 +28,7 @@
#define CMD_READ_JEDEC_ID 0x9f
#define CMD_READ_DATA 0x03
+#define CMD_FAST_READ_DATA 0x0B
#define CMD_SECTOR_ERASE 0x20
// #define CMD_SECTOR_ERASE CMD_READ_JEDEC_ID
#define CMD_DISABLE_WRITE 0x04
diff --git a/ports/atmel-samd/external_flash/devices.h b/supervisor/shared/external_flash/devices.h
index 58da2e509..06fc178cb 100644
--- a/ports/atmel-samd/external_flash/devices.h
+++ b/supervisor/shared/external_flash/devices.h
@@ -40,6 +40,11 @@ typedef struct {
// Max clock speed for all operations and the fastest read mode.
uint8_t max_clock_speed_mhz;
+
+ // Bitmask for Quad Enable bit if present. 0x00 otherwise. This is for the highest byte in the
+ // status register.
+ uint8_t quad_enable_bit_mask;
+
bool has_sector_protection : 1;
// Supports the 0x0b fast read command with 8 dummy cycles.
@@ -48,9 +53,6 @@ typedef struct {
// Supports the fast read, quad output command 0x6b with 8 dummy cycles.
bool supports_qspi : 1;
- // Requires quad enable set in status bit 9.
- bool has_quad_enable : 1;
-
// Supports the quad input page program command 0x32. This is known as 1-1-4 because it only
// uses all four lines for data.
bool supports_qspi_writes: 1;
@@ -58,6 +60,10 @@ typedef struct {
// Requires a separate command 0x31 to write to the second byte of the status register.
// Otherwise two byte are written via 0x01.
bool write_status_register_split: 1;
+
+ // True when the status register is a single byte. This implies the Quad Enable bit is in the
+ // first byte and the Read Status Register 2 command (0x35) is unsupported.
+ bool single_status_byte: 1;
} external_flash_device;
// Settings for the Adesto Tech AT25DF081A 1MiB SPI flash. Its on the SAMD21
@@ -70,12 +76,13 @@ typedef struct {
.memory_type = 0x45, \
.capacity = 0x01, \
.max_clock_speed_mhz = 85, \
+ .quad_enable_bit_mask = 0x00, \
.has_sector_protection = true, \
.supports_fast_read = true, \
.supports_qspi = false, \
- .has_quad_enable = false, \
.supports_qspi_writes = false, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Gigadevice GD25Q16C 2MiB SPI flash.
@@ -87,12 +94,13 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x15, \
.max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Gigadevice GD25Q64C 8MiB SPI flash.
@@ -104,12 +112,13 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x17, \
.max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = true, \
+ .single_status_byte = false, \
}
// Settings for the Cypress (was Spansion) S25FL064L 8MiB SPI flash.
@@ -121,12 +130,13 @@ typedef struct {
.memory_type = 0x60, \
.capacity = 0x17, \
.max_clock_speed_mhz = 108, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Cypress (was Spansion) S25FL116K 2MiB SPI flash.
@@ -138,12 +148,13 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x15, \
.max_clock_speed_mhz = 108, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = false, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Cypress (was Spansion) S25FL216K 2MiB SPI flash.
@@ -155,12 +166,13 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x15, \
.max_clock_speed_mhz = 65, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = false, \
- .has_quad_enable = false, \
.supports_qspi_writes = false, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Winbond W25Q16FW 2MiB SPI flash.
@@ -172,12 +184,13 @@ typedef struct {
.memory_type = 0x60, \
.capacity = 0x15, \
.max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Winbond W25Q16JV-IQ 2MiB SPI flash. Note that JV-IM has a different .memory_type (0x70)
@@ -189,12 +202,13 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x15, \
.max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Winbond W25Q16JV-IM 2MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40)
@@ -223,12 +237,13 @@ typedef struct {
.memory_type = 0x60, \
.capacity = 0x16, \
.max_clock_speed_mhz = 104, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = false, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Winbond W25Q32JV-IM 4MiB SPI flash.
// Datasheet: https://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf
@@ -256,12 +271,14 @@ typedef struct {
.memory_type = 0x70, \
.capacity = 0x17, \
.max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
.has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Winbond W25Q64JV-IQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70)
@@ -273,12 +290,13 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x17, \
.max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
// Settings for the Winbond W25Q80DL 1MiB SPI flash.
@@ -290,12 +308,13 @@ typedef struct {
.memory_type = 0x60, \
.capacity = 0x14, \
.max_clock_speed_mhz = 104, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = false, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
@@ -308,14 +327,33 @@ typedef struct {
.memory_type = 0x40, \
.capacity = 0x18, \
.max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
.has_sector_protection = false, \
.supports_fast_read = true, \
.supports_qspi = true, \
- .has_quad_enable = true, \
.supports_qspi_writes = true, \
.write_status_register_split = false, \
+ .single_status_byte = false, \
}
+// Settings for the Macronix MX25R6435F 8MiB SPI flash.
+// Datasheet: http://www.macronix.com/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf
+// By default its in lower power mode which can only do 8mhz. In high power mode it can do 80mhz.
+#define MX25R6435F {\
+ .total_size = (1 << 23), /* 8 MiB */ \
+ .start_up_time_us = 5000, \
+ .manufacturer_id = 0xc2, \
+ .memory_type = 0x28, \
+ .capacity = 0x17, \
+ .max_clock_speed_mhz = 8, \
+ .quad_enable_bit_mask = 0x40, \
+ .has_sector_protection = false, \
+ .supports_fast_read = true, \
+ .supports_qspi = true, \
+ .supports_qspi_writes = true, \
+ .write_status_register_split = false, \
+ .single_status_byte = true, \
+}
// Settings for the Winbond W25Q128JV-PM 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70)
// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf
diff --git a/ports/atmel-samd/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c
index b4a637be4..defdfa393 100644
--- a/ports/atmel-samd/external_flash/external_flash.c
+++ b/supervisor/shared/external_flash/external_flash.c
@@ -28,8 +28,8 @@
#include <stdint.h>
#include <string.h>
-#include "external_flash/spi_flash_api.h"
-#include "external_flash/common_commands.h"
+#include "supervisor/spi_flash_api.h"
+#include "supervisor/shared/external_flash/common_commands.h"
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
#include "py/misc.h"
@@ -40,15 +40,10 @@
#include "supervisor/memory.h"
#include "supervisor/shared/rgb_led_status.h"
-#include "hal_gpio.h"
-#include "hal_spi_m_sync.h"
-
#define SPI_FLASH_PART1_START_BLOCK (0x1)
#define NO_SECTOR_LOADED 0xFFFFFFFF
-struct spi_m_sync_descriptor spi_flash_desc;
-
// The currently cached sector in the cache, ram or flash based.
static uint32_t current_sector;
@@ -181,7 +176,7 @@ static bool copy_block(uint32_t src_address, uint32_t dest_address) {
return true;
}
-void external_flash_init(void) {
+void supervisor_flash_init(void) {
if (flash_device != NULL) {
return;
}
@@ -265,12 +260,12 @@ void external_flash_init(void) {
}
// The size of each individual block.
-uint32_t external_flash_get_block_size(void) {
+uint32_t supervisor_flash_get_block_size(void) {
return FILESYSTEM_BLOCK_SIZE;
}
// The total number of available blocks.
-uint32_t external_flash_get_block_count(void) {
+uint32_t supervisor_flash_get_block_count(void) {
// We subtract one erase sector size because we may use it as a staging area
// for writes.
return SPI_FLASH_PART1_START_BLOCK + (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE;
@@ -445,14 +440,10 @@ static void spi_flash_flush_keep_cache(bool keep_cache) {
// External flash function used. If called externally we assume we won't need
// the cache after.
-void external_flash_flush(void) {
+void supervisor_flash_flush(void) {
spi_flash_flush_keep_cache(false);
}
-void flash_flush(void) {
- external_flash_flush();
-}
-
// Builds a partition entry for the MBR.
static void build_partition(uint8_t *buf, int boot, int type,
uint32_t start_block, uint32_t num_blocks) {
@@ -492,7 +483,7 @@ static void build_partition(uint8_t *buf, int boot, int type,
}
static int32_t convert_block_to_flash_addr(uint32_t block) {
- if (SPI_FLASH_PART1_START_BLOCK <= block && block < external_flash_get_block_count()) {
+ if (SPI_FLASH_PART1_START_BLOCK <= block && block < supervisor_flash_get_block_count()) {
// a block in partition 1
block -= SPI_FLASH_PART1_START_BLOCK;
return block * FILESYSTEM_BLOCK_SIZE;
@@ -510,7 +501,7 @@ bool external_flash_read_block(uint8_t *dest, uint32_t block) {
build_partition(dest + 446, 0, 0x01 /* FAT12 */,
SPI_FLASH_PART1_START_BLOCK,
- external_flash_get_block_count() - SPI_FLASH_PART1_START_BLOCK);
+ supervisor_flash_get_block_count() - SPI_FLASH_PART1_START_BLOCK);
build_partition(dest + 462, 0, 0, 0, 0);
build_partition(dest + 478, 0, 0, 0, 0);
build_partition(dest + 494, 0, 0, 0, 0);
@@ -605,7 +596,7 @@ bool external_flash_write_block(const uint8_t *data, uint32_t block) {
}
}
-mp_uint_t external_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
+mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
for (size_t i = 0; i < num_blocks; i++) {
if (!external_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
return 1; // error
@@ -614,7 +605,7 @@ mp_uint_t external_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t
return 0; // success
}
-mp_uint_t external_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
+mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
for (size_t i = 0; i < num_blocks; i++) {
if (!external_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
return 1; // error
@@ -622,78 +613,3 @@ mp_uint_t external_flash_write_blocks(const uint8_t *src, uint32_t block_num, ui
}
return 0; // success
}
-
-/******************************************************************************/
-// MicroPython bindings
-//
-// Expose the flash as an object with the block protocol.
-
-// there is a singleton Flash object
-STATIC const mp_obj_base_t external_flash_obj = {&external_flash_type};
-
-STATIC mp_obj_t external_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- // check arguments
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
-
- // return singleton object
- return (mp_obj_t)&external_flash_obj;
-}
-
-STATIC mp_obj_t external_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
- mp_uint_t ret = external_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
- return MP_OBJ_NEW_SMALL_INT(ret);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(external_flash_obj_readblocks_obj, external_flash_obj_readblocks);
-
-STATIC mp_obj_t external_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
- mp_uint_t ret = external_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
- return MP_OBJ_NEW_SMALL_INT(ret);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(external_flash_obj_writeblocks_obj, external_flash_obj_writeblocks);
-
-STATIC mp_obj_t external_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
- mp_int_t cmd = mp_obj_get_int(cmd_in);
- switch (cmd) {
- case BP_IOCTL_INIT: external_flash_init(); return MP_OBJ_NEW_SMALL_INT(0);
- case BP_IOCTL_DEINIT: external_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly
- case BP_IOCTL_SYNC: external_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0);
- case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(external_flash_get_block_count());
- case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(external_flash_get_block_size());
- default: return mp_const_none;
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(external_flash_obj_ioctl_obj, external_flash_obj_ioctl);
-
-STATIC const mp_rom_map_elem_t external_flash_obj_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&external_flash_obj_readblocks_obj) },
- { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&external_flash_obj_writeblocks_obj) },
- { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&external_flash_obj_ioctl_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(external_flash_obj_locals_dict, external_flash_obj_locals_dict_table);
-
-const mp_obj_type_t external_flash_type = {
- { &mp_type_type },
- .name = MP_QSTR_SPIFlash,
- .make_new = external_flash_obj_make_new,
- .locals_dict = (mp_obj_t)&external_flash_obj_locals_dict,
-};
-
-void flash_init_vfs(fs_user_mount_t *vfs) {
- vfs->base.type = &mp_fat_vfs_type;
- vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
- vfs->fatfs.drv = vfs;
- vfs->fatfs.part = 1; // flash filesystem lives on first partition
- vfs->readblocks[0] = (mp_obj_t)&external_flash_obj_readblocks_obj;
- vfs->readblocks[1] = (mp_obj_t)&external_flash_obj;
- vfs->readblocks[2] = (mp_obj_t)external_flash_read_blocks; // native version
- vfs->writeblocks[0] = (mp_obj_t)&external_flash_obj_writeblocks_obj;
- vfs->writeblocks[1] = (mp_obj_t)&external_flash_obj;
- vfs->writeblocks[2] = (mp_obj_t)external_flash_write_blocks; // native version
- vfs->u.ioctl[0] = (mp_obj_t)&external_flash_obj_ioctl_obj;
- vfs->u.ioctl[1] = (mp_obj_t)&external_flash_obj;
-}
diff --git a/supervisor/shared/external_flash/external_flash.h b/supervisor/shared/external_flash/external_flash.h
new file mode 100644
index 000000000..72b619a2a
--- /dev/null
+++ b/supervisor/shared/external_flash/external_flash.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * 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_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H
+#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "py/mpconfig.h"
+
+// Erase sector size.
+#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100)
+
+// These are common across all NOR Flash.
+#define SPI_FLASH_ERASE_SIZE (1 << 12)
+#define SPI_FLASH_PAGE_SIZE (256)
+
+#define SPI_FLASH_SYSTICK_MASK (0x1ff) // 512ms
+#define SPI_FLASH_IDLE_TICK(tick) (((tick) & SPI_FLASH_SYSTICK_MASK) == 2)
+
+#ifndef SPI_FLASH_MAX_BAUDRATE
+#define SPI_FLASH_MAX_BAUDRATE 8000000
+#endif
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H
diff --git a/supervisor/shared/external_flash/external_flash_root_pointers.h b/supervisor/shared/external_flash/external_flash_root_pointers.h
new file mode 100644
index 000000000..cb1b86d19
--- /dev/null
+++ b/supervisor/shared/external_flash/external_flash_root_pointers.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * 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_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H
+#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H
+
+#include <stdint.h>
+
+// We use this when we can allocate the whole cache in RAM.
+#define FLASH_ROOT_POINTERS \
+ uint8_t** flash_ram_cache; \
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H
diff --git a/ports/atmel-samd/common-hal/storage/__init__.c b/supervisor/shared/external_flash/qspi_flash.c
index 501a19dd7..48266540c 100644
--- a/ports/atmel-samd/common-hal/storage/__init__.c
+++ b/supervisor/shared/external_flash/qspi_flash.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2016, 2017, 2018 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,35 +24,33 @@
* THE SOFTWARE.
*/
-#include <string.h>
+#include "supervisor/spi_flash_api.h"
-#include "flash_api.h"
-#include "py/mperrno.h"
-#include "py/runtime.h"
-#include "shared-bindings/microcontroller/__init__.h"
-#include "shared-bindings/storage/__init__.h"
-#include "supervisor/filesystem.h"
-#include "supervisor/shared/translate.h"
-#include "usb.h"
+#include "supervisor/shared/external_flash/common_commands.h"
-extern volatile bool mp_msc_enabled;
-
-void common_hal_storage_remount(const char* mount_path, bool readonly) {
- if (strcmp(mount_path, "/") != 0) {
- mp_raise_OSError(MP_EINVAL);
+void check_quad_enable(const external_flash_device* device) {
+ if (device->quad_enable_bit_mask == 0x00) {
+ return;
}
- // TODO(dhalbert): is this is a good enough check? It checks for
- // CDC enabled. There is no "MSC enabled" check.
- if (usb_connected()) {
- mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active."));
+ // Verify that QSPI mode is enabled.
+ uint8_t status;
+ if (device->single_status_byte) {
+ spi_flash_read_command(CMD_READ_STATUS, &status, 1);
+ } else {
+ spi_flash_read_command(CMD_READ_STATUS2, &status, 1);
}
- flash_set_usb_writable(readonly);
-}
-
-void common_hal_storage_erase_filesystem(void) {
- filesystem_init(false, true); // Force a re-format.
- common_hal_mcu_reset();
- // We won't actually get here, since we're resetting.
+ // Check the quad enable bit.
+ if ((status & device->quad_enable_bit_mask) == 0) {
+ uint8_t full_status[2] = {0x00, device->quad_enable_bit_mask};
+ spi_flash_command(CMD_ENABLE_WRITE);
+ if (device->write_status_register_split) {
+ spi_flash_write_command(CMD_WRITE_STATUS_BYTE2, full_status + 1, 1);
+ } else if (device->single_status_byte) {
+ spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status + 1, 1);
+ } else {
+ spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2);
+ }
+ }
}
diff --git a/supervisor/shared/external_flash/qspi_flash.h b/supervisor/shared/external_flash/qspi_flash.h
new file mode 100644
index 000000000..b72e37b26
--- /dev/null
+++ b/supervisor/shared/external_flash/qspi_flash.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * 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_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H
+#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H
+
+void check_quad_enable(const external_flash_device* device);
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H
diff --git a/ports/atmel-samd/external_flash/spi_flash.c b/supervisor/shared/external_flash/spi_flash.c
index 273915df7..ec7101bc9 100644
--- a/ports/atmel-samd/external_flash/spi_flash.c
+++ b/supervisor/shared/external_flash/spi_flash.c
@@ -23,40 +23,50 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "spi_flash_api.h"
+#include "supervisor/spi_flash_api.h"
#include <stdint.h>
#include <string.h>
-#include "external_flash/common_commands.h"
-#include "samd/sercom.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "supervisor/shared/external_flash/common_commands.h"
+#include "supervisor/shared/external_flash/external_flash.h"
#include "py/mpconfig.h"
-#include "hal_gpio.h"
-#include "hal_spi_m_sync.h"
+digitalio_digitalinout_obj_t cs_pin;
+busio_spi_obj_t spi;
-struct spi_m_sync_descriptor spi_flash_desc;
+const external_flash_device* flash_device;
+uint32_t spi_flash_baudrate;
// Enable the flash over SPI.
static void flash_enable(void) {
- gpio_set_pin_level(SPI_FLASH_CS_PIN, false);
+ while (!common_hal_busio_spi_try_lock(&spi)) {}
+ common_hal_digitalio_digitalinout_set_value(&cs_pin, false);
}
// Disable the flash over SPI.
static void flash_disable(void) {
- gpio_set_pin_level(SPI_FLASH_CS_PIN, true);
+ common_hal_digitalio_digitalinout_set_value(&cs_pin, true);
+ common_hal_busio_spi_unlock(&spi);
}
static bool transfer(uint8_t* command, uint32_t command_length, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) {
- struct spi_xfer xfer = { command, NULL, command_length };
flash_enable();
- int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer);
- if (status >= 0 && !(data_in == NULL && data_out == NULL)) {
- struct spi_xfer data_xfer = {data_in, data_out, data_length};
- status = spi_m_sync_transfer(&spi_flash_desc, &data_xfer);
+ bool status = common_hal_busio_spi_write(&spi, command, command_length);
+ if (status) {
+ if (data_in != NULL && data_out != NULL) {
+ status = common_hal_busio_spi_transfer(&spi, data_out, data_in, data_length);
+ } else if (data_out != NULL) {
+ status = common_hal_busio_spi_read(&spi, data_out, data_length, 0xff);
+ } else if (data_in != NULL) {
+ status = common_hal_busio_spi_write(&spi, data_in, data_length);
+ }
}
flash_disable();
- return status >= 0;
+ return status;
}
static bool transfer_command(uint8_t command, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) {
@@ -92,67 +102,49 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length)
uint8_t request[4] = {CMD_PAGE_PROGRAM, 0x00, 0x00, 0x00};
// Write the SPI flash write address into the bytes following the command byte.
address_to_bytes(address, request + 1);
- struct spi_xfer xfer = { request, NULL, 4 };
flash_enable();
- int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer);
- if (status >= 0) {
- status = sercom_dma_write(spi_flash_desc.dev.prvt, data, data_length);
+ common_hal_busio_spi_configure(&spi, spi_flash_baudrate, 0, 0, 8);
+ bool status = common_hal_busio_spi_write(&spi, request, 4);
+ if (status) {
+ status = common_hal_busio_spi_write(&spi, data, data_length);
}
flash_disable();
- return status >= 0;
+ return status;
}
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) {
- uint8_t request[4] = {CMD_READ_DATA, 0x00, 0x00, 0x00};
+ uint8_t request[5] = {CMD_READ_DATA, 0x00, 0x00, 0x00};
+ uint8_t command_length = 4;
+ if (flash_device->supports_fast_read) {
+ request[0] = CMD_FAST_READ_DATA;
+ command_length = 5;
+ }
// Write the SPI flash write address into the bytes following the command byte.
address_to_bytes(address, request + 1);
- struct spi_xfer xfer = { request, NULL, 4 };
flash_enable();
- int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer);
- if (status >= 0) {
- status = sercom_dma_read(spi_flash_desc.dev.prvt, data, data_length, 0xff);
+ common_hal_busio_spi_configure(&spi, spi_flash_baudrate, 0, 0, 8);
+ bool status = common_hal_busio_spi_write(&spi, request, command_length);
+ if (status) {
+ status = common_hal_busio_spi_read(&spi, data, data_length, 0xff);
}
flash_disable();
- return status >= 0;
+ return status;
}
void spi_flash_init(void) {
- samd_peripherals_sercom_clock_init(SPI_FLASH_SERCOM, SPI_FLASH_SERCOM_INDEX);
-
- // Set up with defaults, then change.
- spi_m_sync_init(&spi_flash_desc, SPI_FLASH_SERCOM);
-
- hri_sercomspi_write_CTRLA_DOPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DOPO);
- hri_sercomspi_write_CTRLA_DIPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DIPO);
-
- gpio_set_pin_direction(SPI_FLASH_SCK_PIN, GPIO_DIRECTION_OUT);
- gpio_set_pin_pull_mode(SPI_FLASH_SCK_PIN, GPIO_PULL_OFF);
- gpio_set_pin_function(SPI_FLASH_SCK_PIN, SPI_FLASH_SCK_PIN_FUNCTION);
-
- gpio_set_pin_direction(SPI_FLASH_MOSI_PIN, GPIO_DIRECTION_OUT);
- gpio_set_pin_pull_mode(SPI_FLASH_MOSI_PIN, GPIO_PULL_OFF);
- gpio_set_pin_function(SPI_FLASH_MOSI_PIN, SPI_FLASH_MOSI_PIN_FUNCTION);
-
- gpio_set_pin_direction(SPI_FLASH_MISO_PIN, GPIO_DIRECTION_IN);
- gpio_set_pin_pull_mode(SPI_FLASH_MISO_PIN, GPIO_PULL_OFF);
- gpio_set_pin_function(SPI_FLASH_MISO_PIN, SPI_FLASH_MISO_PIN_FUNCTION);
-
- hri_sercomspi_write_CTRLA_DOPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DOPO);
- hri_sercomspi_write_CTRLA_DIPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DIPO);
-
- spi_m_sync_set_baudrate(&spi_flash_desc, samd_peripherals_spi_baudrate_to_baud_reg_value(SPI_FLASH_BAUDRATE));
-
- gpio_set_pin_direction(SPI_FLASH_CS_PIN, GPIO_DIRECTION_OUT);
- // There's already a pull-up on the board.
- gpio_set_pin_pull_mode(SPI_FLASH_CS_PIN, GPIO_PULL_OFF);
- gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF);
+ common_hal_digitalio_digitalinout_construct(&cs_pin, SPI_FLASH_CS_PIN);
// Set CS high (disabled).
- flash_disable();
+ common_hal_digitalio_digitalinout_switch_to_output(&cs_pin, true, DRIVE_MODE_PUSH_PULL);
- spi_m_sync_enable(&spi_flash_desc);
+ common_hal_busio_spi_construct(&spi, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN);
+ common_hal_busio_spi_never_reset(&spi);
}
void spi_flash_init_device(const external_flash_device* device) {
-
+ flash_device = device;
+ spi_flash_baudrate = device->max_clock_speed_mhz * 1000000;
+ if (spi_flash_baudrate > SPI_FLASH_MAX_BAUDRATE) {
+ spi_flash_baudrate = SPI_FLASH_MAX_BAUDRATE;
+ }
}
diff --git a/ports/atmel-samd/supervisor/filesystem.c b/supervisor/shared/filesystem.c
index 8a6010951..264ba25f0 100644
--- a/ports/atmel-samd/supervisor/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -30,10 +30,10 @@
#include "py/mpstate.h"
-#include "flash_api.h"
+#include "supervisor/flash.h"
-fs_user_mount_t fs_user_mount_flash;
-mp_vfs_mount_t mp_vfs_mount_flash;
+static mp_vfs_mount_t _mp_vfs;
+static fs_user_mount_t _internal_vfs;
static void make_empty_file(FATFS *fatfs, const char *path) {
FIL fp;
@@ -45,9 +45,9 @@ static void make_empty_file(FATFS *fatfs, const char *path) {
// want it to be executed without using stack within main() function
void filesystem_init(bool create_allowed, bool force_create) {
// init the vfs object
- fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
+ fs_user_mount_t *vfs_fat = &_internal_vfs;
vfs_fat->flags = 0;
- flash_init_vfs(vfs_fat);
+ supervisor_flash_init_vfs(vfs_fat);
// try to mount the flash
FRESULT res = f_mount(&vfs_fat->fatfs);
@@ -57,8 +57,9 @@ void filesystem_init(bool create_allowed, bool force_create) {
uint8_t working_buf[_MAX_SS];
res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
// Flush the new file system to make sure it's repaired immediately.
- flash_flush();
+ supervisor_flash_flush();
if (res != FR_OK) {
+ asm("bkpt");
return;
}
@@ -72,11 +73,12 @@ void filesystem_init(bool create_allowed, bool force_create) {
make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log");
// and ensure everything is flushed
- flash_flush();
+ supervisor_flash_flush();
} else if (res != FR_OK) {
+ asm("bkpt");
return;
}
- mp_vfs_mount_t *vfs = &mp_vfs_mount_flash;
+ mp_vfs_mount_t *vfs = &_mp_vfs;
vfs->str = "/";
vfs->len = 1;
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
@@ -89,11 +91,17 @@ void filesystem_init(bool create_allowed, bool force_create) {
}
void filesystem_flush(void) {
- flash_flush();
+ supervisor_flash_flush();
}
void filesystem_writable_by_python(bool writable) {
- flash_set_usb_writable(!writable);
+ fs_user_mount_t *vfs = &_internal_vfs;
+
+ if (writable) {
+ vfs->flags |= FSUSER_USB_WRITABLE;
+ } else {
+ vfs->flags &= ~FSUSER_USB_WRITABLE;
+ }
}
bool filesystem_present(void) {
diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c
new file mode 100644
index 000000000..4fa2d8f75
--- /dev/null
+++ b/supervisor/shared/flash.c
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft
+ *
+ * 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/flash.h"
+
+#include "extmod/vfs_fat.h"
+#include "py/runtime.h"
+#include "lib/oofatfs/ff.h"
+
+#define VFS_INDEX 0
+
+void supervisor_flash_set_usb_writable(bool usb_writable) {
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ for (uint8_t i = 0; current_mount != NULL; i++) {
+ if (i == VFS_INDEX) {
+ break;
+ }
+ current_mount = current_mount->next;
+ }
+ if (current_mount == NULL) {
+ return;
+ }
+ fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
+
+ if (usb_writable) {
+ vfs->flags |= FSUSER_USB_WRITABLE;
+ } else {
+ vfs->flags &= ~FSUSER_USB_WRITABLE;
+ }
+}
+
+// there is a singleton Flash object
+const mp_obj_type_t supervisor_flash_type;
+STATIC const mp_obj_base_t supervisor_flash_obj = {&supervisor_flash_type};
+
+STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+ // check arguments
+ mp_arg_check_num(n_args, n_kw, 0, 0, false);
+
+ // return singleton object
+ return (mp_obj_t)&supervisor_flash_obj;
+}
+
+STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
+ mp_uint_t ret = supervisor_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
+ return MP_OBJ_NEW_SMALL_INT(ret);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor_flash_obj_readblocks);
+
+STATIC mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
+ mp_uint_t ret = supervisor_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
+ return MP_OBJ_NEW_SMALL_INT(ret);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks);
+
+STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
+ mp_int_t cmd = mp_obj_get_int(cmd_in);
+ switch (cmd) {
+ case BP_IOCTL_INIT: supervisor_flash_init(); return MP_OBJ_NEW_SMALL_INT(0);
+ case BP_IOCTL_DEINIT: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly
+ case BP_IOCTL_SYNC: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0);
+ case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_count());
+ case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_size());
+ default: return mp_const_none;
+ }
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_ioctl_obj, supervisor_flash_obj_ioctl);
+
+STATIC const mp_rom_map_elem_t supervisor_flash_obj_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&supervisor_flash_obj_readblocks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&supervisor_flash_obj_writeblocks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&supervisor_flash_obj_ioctl_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(supervisor_flash_obj_locals_dict, supervisor_flash_obj_locals_dict_table);
+
+const mp_obj_type_t supervisor_flash_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Flash,
+ .make_new = supervisor_flash_obj_make_new,
+ .locals_dict = (mp_obj_t)&supervisor_flash_obj_locals_dict,
+};
+
+void supervisor_flash_init_vfs(fs_user_mount_t *vfs) {
+ vfs->base.type = &mp_fat_vfs_type;
+ vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->fatfs.drv = vfs;
+ vfs->fatfs.part = 1; // flash filesystem lives on first partition
+ vfs->readblocks[0] = (mp_obj_t)&supervisor_flash_obj_readblocks_obj;
+ vfs->readblocks[1] = (mp_obj_t)&supervisor_flash_obj;
+ vfs->readblocks[2] = (mp_obj_t)supervisor_flash_read_blocks; // native version
+ vfs->writeblocks[0] = (mp_obj_t)&supervisor_flash_obj_writeblocks_obj;
+ vfs->writeblocks[1] = (mp_obj_t)&supervisor_flash_obj;
+ vfs->writeblocks[2] = (mp_obj_t)supervisor_flash_write_blocks; // native version
+ vfs->u.ioctl[0] = (mp_obj_t)&supervisor_flash_obj_ioctl_obj;
+ vfs->u.ioctl[1] = (mp_obj_t)&supervisor_flash_obj;
+}
diff --git a/ports/atmel-samd/flash_api.c b/supervisor/shared/micropython.c
index b8a212718..245db11d4 100644
--- a/ports/atmel-samd/flash_api.c
+++ b/supervisor/shared/micropython.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2018 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,28 +24,35 @@
* THE SOFTWARE.
*/
-#include "flash_api.h"
+#include <string.h>
-#include "py/mpstate.h"
+#include "supervisor/serial.h"
+#include "lib/oofatfs/ff.h"
+#include "py/mpconfig.h"
-#define VFS_INDEX 0
+#include "supervisor/shared/status_leds.h"
-void flash_set_usb_writable(bool usb_writable) {
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- for (uint8_t i = 0; current_mount != NULL; i++) {
- if (i == VFS_INDEX) {
- break;
+int mp_hal_stdin_rx_chr(void) {
+ for (;;) {
+ #ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+ #endif
+ if (serial_bytes_available()) {
+ toggle_rx_led();
+ return serial_read();
}
- current_mount = current_mount->next;
}
- if (current_mount == NULL) {
- return;
- }
- fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
+}
- if (usb_writable) {
- vfs->flags |= FSUSER_USB_WRITABLE;
- } else {
- vfs->flags &= ~FSUSER_USB_WRITABLE;
+void mp_hal_stdout_tx_strn(const char *str, size_t len) {
+ toggle_tx_led();
+
+ #ifdef CIRCUITPY_BOOT_OUTPUT_FILE
+ if (boot_output_file != NULL) {
+ UINT bytes_written = 0;
+ f_write(boot_output_file, str, len, &bytes_written);
}
+ #endif
+
+ serial_write_substring(str, len);
}
diff --git a/supervisor/shared/rgb_led_status.h b/supervisor/shared/rgb_led_status.h
index 24e071aac..9542b3197 100644
--- a/supervisor/shared/rgb_led_status.h
+++ b/supervisor/shared/rgb_led_status.h
@@ -33,7 +33,7 @@
#include "lib/utils/pyexec.h"
#include "supervisor/port.h"
-#include "mpconfigport.h"
+#include "py/mpconfig.h"
#include "rgb_led_colors.h"
// Overall, the time module must be implemented.
diff --git a/ports/nrf/common-hal/storage/__init__.c b/supervisor/shared/serial.c
index 4ff5f0dac..058c4a7a4 100644
--- a/ports/nrf/common-hal/storage/__init__.c
+++ b/supervisor/shared/serial.c
@@ -26,22 +26,31 @@
#include <string.h>
-#include "py/mperrno.h"
-#include "py/runtime.h"
-#include "shared-bindings/microcontroller/__init__.h"
-#include "shared-bindings/storage/__init__.h"
-#include "supervisor/filesystem.h"
-
-extern volatile bool mp_msc_enabled;
-
-void common_hal_storage_remount(const char *mount_path, bool readonly) {
- if (strcmp(mount_path, "/") != 0) {
- mp_raise_OSError(MP_EINVAL);
- }
+#include "supervisor/serial.h"
+#include "supervisor/usb.h"
+
+#include "tusb.h"
+
+void serial_init(void) {
+ usb_init();
+}
+
+bool serial_connected(void) {
+ return tud_cdc_connected();
+}
+
+char serial_read(void) {
+ return (char) tud_cdc_read_char();
+}
+
+bool serial_bytes_available(void) {
+ return tud_cdc_available() > 0;
+}
+
+void serial_write(const char* text) {
+ tud_cdc_write(text, strlen(text));
}
-void common_hal_storage_erase_filesystem(void) {
- filesystem_init(false, true); // Force a re-format.
- common_hal_mcu_reset();
- // We won't actually get here, since we're resetting.
+void serial_write_substring(const char* text, uint32_t length) {
+ tud_cdc_write(text, length);
}
diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c
new file mode 100644
index 000000000..d99853ceb
--- /dev/null
+++ b/supervisor/shared/status_leds.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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/shared/status_leds.h"
+
+#include "common-hal/digitalio/DigitalInOut.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+
+#ifdef MICROPY_HW_LED_RX
+digitalio_digitalinout_obj_t rx_led;
+#endif
+
+#ifdef MICROPY_HW_LED_TX
+digitalio_digitalinout_obj_t tx_led;
+#endif
+
+void init_status_leds(void) {
+ #ifdef MICROPY_HW_LED_RX
+ common_hal_digitalio_digitalinout_construct(&rx_led, MICROPY_HW_LED_RX);
+ common_hal_digitalio_digitalinout_switch_to_output(&rx_led, true, DRIVE_MODE_PUSH_PULL);
+ #endif
+ #ifdef MICROPY_HW_LED_TX
+ common_hal_digitalio_digitalinout_construct(&tx_led, MICROPY_HW_LED_TX);
+ common_hal_digitalio_digitalinout_switch_to_output(&tx_led, true, DRIVE_MODE_PUSH_PULL);
+ #endif
+}
+
+void toggle_rx_led(void) {
+ #ifdef MICROPY_HW_LED_RX
+ common_hal_digitalio_digitalinout_set_value(&rx_led, !common_hal_digitalio_digitalinout_get_value(&rx_led));
+ #endif
+}
+
+
+void toggle_tx_led(void) {
+ #ifdef MICROPY_HW_LED_TX
+ common_hal_digitalio_digitalinout_set_value(&tx_led, !common_hal_digitalio_digitalinout_get_value(&tx_led));
+ #endif
+}
diff --git a/ports/atmel-samd/flash_api.h b/supervisor/shared/status_leds.h
index 3e41f59a2..30132753f 100644
--- a/ports/atmel-samd/flash_api.h
+++ b/supervisor/shared/status_leds.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2018 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
@@ -23,14 +23,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H
-#include "extmod/vfs_fat.h"
+#ifndef MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H
+#define MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H
-extern void flash_init_vfs(fs_user_mount_t *vfs);
-extern void flash_flush(void);
+void init_status_leds(void);
-void flash_set_usb_writable(bool usb_writable);
+void toggle_rx_led(void);
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H
+void toggle_tx_led(void);
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H
diff --git a/ports/nrf/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h
index 626b99eeb..649c390ac 100644
--- a/ports/nrf/usb/tusb_config.h
+++ b/supervisor/shared/usb/tusb_config.h
@@ -38,6 +38,8 @@
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
+#include "genhdr/autogen_usb_descriptor.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -45,7 +47,6 @@
//--------------------------------------------------------------------+
// COMMON CONFIGURATION
//--------------------------------------------------------------------+
-#define CFG_TUSB_MCU OPT_MCU_NRF5X
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#define CFG_TUSB_DEBUG 0
@@ -74,16 +75,12 @@
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
#define CFG_TUD_HID 1
+#define CFG_TUD_CUSTOM_CLASS 0
/*------------------------------------------------------------------*/
/* CLASS DRIVER
*------------------------------------------------------------------*/
-/*------------- CDC -------------*/
-// FIFO size of CDC TX and RX
-#define CFG_TUD_CDC_RX_BUFSIZE 1024
-#define CFG_TUD_CDC_TX_BUFSIZE 1024
-
/* TX is sent automatically on every Start of Frame event ~ 1ms.
* If not enabled, application must call tud_cdc_flush() periodically
* Note: Enabled this could overflow device task, if it does, define
@@ -99,17 +96,7 @@
// Number of Blocks
#define CFG_TUD_MSC_BLOCK_NUM (256*1024)/512
-// Block size
-#define CFG_TUD_MSC_BLOCK_SZ 512
-
-// Buffer size for each read/write transfer, the more the better
-#define CFG_TUD_MSC_BUFSIZE (4*1024)
-
-// Vendor name included in Inquiry response, max 8 bytes
-#define CFG_TUD_MSC_VENDOR "Adafruit"
-// Product name included in Inquiry response, max 16 bytes
-#define CFG_TUD_MSC_PRODUCT "CircuitPY nRF52"
// Product revision string included in Inquiry response, max 4 bytes
#define CFG_TUD_MSC_PRODUCT_REV "1.0"
diff --git a/ports/nrf/usb/usb.c b/supervisor/shared/usb/usb.c
index 248d31e21..1aa34e9e6 100644
--- a/ports/nrf/usb/usb.c
+++ b/supervisor/shared/usb/usb.c
@@ -24,79 +24,47 @@
* THE SOFTWARE.
*/
-#include "nrfx.h"
-#include "nrfx_power.h"
#include "tick.h"
-#include "usb.h"
+#include "shared-bindings/microcontroller/Processor.h"
+#include "supervisor/port.h"
+#include "supervisor/usb.h"
#include "lib/utils/interrupt_char.h"
#include "lib/mp-readline/readline.h"
-#ifdef SOFTDEVICE_PRESENT
-#include "nrf_sdm.h"
-#include "nrf_soc.h"
-#endif
-
-/* tinyusb function that handles power event (detected, ready, removed)
- * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
- */
-extern void tusb_hal_nrf_power_event(uint32_t event);
-
-void usb_init(void) {
-
- // USB power may already be ready at this time -> no event generated
- // We need to invoke the handler based on the status initially
- uint32_t usb_reg;
-
-#ifdef SOFTDEVICE_PRESENT
- uint8_t sd_en = false;
- (void) sd_softdevice_is_enabled(&sd_en);
-
- if ( sd_en ) {
- sd_power_usbdetected_enable(true);
- sd_power_usbpwrrdy_enable(true);
- sd_power_usbremoved_enable(true);
-
- sd_power_usbregstatus_get(&usb_reg);
- }else
-#endif
- {
- // Power module init
- const nrfx_power_config_t pwr_cfg = { 0 };
- nrfx_power_init(&pwr_cfg);
-
- // Register tusb function as USB power handler
- const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
- nrfx_power_usbevt_init(&config);
-
- nrfx_power_usbevt_enable();
-
- usb_reg = NRF_POWER->USBREGSTATUS;
- }
+#include "tusb.h"
- if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) {
- tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
- }
-
- if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) {
- tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
- }
+// Serial number as hex characters. This writes directly to the USB
+// descriptor.
+extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2];
+void load_serial_number(void) {
// create serial number based on device unique id
- extern uint16_t usb_desc_str_serial[1 + 16];
+ uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
+ common_hal_mcu_processor_get_uid(raw_id);
+
+ const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'};
+ for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
+ for (int j = 0; j < 2; j++) {
+ uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
+ // Strings are UTF-16-LE encoded.
+ usb_serial_number[1 + i * 2 + j] = nibble_to_hex[nibble];
+ }
+ }
+}
- char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+bool _usb_enabled = false;
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < 8; j++) {
- uint8_t nibble = (NRF_FICR->DEVICEID[i] >> j * 4) & 0xf;
+bool usb_enabled(void) {
+ return _usb_enabled;
+}
- // Invert order since it is LE, +1 for skipping descriptor header
- uint8_t const idx = (15 - (i * 8 + j)) + 1;
- usb_desc_str_serial[idx] = nibble_to_hex[nibble];
- }
- }
+void usb_init(void) {
+ init_usb_hardware();
+ load_serial_number();
tusb_init();
+ _usb_enabled = true;
#if MICROPY_KBD_EXCEPTION
// Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() callback will be invoked when Ctrl+C is received
@@ -105,6 +73,13 @@ void usb_init(void) {
#endif
}
+void usb_background(void) {
+ if (usb_enabled()) {
+ tusb_task();
+ tud_cdc_write_flush();
+ }
+}
+
//--------------------------------------------------------------------+
// tinyusb callbacks
//--------------------------------------------------------------------+
@@ -138,10 +113,7 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
if ( coding.bit_rate == 1200 )
{
- enum { DFU_MAGIC_SERIAL = 0x4e };
-
- NRF_POWER->GPREGRET = DFU_MAGIC_SERIAL;
- NVIC_SystemReset();
+ reset_to_bootloader();
}
}
}
@@ -166,4 +138,3 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char)
}
#endif
-
diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c
new file mode 100644
index 000000000..5a0de1ffc
--- /dev/null
+++ b/supervisor/shared/usb/usb_desc.c
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach 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/shared/usb/usb_desc.h"
+#include "shared-module/usb_hid/Device.h"
+
+#include "genhdr/autogen_usb_descriptor.h"
+
+// tud_desc_set is required by tinyusb stack
+tud_desc_set_t tud_desc_set =
+{
+ .device = &usb_desc_dev,
+ .config = &usb_desc_cfg,
+ .string_arr = (uint8_t const **) string_desc_arr,
+ .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]),
+
+ .hid_report =
+ {
+ .generic = hid_report_descriptor,
+ .boot_keyboard = NULL,
+ .boot_mouse = NULL
+ }
+};
diff --git a/ports/nrf/usb/usb.h b/supervisor/shared/usb/usb_desc.h
index 203260874..250147aa6 100644
--- a/ports/nrf/usb/usb.h
+++ b/supervisor/shared/usb/usb_desc.h
@@ -1,5 +1,5 @@
/*
- * This file is part of the Micro Python project, http://micropython.org/
+ * This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
@@ -24,11 +24,20 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_NRF_USB_H
-#define MICROPY_INCLUDED_NRF_USB_H
+#ifndef USB_DESC_H_
+#define USB_DESC_H_
-#include "tusb.h"
+#include "lib/tinyusb/src/tusb.h"
-void usb_init(void);
+#ifdef __cplusplus
+ extern "C" {
+#endif
-#endif // MICROPY_INCLUDED_NRF_USB_H
+// Descriptors set used by tinyusb stack
+extern tud_desc_set_t tud_desc_set;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* USB_DESC_H_ */
diff --git a/ports/nrf/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c
index f78c24145..13b5c3966 100644
--- a/ports/nrf/usb/usb_msc_flash.c
+++ b/supervisor/shared/usb/usb_msc_flash.c
@@ -25,37 +25,60 @@
*/
#include "tusb.h"
-#include "internal_flash.h"
+// // #include "supervisor/flash.h"
// For updating fatfs's cache
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
+#include "lib/oofatfs/diskio.h"
#include "lib/oofatfs/ff.h"
#include "py/mpstate.h"
#include "supervisor/shared/autoreload.h"
-/*------------------------------------------------------------------*/
-/* MACRO TYPEDEF CONSTANT ENUM
- *------------------------------------------------------------------*/
-#define MSC_FLASH_ADDR_END 0xED000
-#define MSC_FLASH_SIZE (256*1024)
-#define MSC_FLASH_ADDR_START (MSC_FLASH_ADDR_END-MSC_FLASH_SIZE)
#define MSC_FLASH_BLOCK_SIZE 512
-#define FL_PAGE_SZ 4096
+static bool ejected[1];
+
+// The root FS is always at the end of the list.
+static fs_user_mount_t* get_vfs(int lun) {
+ // TODO(tannewt): Return the mount which matches the lun where 0 is the end
+ // and is counted in reverse.
+ if (lun > 0) {
+ return NULL;
+ }
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ if (current_mount == NULL) {
+ return NULL;
+ }
+ while (current_mount->next != NULL) {
+ current_mount = current_mount->next;
+ }
+ return current_mount->obj;
+}
// Callback invoked when received an SCSI command not in built-in list below
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
-// - READ10 and WRITE10 has their own callbacks
+// - READ10 and WRITE10 have their own callbacks
int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) {
const void* response = NULL;
- uint16_t resplen = 0;
+ int32_t resplen = 0;
switch ( scsi_cmd[0] ) {
case SCSI_CMD_TEST_UNIT_READY:
// Command that host uses to check our readiness before sending other commands
resplen = 0;
+ if (lun > 1) {
+ resplen = -1;
+ } else {
+ fs_user_mount_t* current_mount = get_vfs(lun);
+ if (current_mount == NULL) {
+ resplen = -1;
+ }
+ if (ejected[lun]) {
+ resplen = -1;
+ }
+ }
break;
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
@@ -64,14 +87,28 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer,
break;
case SCSI_CMD_START_STOP_UNIT:
+ {
// Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
- /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
+ const scsi_start_stop_unit_t* start_stop = (const scsi_start_stop_unit_t*) scsi_cmd;
// Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
// Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
- start_stop->start;
- start_stop->load_eject;
- */
resplen = 0;
+ if (start_stop->load_eject == 1) {
+ if (lun > 1) {
+ resplen = -1;
+ } else {
+ fs_user_mount_t* current_mount = get_vfs(lun);
+ if (current_mount == NULL) {
+ resplen = -1;
+ }
+ if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) {
+ resplen = -1;
+ } else {
+ ejected[lun] = true;
+ }
+ }
+ }
+ }
break;
default:
@@ -96,6 +133,35 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer,
return resplen;
}
+bool tud_lun_capacity_cb(uint8_t lun, uint32_t* last_valid_sector, uint16_t* sector_size) {
+ fs_user_mount_t * vfs = get_vfs(lun);
+ if (vfs == NULL ||
+ disk_ioctl(vfs, GET_SECTOR_COUNT, last_valid_sector) != RES_OK ||
+ disk_ioctl(vfs, GET_SECTOR_SIZE, sector_size) != RES_OK) {
+ return false;
+ }
+ // Subtract one from the sector count to get the last valid sector.
+ (*last_valid_sector)--;
+
+ return true;
+}
+
+bool tud_msc_is_writable_cb(uint8_t lun) {
+ if (lun > 1) {
+ return false;
+ }
+
+ fs_user_mount_t* vfs = get_vfs(lun);
+ if (vfs == NULL) {
+ return false;
+ }
+ if (vfs->writeblocks[0] == MP_OBJ_NULL ||
+ (vfs->flags & FSUSER_USB_WRITABLE) == 0) {
+ return false;
+ }
+ return true;
+}
+
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
@@ -104,27 +170,36 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf
const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE;
- internal_flash_read_blocks(buffer, lba, block_count);
+ fs_user_mount_t * vfs = get_vfs(lun);
+ disk_read(vfs, buffer, lba, block_count);
return block_count * MSC_FLASH_BLOCK_SIZE;
}
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and return number of written bytes
-int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
+int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
(void) lun;
(void) offset;
const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE;
- // bufsize <= CFG_TUD_MSC_BUFSIZE (4096)
- internal_flash_write_blocks(buffer, lba, block_count);
-
- // update fatfs's cache if address matches
- fs_user_mount_t* vfs = MP_STATE_VM(vfs_mount_table)->obj;
-
- if ( (lba <= vfs->fatfs.winsect) && (vfs->fatfs.winsect <= (lba + bufsize / MSC_FLASH_BLOCK_SIZE)) ) {
- memcpy(vfs->fatfs.win, buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba), MSC_FLASH_BLOCK_SIZE);
+ fs_user_mount_t * vfs = get_vfs(lun);
+ disk_write(vfs, buffer, lba, block_count);
+ // Since by getting here we assume the mount is read-only to
+ // MicroPython let's update the cached FatFs sector if it's the one
+ // we just wrote.
+ #if _MAX_SS != _MIN_SS
+ if (vfs->ssize == MSC_FLASH_BLOCK_SIZE) {
+ #else
+ // The compiler can optimize this away.
+ if (_MAX_SS == FILESYSTEM_BLOCK_SIZE) {
+ #endif
+ if (lba == vfs->fatfs.winsect && lba > 0) {
+ memcpy(vfs->fatfs.win,
+ buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba),
+ MSC_FLASH_BLOCK_SIZE);
+ }
}
return block_count * MSC_FLASH_BLOCK_SIZE;
@@ -135,9 +210,6 @@ int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* bu
void tud_msc_write10_complete_cb (uint8_t lun) {
(void) lun;
- // flush pending cache when write10 is complete
- internal_flash_flush();
-
// This write is complete, start the autoreload clock.
autoreload_start();
}
diff --git a/ports/atmel-samd/external_flash/spi_flash_api.h b/supervisor/spi_flash_api.h
index a6df0c459..28cccb1b1 100644
--- a/ports/atmel-samd/external_flash/spi_flash_api.h
+++ b/supervisor/spi_flash_api.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,13 +23,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H
+#ifndef MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H
+#define MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H
#include <stdbool.h>
#include <stdint.h>
-#include "external_flash/devices.h"
+#include "supervisor/shared/external_flash/devices.h"
// This API is implemented for both normal SPI peripherals and QSPI peripherals.
@@ -42,4 +42,4 @@ bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length);
void spi_flash_init(void);
void spi_flash_init_device(const external_flash_device* device);
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H
+#endif // MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index e516dcb2d..ac982d277 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -2,22 +2,82 @@ SRC_SUPERVISOR = \
main.c \
supervisor/port.c \
supervisor/shared/autoreload.c \
+ supervisor/shared/filesystem.c \
+ supervisor/shared/flash.c \
+ supervisor/shared/micropython.c \
supervisor/shared/rgb_led_status.c \
supervisor/shared/stack.c \
+ supervisor/shared/status_leds.c \
supervisor/shared/translate.c
-ifeq ($(wildcard atmel-samd/supervisor/filesystem.c),)
- SRC_SUPERVISOR += supervisor/filesystem.c
+ifndef $(NO_USB)
+NO_USB = $(wildcard supervisor/usb.c)
+endif
+
+
+# Choose which flash filesystem impl to use.
+# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive.
+# But that might not be true in the future.)
+ifdef EXTERNAL_FLASH_DEVICES
+ CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \
+ -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT)
+
+ SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c
+ ifeq ($(SPI_FLASH_FILESYSTEM),1)
+ CFLAGS += -DSPI_FLASH_FILESYSTEM
+ SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c
+ endif
+ ifeq ($(QSPI_FLASH_FILESYSTEM),1)
+ CFLAGS += -DQSPI_FLASH_FILESYSTEM
+ SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c
+ endif
else
- SRC_SUPERVISOR += supervisor/stub/filesystem.c
+ SRC_SUPERVISOR += supervisor/internal_flash.c
endif
-ifeq ($(wildcard atmel-samd/supervisor/serial.c),)
- SRC_SUPERVISOR += supervisor/serial.c
+ifeq ($(USB),FALSE)
+ ifeq ($(wildcard supervisor/serial.c),)
+ SRC_SUPERVISOR += supervisor/stub/serial.c
+ else
+ SRC_SUPERVISOR += supervisor/serial.c
+ endif
else
- SRC_SUPERVISOR += supervisor/stub/serial.c
+ SRC_SUPERVISOR += lib/tinyusb/src/common/tusb_fifo.c \
+ lib/tinyusb/src/device/control.c \
+ lib/tinyusb/src/device/usbd.c \
+ lib/tinyusb/src/class/msc/msc_device.c \
+ lib/tinyusb/src/class/cdc/cdc_device.c \
+ lib/tinyusb/src/class/hid/hid_device.c \
+ lib/tinyusb/src/tusb.c \
+ supervisor/shared/serial.c \
+ supervisor/usb.c \
+ supervisor/shared/usb/usb_desc.c \
+ supervisor/shared/usb/usb.c \
+ supervisor/shared/usb/usb_msc_flash.c \
+ shared-bindings/usb_hid/__init__.c \
+ shared-bindings/usb_hid/Device.c \
+ shared-module/usb_hid/__init__.c \
+ shared-module/usb_hid/Device.c \
+ $(BUILD)/autogen_usb_descriptor.c
+ CFLAGS += -DUSB_AVAILABLE
endif
SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o))
$(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h
+
+$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: autogen_usb_descriptor.intermediate
+
+.INTERMEDIATE: autogen_usb_descriptor.intermediate
+
+autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD)
+ $(STEPECHO) "GEN $@"
+ $(Q)install -d $(BUILD)/genhdr
+ $(Q)$(PYTHON3) ../../tools/gen_usb_descriptor.py \
+ --manufacturer $(USB_MANUFACTURER)\
+ --product $(USB_PRODUCT)\
+ --vid $(USB_VID)\
+ --pid $(USB_PID)\
+ --serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\
+ --output_c_file $(BUILD)/autogen_usb_descriptor.c\
+ --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h
diff --git a/ports/atmel-samd/usb.h b/supervisor/usb.h
index f01c5ebfb..c87540d40 100644
--- a/ports/atmel-samd/usb.h
+++ b/supervisor/usb.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2018 hathach 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,19 +24,21 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_USB_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_USB_H
+#ifndef MICROPY_INCLUDED_SUPERVISOR_USB_H
+#define MICROPY_INCLUDED_SUPERVISOR_USB_H
#include <stdbool.h>
-#include <stdint.h>
-#define USB_RX_BUF_SIZE 128
+// Ports must call this as frequently as they can in order to keep the USB connection
+// alive and responsive.
+void usb_background(void);
-void init_usb(void);
-int usb_read(void);
-void usb_write(const char* buffer, uint32_t len);
-bool usb_bytes_available(void);
-bool usb_connected(void);
-void usb_cdc_background(void);
+// Only inits the USB peripheral clocks and pins. The peripheral will be initialized by
+// TinyUSB.
+void init_usb_hardware(void);
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_USB_H
+// Shared implementation.
+bool usb_enabled(void);
+void usb_init(void);
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_USB_H
diff --git a/ports/atmel-samd/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py
index efa8124bf..2cb06ec2f 100644
--- a/ports/atmel-samd/tools/gen_usb_descriptor.py
+++ b/tools/gen_usb_descriptor.py
@@ -3,10 +3,9 @@ import argparse
import os
import sys
-# path hacking
sys.path.append("../../tools/usb_descriptor")
-from adafruit_usb_descriptor import cdc, hid, msc, standard, util
+from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util
import hid_report_descriptors
parser = argparse.ArgumentParser(description='Generate USB descriptors.')
@@ -28,16 +27,21 @@ args = parser.parse_args()
class StringIndex:
"""Assign a monotonically increasing index to each unique string. Start with 0."""
string_to_index = {}
+ index_to_variable = {}
strings = []
@classmethod
- def index(cls, string):
+ def index(cls, string, *, variable_name = None):
if string in cls.string_to_index:
- return cls.string_to_index[string]
+ idx = cls.string_to_index[string]
+ if not cls.index_to_variable[idx]:
+ cls.index_to_variable[idx] = variable_name
+ return idx
else:
idx = len(cls.strings)
cls.string_to_index[string] = idx
cls.strings.append(string)
+ cls.index_to_variable[idx] = variable_name
return idx
@classmethod
@@ -47,9 +51,9 @@ class StringIndex:
# langid must be the 0th string descriptor
-LANGID_INDEX = StringIndex.index("\u0409")
+LANGID_INDEX = StringIndex.index("\u0409", variable_name="language_id")
assert LANGID_INDEX == 0
-SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length)
+SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length, variable_name="usb_serial_number")
device = standard.DeviceDescriptor(
description="top",
@@ -155,12 +159,6 @@ hid_endpoint_in_descriptor = standard.EndpointDescriptor(
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
bInterval=10)
-hid_endpoint_out_descriptor = standard.EndpointDescriptor(
- description="HID out",
- bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
- bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
- bInterval=10)
-
hid_interfaces = [
standard.InterfaceDescriptor(
description="HID Multiple Devices",
@@ -173,11 +171,71 @@ hid_interfaces = [
description="HID",
wDescriptorLength=len(bytes(combined_hid_report_descriptor))),
hid_endpoint_in_descriptor,
- hid_endpoint_out_descriptor,
]
),
]
+# Audio!
+midi_in_jack = midi.InJackDescriptor(
+ description="MIDI PC <- CircuitPython internals",
+ bJackType=midi.JACK_TYPE_EMBEDDED,
+ iJack=0)
+midi_out_jack = midi.OutJackDescriptor(
+ description="MIDI PC -> CircuitPython internals",
+ bJackType=midi.JACK_TYPE_EMBEDDED,
+ iJack=0)
+audio_midi_interface = standard.InterfaceDescriptor(
+ description="All the audio",
+ bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
+ bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING,
+ bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
+ iInterface=StringIndex.index("CircuitPython MIDI"),
+ subdescriptors=[
+ midi.Header(
+ jacks_and_elements=[
+ midi_in_jack,
+ midi.InJackDescriptor(
+ description="MIDI data in from user code.",
+ bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0),
+ midi_out_jack,
+ midi.OutJackDescriptor(
+ description="MIDI data out to user code.",
+ bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0),
+ ]
+ ),
+ standard.EndpointDescriptor(
+ description="MIDI data out",
+ bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
+ bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
+ midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack]),
+ standard.EndpointDescriptor(
+ description="MIDI data in",
+ bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
+ bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
+ midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack]),
+ ])
+
+cs_ac_interface = audio10.AudioControlInterface(
+ description="Empty audio control",
+ audio_streaming_interfaces = [],
+ midi_streaming_interfaces = [
+ audio_midi_interface
+ ]
+ )
+
+audio_control_interface = standard.InterfaceDescriptor(
+ description="All the audio",
+ bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
+ bInterfaceSubClass=audio.AUDIO_SUBCLASS_CONTROL,
+ bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
+ iInterface=StringIndex.index("CircuitPython Audio"),
+ subdescriptors=[
+ cs_ac_interface,
+ ])
+
+# Audio streaming interfaces must occur before MIDI ones.
+# audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces
+
# This will renumber the endpoints to make them unique across descriptors,
# and renumber the interfaces in order. But we still need to fix up certain
# interface cross-references.
@@ -194,23 +252,25 @@ cdc_iad = standard.InterfaceAssociationDescriptor(
description="CDC IAD",
bFirstInterface=cdc_comm_interface.bInterfaceNumber,
bInterfaceCount=len(cdc_interfaces),
- bFunctionClass=0x2, # Communications Device Class
- bFunctionSubClass=0x2, # Abstract control model
- bFunctionProtocol=0x1)
+ bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class
+ bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
+ bFunctionProtocol=cdc.CDC_PROTOCOL_NONE)
+
+# audio_iad = standard.InterfaceAssociationDescriptor(
+# description="Audio IAD",
+# bFirstInterface=audio_control_interface.bInterfaceNumber,
+# bInterfaceCount=len(audio_interfaces),
+# bFunctionClass=audio.AUDIO_CLASS_DEVICE,
+# bFunctionSubClass=audio.AUDIO_SUBCLASS_UNKNOWN,
+# bFunctionProtocol=audio.AUDIO_PROTOCOL_V1)
-configuration = standard.ConfigurationDescriptor(
- description="Composite configuration",
- wTotalLength=(standard.ConfigurationDescriptor.bLength +
- cdc_iad.bLength +
- sum([len(bytes(x)) for x in interfaces])),
- bNumInterfaces=len(interfaces))
descriptor_list = []
-descriptor_list.append(device)
-descriptor_list.append(configuration)
descriptor_list.append(cdc_iad)
+# descriptor_list.append(audio_iad)
descriptor_list.extend(cdc_interfaces)
descriptor_list.extend(msc_interfaces)
+# descriptor_list.append(audio_control_interface)
# Put the CDC IAD just before the CDC interfaces.
# There appears to be a bug in the Windows composite USB driver that requests the
# HID report descriptor with the wrong interface number if the HID interface is not given
@@ -219,9 +279,15 @@ descriptor_list.extend(msc_interfaces)
# there for backwards compatibility.
descriptor_list.extend(hid_interfaces)
+configuration = standard.ConfigurationDescriptor(
+ description="Composite configuration",
+ wTotalLength=(standard.ConfigurationDescriptor.bLength +
+ sum([len(bytes(x)) for x in descriptor_list])),
+ bNumInterfaces=len(interfaces))
+descriptor_list.insert(0, configuration)
+
string_descriptors = [standard.StringDescriptor(string) for string in StringIndex.strings_in_order()]
serial_number_descriptor = string_descriptors[SERIAL_NUMBER_INDEX]
-descriptor_list.extend(string_descriptors)
c_file = args.output_c_file
h_file = args.output_h_file
@@ -232,17 +298,29 @@ c_file.write("""\
#include "{H_FILE_NAME}"
-#include "usb/device/usbdc.h"
-
""".format(H_FILE_NAME=h_file.name))
c_file.write("""\
-uint8_t usb_descriptors[] = {
+// {DESCRIPTION} : {CLASS}
+""".format(DESCRIPTION=device.description,
+ CLASS=device.__class__))
+
+c_file.write("""\
+const uint8_t usb_desc_dev[] = {
+""")
+for b in bytes(device):
+ c_file.write("0x{:02x}, ".format(b))
+
+c_file.write("""\
+};
+""")
+
+c_file.write("""\
+const uint8_t usb_desc_cfg[] = {
""")
# Write out all the regular descriptors as one long array (that's how ASF4 does it).
descriptor_length = 0
-serial_number_offset = None
for descriptor in descriptor_list:
c_file.write("""\
// {DESCRIPTION} : {CLASS}
@@ -250,91 +328,140 @@ for descriptor in descriptor_list:
CLASS=descriptor.__class__))
b = bytes(descriptor)
+ notes = descriptor.notes()
i = 0
- if descriptor == serial_number_descriptor:
- # Add two for bLength and bDescriptorType.
- serial_number_offset = descriptor_length + 2
-
# This prints each subdescriptor on a separate line.
+ n = 0
while i < len(b):
length = b[i]
for j in range(length):
c_file.write("0x{:02x}, ".format(b[i + j]))
+ c_file.write("// " + notes[n])
+ n += 1
c_file.write("\n")
i += length
- descriptor_length += length
+ descriptor_length += len(b)
+c_file.write("""\
+};
+""")
+
+pointers_to_strings = []
+
+for idx, descriptor in enumerate(string_descriptors):
+ c_file.write("""\
+// {DESCRIPTION} : {CLASS}
+""".format(DESCRIPTION=descriptor.description,
+ CLASS=descriptor.__class__))
+
+ b = bytes(descriptor)
+ notes = descriptor.notes()
+ i = 0
+
+ # This prints each subdescriptor on a separate line.
+ variable_name = StringIndex.index_to_variable[idx]
+ if not variable_name:
+ variable_name = "string_descriptor{}".format(idx)
+
+ const = "const "
+ if variable_name == "usb_serial_number":
+ const = ""
+ c_file.write("""\
+{const}uint16_t {NAME}[] = {{
+""".format(const=const, NAME=variable_name))
+ pointers_to_strings.append("{name}".format(name=variable_name))
+ n = 0
+ while i < len(b):
+ length = b[i]
+ for j in range(length // 2):
+ c_file.write("0x{:04x}, ".format(b[i + 2*j + 1] << 8 | b[i + 2*j]))
+ n += 1
+ c_file.write("\n")
+ i += length
+ c_file.write("""\
+};
+""")
c_file.write("""\
+// array of pointer to string descriptors
+uint16_t const * const string_desc_arr [] =
+{
+""")
+c_file.write(""",\
+
+""".join(pointers_to_strings))
+
+c_file.write("""
};
""")
+c_file.write("\n");
+
+hid_descriptor_length = len(bytes(combined_hid_report_descriptor))
+
# Now we values we need for the .h file.
h_file.write("""\
#ifndef MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
#define MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
-#define SERIAL_NUMBER_OFFSET {SERIAL_NUMBER_OFFSET}
-#define SERIAL_NUMBER_LENGTH {SERIAL_NUMBER_LENGTH}
-uint8_t* serial_number;
+#include <stdint.h>
+
+const uint8_t usb_desc_dev[{device_length}];
+// Make sure the control buffer is big enough to fit the descriptor.
+#define CFG_TUD_ENUM_BUFFER_SIZE {max_configuration_length}
+const uint8_t usb_desc_cfg[{configuration_length}];
+uint16_t usb_serial_number[{serial_number_length}];
+uint16_t const * const string_desc_arr [{string_descriptor_length}];
+
+const uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTOR_LENGTH}];
+
+// Vendor name included in Inquiry response, max 8 bytes
+#define CFG_TUD_MSC_VENDOR "{msc_vendor}"
-uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTOR_LENGTH}];
-#define USB_HID_ENDPOINT_IN {HID_ENDPOINT_IN_ADDRESS}
-#define USB_HID_ENDPOINT_OUT {HID_ENDPOINT_OUT_ADDRESS}
+// Product name included in Inquiry response, max 16 bytes
+#define CFG_TUD_MSC_PRODUCT "{msc_product}"
"""
-.format(SERIAL_NUMBER_OFFSET=serial_number_offset,
- SERIAL_NUMBER_LENGTH=args.serial_number_length,
+.format(serial_number_length=len(bytes(serial_number_descriptor)) // 2,
+ device_length=len(bytes(device)),
+ configuration_length=descriptor_length,
+ max_configuration_length=max(hid_descriptor_length, descriptor_length),
+ string_descriptor_length=len(pointers_to_strings),
HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)),
- HID_ENDPOINT_IN_ADDRESS=hex(hid_endpoint_in_descriptor.bEndpointAddress),
- HID_ENDPOINT_OUT_ADDRESS=hex(hid_endpoint_out_descriptor.bEndpointAddress)))
-
-# Write out #define's that declare which endpoints are in use.
-# These provide information for declaring cache sizes and perhaps other things at compile time
-for interface in interfaces:
- for subdescriptor in interface.subdescriptors:
- if isinstance(subdescriptor, standard.EndpointDescriptor):
- endpoint_num = subdescriptor.bEndpointAddress & standard.EndpointDescriptor.NUMBER_MASK
- endpoint_in = ((subdescriptor.bEndpointAddress & standard.EndpointDescriptor.DIRECTION_MASK) ==
- standard.EndpointDescriptor.DIRECTION_IN)
- h_file.write("""\
-#define USB_ENDPOINT_{NUMBER}_{DIRECTION}_USED 1
-""".format(NUMBER=endpoint_num,
- DIRECTION="IN" if endpoint_in else "OUT"))
-
-h_file.write("\n")
+ msc_vendor=args.manufacturer[:8],
+ msc_product=args.product[:16]))
# #define the report ID's used in the combined HID descriptor
for name, id in hid_report_ids_dict.items():
h_file.write("""\
-#define USB_HID_REPORT_ID_{NAME} {ID}
-""".format(NAME=name,
- ID = id))
+#define USB_HID_REPORT_ID_{name} {id}
+""".format(name=name,
+ id=id))
h_file.write("\n")
# #define the report sizes used in the combined HID descriptor
for name, length in hid_report_lengths_dict.items():
h_file.write("""\
-#define USB_HID_REPORT_LENGTH_{NAME} {LENGTH}
-""".format(NAME=name,
- LENGTH=length))
+#define USB_HID_REPORT_LENGTH_{name} {length}
+""".format(name=name,
+ length=length))
h_file.write("\n")
h_file.write("""\
-#define USB_HID_NUM_DEVICES {NUM_DEVICES}
-#define USB_HID_MAX_REPORT_LENGTH {MAX_LENGTH}
-""".format(NUM_DEVICES=len(hid_report_lengths_dict),
- MAX_LENGTH=hid_max_report_length))
+#define USB_HID_NUM_DEVICES {num_devices}
+#define USB_HID_MAX_REPORT_LENGTH {max_length}
+""".format(num_devices=len(hid_report_lengths_dict),
+ max_length=hid_max_report_length))
# Write out the report descriptor and info
c_file.write("""\
-uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{
-""".format(HID_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor))))
+const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{
+""".format(HID_DESCRIPTOR_LENGTH=hid_descriptor_length))
for b in bytes(combined_hid_report_descriptor):
c_file.write("0x{:02x}, ".format(b))
@@ -342,12 +469,6 @@ c_file.write("""
};
""")
-c_file.write("""\
-
-struct usbd_descriptors descriptor_bounds = {{usb_descriptors, usb_descriptors + sizeof(usb_descriptors)}};
-uint8_t* serial_number = usb_descriptors + {SERIAL_NUMBER_OFFSET};
-""".format(SERIAL_NUMBER_OFFSET=serial_number_offset))
-
h_file.write("""\
#endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
""")
diff --git a/ports/atmel-samd/tools/hid_report_descriptors.py b/tools/hid_report_descriptors.py
index f3b28ebcf..f3b28ebcf 100644
--- a/ports/atmel-samd/tools/hid_report_descriptors.py
+++ b/tools/hid_report_descriptors.py
diff --git a/tools/usb_descriptor b/tools/usb_descriptor
-Subproject 2507847031a0395465956539253cbfa27f87511
+Subproject 57bf602dac9cba8c4226f764c286cbc60103d67