From 9d91111b1b6a1eee77a88b13faf695ee0c5caea3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 19 Oct 2018 18:46:22 -0700 Subject: [PATCH 1/5] Move atmel-samd to tinyusb and support nRF flash. This started while adding USB MIDI support (and descriptor support is in this change.) When seeing that I'd have to implement the MIDI class logic twice, once for atmel-samd and once for nrf, I decided to refactor the USB stack so its shared across ports. This has led to a number of changes that remove items from the ports folder and move them into supervisor. Furthermore, we had external SPI flash support for nrf pending so I factored out the connection between the usb stack and the flash API as well. This PR also includes the QSPI support for nRF. --- .gitmodules | 2 +- lib/tinyusb | 2 +- main.c | 3 + ports/atmel-samd/Makefile | 72 +--- ports/atmel-samd/background.c | 7 +- ports/atmel-samd/boards/arduino_zero/board.c | 7 - .../boards/arduino_zero/mpconfigboard.h | 8 +- .../circuitplayground_express/mpconfigboard.h | 39 +- .../mpconfigboard.mk | 2 + .../mpconfigboard.h | 40 +- .../mpconfigboard.mk | 2 + .../feather_m0_adalogger/mpconfigboard.h | 4 +- .../boards/feather_m0_basic/mpconfigboard.h | 4 +- .../boards/feather_m0_express/mpconfigboard.h | 37 +- .../feather_m0_express/mpconfigboard.mk | 2 + .../mpconfigboard.h | 38 +- .../mpconfigboard.mk | 2 + .../boards/feather_m0_rfm69/mpconfigboard.h | 4 +- .../boards/feather_m0_rfm9x/mpconfigboard.h | 4 +- .../feather_m0_supersized/mpconfigboard.h | 37 +- .../feather_m0_supersized/mpconfigboard.mk | 2 + .../boards/feather_m4_express/mpconfigboard.h | 7 - .../feather_m4_express/mpconfigboard.mk | 3 + .../feather_radiofruit_zigbee/mpconfigboard.h | 38 +- .../mpconfigboard.mk | 2 + .../boards/gemma_m0/mpconfigboard.h | 2 - .../boards/grandcentral_m4_express/board.c | 7 - .../grandcentral_m4_express/mpconfigboard.h | 11 +- .../grandcentral_m4_express/mpconfigboard.mk | 3 + .../hallowing_m0_express/mpconfigboard.h | 41 +- .../hallowing_m0_express/mpconfigboard.mk | 2 + .../itsybitsy_m0_express/mpconfigboard.h | 38 +- .../itsybitsy_m0_express/mpconfigboard.mk | 2 + .../itsybitsy_m4_express/mpconfigboard.h | 7 - .../itsybitsy_m4_express/mpconfigboard.mk | 2 + .../boards/meowmeow/mpconfigboard.h | 6 +- .../boards/metro_m0_express/mpconfigboard.h | 39 +- .../boards/metro_m0_express/mpconfigboard.mk | 4 + .../boards/metro_m4_express/board.c | 7 - .../boards/metro_m4_express/mpconfigboard.h | 19 +- .../boards/metro_m4_express/mpconfigboard.mk | 3 + .../boards/pirkey_m0/mpconfigboard.h | 2 - .../boards/trellis_m4_express/mpconfigboard.h | 7 - .../trellis_m4_express/mpconfigboard.mk | 2 + .../boards/trinket_m0/mpconfigboard.h | 2 - .../trinket_m0_haxpress/mpconfigboard.h | 42 +- .../trinket_m0_haxpress/mpconfigboard.mk | 2 + .../atmel-samd/boards/ugame10/mpconfigboard.h | 39 +- .../boards/ugame10/mpconfigboard.mk | 2 + ports/atmel-samd/common-hal/busio/SPI.c | 47 +++ ports/atmel-samd/common-hal/busio/SPI.h | 3 + .../common-hal/microcontroller/Pin.c | 15 +- .../common-hal/microcontroller/Pin.h | 1 + .../common-hal/microcontroller/__init__.c | 220 +++++++--- .../common-hal/supervisor/Runtime.c | 7 +- ports/atmel-samd/common-hal/usb_hid/Device.c | 106 ----- .../atmel-samd/common-hal/usb_hid/__init__.c | 152 ------- .../external_flash/external_flash.h | 64 --- ports/atmel-samd/mpconfigport.h | 10 +- ports/atmel-samd/mpconfigport.mk | 2 +- ports/atmel-samd/mphalport.c | 34 -- ports/atmel-samd/mphalport.h | 2 - ports/atmel-samd/peripherals | 2 +- ports/atmel-samd/reset.c | 4 - .../{ => supervisor}/internal_flash.c | 110 +---- .../{ => supervisor}/internal_flash.h | 0 .../supervisor/internal_flash_root_pointers.h | 31 ++ ports/atmel-samd/supervisor/port.c | 39 +- .../qspi_flash.c | 20 +- ports/atmel-samd/supervisor/serial.c | 79 ---- ports/atmel-samd/supervisor/usb.c | 59 +++ ports/atmel-samd/tick.h | 2 +- ports/atmel-samd/usb.c | 326 --------------- ports/atmel-samd/usb_mass_storage.c | 338 --------------- ports/atmel-samd/usb_mass_storage.h | 48 --- ports/esp8266/Makefile | 2 - ports/esp8266/mpconfigport.h | 2 - ports/nrf/Makefile | 48 +-- ports/nrf/README.md | 2 +- ports/nrf/background.c | 11 +- ports/nrf/board_busses.c | 2 +- .../boards/feather_nrf52840_express/board.c | 2 - .../feather_nrf52840_express/mpconfigboard.h | 23 +- .../feather_nrf52840_express/mpconfigboard.mk | 9 + .../boards/makerdiary_nrf52840_mdk/board.c | 2 - .../makerdiary_nrf52840_mdk/mpconfigboard.h | 25 +- .../makerdiary_nrf52840_mdk/mpconfigboard.mk | 9 + ports/nrf/boards/pca10056/board.c | 2 - ports/nrf/boards/pca10056/mpconfigboard.h | 23 + ports/nrf/boards/pca10056/mpconfigboard.mk | 9 + ports/nrf/boards/pca10059/board.c | 5 - ports/nrf/boards/pca10059/mpconfigboard.mk | 5 + ports/nrf/common-hal/busio/SPI.c | 18 + ports/nrf/common-hal/busio/UART.c | 2 +- ports/nrf/common-hal/digitalio/DigitalInOut.c | 5 + ports/nrf/common-hal/microcontroller/Pin.c | 13 +- ports/nrf/common-hal/microcontroller/Pin.h | 1 + .../common-hal/microcontroller/Processor.c | 7 +- ports/nrf/common-hal/pulseio/PulseIn.c | 2 +- ports/nrf/common-hal/pulseio/PulseOut.c | 2 +- ports/nrf/common-hal/usb_hid/Device.h | 94 ----- ports/nrf/internal_flash.c | 226 ---------- ports/nrf/mpconfigport.h | 5 +- ports/nrf/mpconfigport.mk | 1 + ports/nrf/mphalport.c | 81 ---- ports/nrf/nrfx_config.h | 3 + ports/nrf/peripherals/nrf/timers.c | 2 +- ports/nrf/supervisor/filesystem.c | 97 ----- ports/nrf/supervisor/internal_flash.c | 121 ++++++ ports/nrf/{ => supervisor}/internal_flash.h | 19 +- .../supervisor/internal_flash_root_pointers.h | 31 ++ ports/nrf/supervisor/port.c | 7 + ports/nrf/supervisor/qspi_flash.c | 146 +++++++ ports/nrf/supervisor/serial.c | 56 +-- ports/nrf/supervisor/usb.c | 83 ++++ ports/nrf/tick.h | 2 +- ports/nrf/usb/usb_desc.c | 393 ------------------ ports/nrf/usb/usb_desc.h | 87 ---- shared-bindings/busio/SPI.h | 3 + shared-bindings/usb_hid/Device.h | 2 +- shared-module/bitbangio/SPI.c | 3 +- shared-module/storage/__init__.c | 26 ++ .../usb_hid/Device.c | 2 +- .../usb_hid/Device.h | 28 +- .../usb_hid/__init__.c | 34 +- supervisor/flash.h | 54 +++ supervisor/flash_root_pointers.h | 35 ++ supervisor/port.h | 3 + supervisor/serial.h | 10 + .../shared}/external_flash/common_commands.h | 1 + .../shared}/external_flash/devices.h | 68 ++- .../shared}/external_flash/external_flash.c | 104 +---- .../shared/external_flash/external_flash.h | 41 +- .../external_flash_root_pointers.h | 35 ++ .../shared/external_flash/qspi_flash.c | 50 ++- supervisor/shared/external_flash/qspi_flash.h | 31 ++ .../shared}/external_flash/spi_flash.c | 106 +++-- .../shared}/filesystem.c | 28 +- supervisor/shared/flash.c | 123 ++++++ supervisor/shared/micropython.c | 58 +++ supervisor/shared/rgb_led_status.h | 2 +- .../__init__.c => supervisor/shared/serial.c | 37 +- supervisor/shared/status_leds.c | 62 +++ .../shared/status_leds.h | 16 +- .../shared}/usb/tusb_config.h | 18 +- {ports/nrf => supervisor/shared}/usb/usb.c | 103 ++--- supervisor/shared/usb/usb_desc.c | 46 ++ .../usb.h => supervisor/shared/usb/usb_desc.h | 21 +- .../shared}/usb/usb_msc_flash.c | 114 +++-- .../spi_flash_api.h | 10 +- supervisor/supervisor.mk | 70 +++- {ports/atmel-samd => supervisor}/usb.h | 26 +- .../tools => tools}/gen_usb_descriptor.py | 279 +++++++++---- .../tools => tools}/hid_report_descriptors.py | 0 tools/usb_descriptor | 2 +- 155 files changed, 2226 insertions(+), 3490 deletions(-) delete mode 100644 ports/atmel-samd/common-hal/usb_hid/Device.c delete mode 100644 ports/atmel-samd/common-hal/usb_hid/__init__.c delete mode 100644 ports/atmel-samd/external_flash/external_flash.h rename ports/atmel-samd/{ => supervisor}/internal_flash.c (52%) rename ports/atmel-samd/{ => supervisor}/internal_flash.h (100%) create mode 100644 ports/atmel-samd/supervisor/internal_flash_root_pointers.h rename ports/atmel-samd/{external_flash => supervisor}/qspi_flash.c (93%) delete mode 100644 ports/atmel-samd/supervisor/serial.c create mode 100644 ports/atmel-samd/supervisor/usb.c delete mode 100644 ports/atmel-samd/usb.c delete mode 100644 ports/atmel-samd/usb_mass_storage.c delete mode 100644 ports/atmel-samd/usb_mass_storage.h delete mode 100644 ports/nrf/common-hal/usb_hid/Device.h delete mode 100644 ports/nrf/internal_flash.c delete mode 100644 ports/nrf/supervisor/filesystem.c create mode 100644 ports/nrf/supervisor/internal_flash.c rename ports/nrf/{ => supervisor}/internal_flash.h (72%) create mode 100644 ports/nrf/supervisor/internal_flash_root_pointers.h create mode 100644 ports/nrf/supervisor/qspi_flash.c create mode 100644 ports/nrf/supervisor/usb.c delete mode 100644 ports/nrf/usb/usb_desc.c delete mode 100644 ports/nrf/usb/usb_desc.h rename {ports/nrf/common-hal => shared-module}/usb_hid/Device.c (98%) rename {ports/atmel-samd/common-hal => shared-module}/usb_hid/Device.h (73%) rename {ports/nrf/common-hal => shared-module}/usb_hid/__init__.c (88%) create mode 100644 supervisor/flash.h create mode 100644 supervisor/flash_root_pointers.h rename {ports/atmel-samd => supervisor/shared}/external_flash/common_commands.h (98%) rename {ports/atmel-samd => supervisor/shared}/external_flash/devices.h (85%) rename {ports/atmel-samd => supervisor/shared}/external_flash/external_flash.c (83%) rename ports/atmel-samd/flash_api.c => supervisor/shared/external_flash/external_flash.h (62%) create mode 100644 supervisor/shared/external_flash/external_flash_root_pointers.h rename ports/atmel-samd/common-hal/storage/__init__.c => supervisor/shared/external_flash/qspi_flash.c (51%) create mode 100644 supervisor/shared/external_flash/qspi_flash.h rename {ports/atmel-samd => supervisor/shared}/external_flash/spi_flash.c (55%) rename {ports/atmel-samd/supervisor => supervisor/shared}/filesystem.c (85%) create mode 100644 supervisor/shared/flash.c create mode 100644 supervisor/shared/micropython.c rename ports/nrf/common-hal/storage/__init__.c => supervisor/shared/serial.c (69%) create mode 100644 supervisor/shared/status_leds.c rename ports/atmel-samd/flash_api.h => supervisor/shared/status_leds.h (76%) rename {ports/nrf => supervisor/shared}/usb/tusb_config.h (87%) rename {ports/nrf => supervisor/shared}/usb/usb.c (59%) create mode 100644 supervisor/shared/usb/usb_desc.c rename ports/nrf/usb/usb.h => supervisor/shared/usb/usb_desc.h (78%) rename {ports/nrf => supervisor/shared}/usb/usb_msc_flash.c (58%) rename {ports/atmel-samd/external_flash => supervisor}/spi_flash_api.h (87%) rename {ports/atmel-samd => supervisor}/usb.h (69%) rename {ports/atmel-samd/tools => tools}/gen_usb_descriptor.py (57%) rename {ports/atmel-samd/tools => tools}/hid_report_descriptors.py (100%) diff --git a/.gitmodules b/.gitmodules index 38b6ea5dfd..1c1f8eb65d 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 index 33c61bfda2..30e3c64134 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 33c61bfda2c3aada3cb06d36e12d7cf57da02037 +Subproject commit 30e3c64134789416e10ed867fa12c210b808e98f diff --git a/main.c b/main.c index c1379c5716..ac55b72ba1 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 7861f4235b..552be92be8 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 3cf6831a33..099cb8b23e 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_zero/board.c b/ports/atmel-samd/boards/arduino_zero/board.c index 2dc1683eaf..770bc82593 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 1382d4736f..56e4dbcec7 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_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 5077840cba..6dfaf87e91 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -8,52 +8,25 @@ #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 - -// 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 831106adc8..e5665afb67 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 638a6646c6..250300858d 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 - -// 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 972c4b10dc..b07d63984d 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 c8b5c56ee5..c28c4aafbf 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 dcac9749df..d66efb36f8 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 03d0ba9bd3..1f02ee9953 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 -// 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 e9f9b09fbe..57ce96285d 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 7564620136..b5544e2539 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 -// 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 7ff5337a34..f773bcb57b 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 4a530ed29d..c385a97eab 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 3a6f28c12c..1e3a0bda0c 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 a7a2d7de0e..6bf1df1566 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 -// 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 79bf2d34a2..4bae6ffa72 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 e9e921b4d2..98906a8446 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 bbc5985a96..3f2cb6ce47 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 32c549953d..c4e0251784 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 -// 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 42177d274b..634a9ede77 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 1ec2170964..08d1803f2b 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 360b5d8f98..7599f02b8e 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 231bf20e05..0d2d65ba54 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 3e8717ecf8..2605c9f555 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 8450882b95..7dd4bf7c43 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h @@ -3,51 +3,22 @@ #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 -// 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 ) +#define MICROPY_PORT_A ( PORT_PA01 | PORT_PA12 | PORT_PA27 | PORT_PA28) +#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 817d93943e..37f1bdef0b 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 f56f57c46a..4de28d3882 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 -// 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 9f62ae8391..8fcf5208f0 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 e47d5390db..5bbfec9ce0 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 27f5ea2b88..2afff59654 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 3ce00b04f7..f07eb9cce3 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 40ef3ce78b..28bb1f2931 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h @@ -1,37 +1,22 @@ #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 +//#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 -// 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 (PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31) +#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 +25,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 40a0092ac7..49a94144b6 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 a98385d295..0f60736a24 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 f1201c8a0a..06feb1a226 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 cbc89159f4..6338563623 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 15979ae778..cbbd4b569f 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 1464d100c8..6870b86ba0 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 3841a87c76..7094b79be8 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 9036f8e7b7..24f3004e90 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -9,8 +9,6 @@ #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 8e3fdd7a8b..dfbd873b6f 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 -// 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 d97aa08ab4..c9c196da7b 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 ed822952d4..c22a3f7351 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 -// 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 2386531f91..6dc0af9cfb 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 a292f9e3d3..4de34c975c 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 2fced6d642..56d163a9d8 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 0f179a6c1a..9af5aeaf7b 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -43,8 +43,12 @@ 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); @@ -53,6 +57,11 @@ void reset_all_pins(void) { pin_mask[0] &= ~(PORT_PA31); #endif + for (uint32_t i = 0; i < PORT_COUNT; i++) { + pin_mask[i] &= ~(PORT_PA31); + 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); #if PORT_BITS > 64 @@ -91,6 +100,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 dcd80997e2..f798ea300c 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 746207787c..0ca3a08355 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 2636fe6465..ea663f897d 100755 --- a/ports/atmel-samd/common-hal/supervisor/Runtime.c +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c @@ -26,13 +26,12 @@ #include #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 31bace0189..0000000000 --- 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 - -#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 770d221c7c..0000000000 --- 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 f8ec5673ce..0000000000 --- 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 - -#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 a4c763d059..3b95aefa9a 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 d5c9f2ce6e..7db581dd63 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 a4eca1c748..ac5b0fbcab 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 3bc824d4e9..64269b201f 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 index d0dcba251c..f20fcf642b 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit d0dcba251c27f629c0a89b5ced4433dd0a609ca3 +Subproject commit f20fcf642b5654ee68d7d551ea7db39716ef83bf diff --git a/ports/atmel-samd/reset.c b/ports/atmel-samd/reset.c index ba5bf9ba1f..735639cc4d 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 similarity index 52% rename from ports/atmel-samd/internal_flash.c rename to ports/atmel-samd/supervisor/internal_flash.c index 35eb52da23..bf12ad0cd4 100644 --- a/ports/atmel-samd/internal_flash.c +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -23,7 +23,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "internal_flash.h" #include #include @@ -42,9 +41,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 +60,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 +124,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 +149,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 +171,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 +190,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 similarity index 100% rename from ports/atmel-samd/internal_flash.h rename to ports/atmel-samd/supervisor/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 0000000000..3e9148ce0a --- /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 45b8ed1a4c..9f951b0355 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 similarity index 93% rename from ports/atmel-samd/external_flash/qspi_flash.c rename to ports/atmel-samd/supervisor/qspi_flash.c index f6dc00d508..eca47b1648 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 #include #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); + check_quad_enable(device); - // 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); - } - } + // 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 4917dfb5b2..0000000000 --- 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 - -#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 0000000000..d13ca0ef13 --- /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 80e7bc9afb..c8c8d739ab 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 1f1ba550f7..0000000000 --- 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 - -// 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 9b6715158c..0000000000 --- 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 - -#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, §or_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/atmel-samd/usb_mass_storage.h b/ports/atmel-samd/usb_mass_storage.h deleted file mode 100644 index 767a6779ca..0000000000 --- a/ports/atmel-samd/usb_mass_storage.h +++ /dev/null @@ -1,48 +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. - */ - -// 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. - -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H -#define MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H - -#include - -// "background" task that actually manages loading to and from the file systems. -void usb_msc_background(void); - -// 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); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 3b6cc1fb48..03d5a65cbd 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 eca3f525df..435f2c5cd2 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 25ddebc576..8d0d6d000f 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 4bd865400b..34e58cb78e 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 d19604f680..f614b6bd03 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 91f0def6d3..6d5cbd041e 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 a6d050fce2..4421970eef 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 bd6d4b2449..68914c6261 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 caf580ec4d..f03109319f 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 a6d050fce2..4421970eef 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 b33fb2dd62..40b6487ecf 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 caf580ec4d..84dff0bc4d 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 a6d050fce2..4421970eef 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 00a73005c5..83c3f66c1e 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 caf580ec4d..49c708cff2 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 cbb4ef3b6d..4421970eef 100644 --- a/ports/nrf/boards/pca10059/board.c +++ b/ports/nrf/boards/pca10059/board.c @@ -24,14 +24,9 @@ * THE SOFTWARE. */ -#include -#include #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 f399927fd2..030c9a823a 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 f094b7f240..19bd4d1ba9 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 b9e79381ab..516a7747d7 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 f05cf568f7..0836962c63 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 7a069eedaa..0522bfef3b 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 2cdf440b58..61be8bc358 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 2ce3e8bf5e..e4d9439c99 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 950cc877d6..3d6d266af3 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -28,7 +28,7 @@ #include -#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 044c4d3a8d..be5deca9fb 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -28,7 +28,7 @@ #include -#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 612423715c..0000000000 --- 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 -#include - -#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 812ef4d3f5..0000000000 --- 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 -#include - -#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 8b193fb595..c9c03427f3 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 diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 17304b783b..f43e29fce1 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 e9a8722c6b..73f38bada8 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 69b8e6a0cb..1d3085e2b8 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 0027d526f4..7f7a003d3b 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 b6611417d7..0000000000 --- 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 0000000000..a648afa173 --- /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 +#include + +#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 similarity index 72% rename from ports/nrf/internal_flash.h rename to ports/nrf/supervisor/internal_flash.h index 3811815e29..adcb9bbc2f 100644 --- a/ports/nrf/internal_flash.h +++ b/ports/nrf/supervisor/internal_flash.h @@ -29,7 +29,7 @@ #include #include -#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 0000000000..cc6074585e --- /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 f98b05f5a4..fcb3ae55c6 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 0000000000..24b06c420b --- /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 +#include + +#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 c7744fd79e..6fd89eb3ea 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 #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(); -} - -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() -} - -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; + return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY); } void serial_write(const char* text) { - tud_cdc_write(text, strlen(text)); + serial_write_substring(text, strlen(text)); +} + +void serial_write_substring(const char *text, uint32_t len) { + if (len == 0) { + return; + } + + // 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); + } + + nrfx_uarte_tx(&serial_instance, tx_buf, len); + + 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 0000000000..a67c9311ac --- /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 73f17d7031..838e9fbea8 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 diff --git a/ports/nrf/usb/usb_desc.c b/ports/nrf/usb/usb_desc.c deleted file mode 100644 index 10d603528b..0000000000 --- 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 19f3f6d5bf..0000000000 --- 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/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 555f32c928..2d12b8b764 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 2bc553c4a2..cb9a64b5ea 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 9e45083552..6d3a285231 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 edce286b1f..f09edd7858 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 similarity index 98% rename from ports/nrf/common-hal/usb_hid/Device.c rename to shared-module/usb_hid/Device.c index 6acb2717f3..820e14ad0b 100644 --- a/ports/nrf/common-hal/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -26,9 +26,9 @@ #include #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 similarity index 73% rename from ports/atmel-samd/common-hal/usb_hid/Device.h rename to shared-module/usb_hid/Device.h index b81c0e7091..10f2ee897d 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 #include #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[]; -#endif // COMMON_HAL_USB_HID_DEVICE_H +#ifdef __cplusplus + } +#endif + +#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 similarity index 88% rename from ports/nrf/common-hal/usb_hid/__init__.c rename to shared-module/usb_hid/__init__.c index 00fc8bd002..c0f9c897ca 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 +#if 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 +#if 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 +#if 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 +#if 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 +#if 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 +#if USB_HID_REPORT_ID_DIGITIZER { .base = { .type = &usb_hid_device_type } , .report_buffer = digitizer_report_buffer , diff --git a/supervisor/flash.h b/supervisor/flash.h new file mode 100644 index 0000000000..ae6a44fd01 --- /dev/null +++ b/supervisor/flash.h @@ -0,0 +1,54 @@ +/* + * 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_SUPERVISOR_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_FLASH_H + +#include +#include + +#include "py/mpconfig.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); + +// 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); + +struct _fs_user_mount_t; +void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs); +void supervisor_flash_flush(void); + +#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 0000000000..634ae58d3f --- /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 f30d87b47b..dd4a82209d 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 9446ee71cf..84b3062a3b 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -30,8 +30,18 @@ #include #include +#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 similarity index 98% rename from ports/atmel-samd/external_flash/common_commands.h rename to supervisor/shared/external_flash/common_commands.h index d82d2c046f..cc0da21759 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 similarity index 85% rename from ports/atmel-samd/external_flash/devices.h rename to supervisor/shared/external_flash/devices.h index 58da2e5092..06fc178cb8 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 similarity index 83% rename from ports/atmel-samd/external_flash/external_flash.c rename to supervisor/shared/external_flash/external_flash.c index b4a637be43..defdfa393f 100644 --- a/ports/atmel-samd/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -28,8 +28,8 @@ #include #include -#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/ports/atmel-samd/flash_api.c b/supervisor/shared/external_flash/external_flash.h similarity index 62% rename from ports/atmel-samd/flash_api.c rename to supervisor/shared/external_flash/external_flash.h index b8a2127188..852d183a7f 100644 --- a/ports/atmel-samd/flash_api.c +++ b/supervisor/shared/external_flash/external_flash.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 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,29 +23,26 @@ * 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 "flash_api.h" +#include +#include -#include "py/mpstate.h" +#include "py/mpconfig.h" -#define VFS_INDEX 0 +// Erase sector size. +#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100) -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; - } - current_mount = current_mount->next; - } - if (current_mount == NULL) { - return; - } - fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj; +// These are common across all NOR Flash. +#define SPI_FLASH_ERASE_SIZE (1 << 12) +#define SPI_FLASH_PAGE_SIZE (256) - if (usb_writable) { - vfs->flags |= FSUSER_USB_WRITABLE; - } else { - vfs->flags &= ~FSUSER_USB_WRITABLE; - } -} +#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 0000000000..cb1b86d193 --- /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 + +// 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 similarity index 51% rename from ports/atmel-samd/common-hal/storage/__init__.c rename to supervisor/shared/external_flash/qspi_flash.c index 501a19dd79..48266540c4 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 +#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 0000000000..b72e37b268 --- /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 similarity index 55% rename from ports/atmel-samd/external_flash/spi_flash.c rename to supervisor/shared/external_flash/spi_flash.c index 273915df72..ec7101bc91 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 #include -#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 similarity index 85% rename from ports/atmel-samd/supervisor/filesystem.c rename to supervisor/shared/filesystem.c index 8a6010951f..264ba25f09 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 0000000000..4fa2d8f75e --- /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/supervisor/shared/micropython.c b/supervisor/shared/micropython.c new file mode 100644 index 0000000000..245db11d42 --- /dev/null +++ b/supervisor/shared/micropython.c @@ -0,0 +1,58 @@ +/* + * 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 + +#include "supervisor/serial.h" +#include "lib/oofatfs/ff.h" +#include "py/mpconfig.h" + +#include "supervisor/shared/status_leds.h" + +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(); + } + } +} + +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 24e071aac1..9542b31972 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 similarity index 69% rename from ports/nrf/common-hal/storage/__init__.c rename to supervisor/shared/serial.c index 4ff5f0dac9..058c4a7a4b 100644 --- a/ports/nrf/common-hal/storage/__init__.c +++ b/supervisor/shared/serial.c @@ -26,22 +26,31 @@ #include -#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/serial.h" +#include "supervisor/usb.h" -extern volatile bool mp_msc_enabled; +#include "tusb.h" -void common_hal_storage_remount(const char *mount_path, bool readonly) { - if (strcmp(mount_path, "/") != 0) { - mp_raise_OSError(MP_EINVAL); - } +void serial_init(void) { + usb_init(); } -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. +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 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 0000000000..d99853cebe --- /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 similarity index 76% rename from ports/atmel-samd/flash_api.h rename to supervisor/shared/status_leds.h index 3e41f59a24..30132753f3 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 similarity index 87% rename from ports/nrf/usb/tusb_config.h rename to supervisor/shared/usb/tusb_config.h index 626b99eeb2..4693bfcedb 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 @@ -79,11 +80,6 @@ /* 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 +95,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 similarity index 59% rename from ports/nrf/usb/usb.c rename to supervisor/shared/usb/usb.c index 248d31e213..1aa34e9e6f 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 +#include "tusb.h" -/* 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; - } - - 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); - 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 < 2; i++) { - for (int j = 0; j < 8; j++) { - uint8_t nibble = (NRF_FICR->DEVICEID[i] >> j * 4) & 0xf; - - // 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]; + 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]; } } +} + +bool _usb_enabled = false; + +bool usb_enabled(void) { + return _usb_enabled; +} + +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 0000000000..5a0de1ffc8 --- /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 similarity index 78% rename from ports/nrf/usb/usb.h rename to supervisor/shared/usb/usb_desc.h index 2032608749..250147aa66 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 similarity index 58% rename from ports/nrf/usb/usb_msc_flash.c rename to supervisor/shared/usb/usb_msc_flash.c index f78c241455..72dc40204c 100644 --- a/ports/nrf/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -25,29 +25,39 @@ */ #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 +// 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; @@ -56,6 +66,14 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, 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; + } + } break; case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: @@ -64,14 +82,23 @@ 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; + } + } + } + } break; default: @@ -96,6 +123,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 +160,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 +200,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 similarity index 87% rename from ports/atmel-samd/external_flash/spi_flash_api.h rename to supervisor/spi_flash_api.h index a6df0c4595..28cccb1b1a 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 #include -#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 e516dcb2da..d870f799fa 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -2,22 +2,78 @@ 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 -else - SRC_SUPERVISOR += supervisor/stub/filesystem.c +ifndef $(NO_USB) +NO_USB = $(wildcard supervisor/usb.c) endif -ifeq ($(wildcard atmel-samd/supervisor/serial.c),) - SRC_SUPERVISOR += supervisor/serial.c + +# 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/serial.c + SRC_SUPERVISOR += supervisor/internal_flash.c +endif + +ifeq ($(USB),FALSE) + ifeq ($(wildcard supervisor/serial.c),) + SRC_SUPERVISOR += supervisor/stub/serial.c + else + SRC_SUPERVISOR += supervisor/serial.c + endif +else + 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: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) + $(STEPECHO) "GEN $@" + $(Q)install -d $(BUILD)/genhdr + $(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 similarity index 69% rename from ports/atmel-samd/usb.h rename to supervisor/usb.h index f01c5ebfb7..c87540d408 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 -#include -#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 similarity index 57% rename from ports/atmel-samd/tools/gen_usb_descriptor.py rename to tools/gen_usb_descriptor.py index efa8124bfa..b50c0798ff 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", @@ -76,7 +80,7 @@ cdc_comm_interface = standard.InterfaceDescriptor( description="CDC comm", bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, + bInterfaceProtocol=cdc.CDC_PROTOCOL_V25TER, iInterface=StringIndex.index("CircuitPython CDC control"), subdescriptors=[ cdc.Header( @@ -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_V25TER) # TODO(tannewt): can this be NONE (aka 0)? + +# 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 -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} +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}" + +// 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 similarity index 100% rename from ports/atmel-samd/tools/hid_report_descriptors.py rename to tools/hid_report_descriptors.py diff --git a/tools/usb_descriptor b/tools/usb_descriptor index 2507847031..57bf602dac 160000 --- a/tools/usb_descriptor +++ b/tools/usb_descriptor @@ -1 +1 @@ -Subproject commit 2507847031a0395465956539253cbfa27f87511e +Subproject commit 57bf602dac9cba8c4226f764c286cbc60103d67d From 168e23e466737fd25d6c7a524231781e35d1d49a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 00:11:43 -0800 Subject: [PATCH 2/5] Build refinement to handle warnings and quiet output --- lib/tinyusb | 2 +- py/py.mk | 4 ++-- shared-module/usb_hid/__init__.c | 12 ++++++------ supervisor/shared/usb/tusb_config.h | 1 + supervisor/supervisor.mk | 8 ++++++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index 30e3c64134..537a29273c 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 30e3c64134789416e10ed867fa12c210b808e98f +Subproject commit 537a29273c08b1e047004e1bd71c37af82937dd4 diff --git a/py/py.mk b/py/py.mk index 9874dde4df..c640e6cff3 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-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index c0f9c897ca..f14fdd41e3 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -58,7 +58,7 @@ static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER]; #endif usb_hid_device_obj_t usb_hid_devices[] = { -#if USB_HID_REPORT_ID_KEYBOARD +#ifdef USB_HID_REPORT_ID_KEYBOARD { .base = { .type = &usb_hid_device_type } , .report_buffer = keyboard_report_buffer , @@ -69,7 +69,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_MOUSE +#ifdef USB_HID_REPORT_ID_MOUSE { .base = { .type = &usb_hid_device_type } , .report_buffer = mouse_report_buffer , @@ -80,7 +80,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_CONSUMER +#ifdef USB_HID_REPORT_ID_CONSUMER { .base = { .type = &usb_hid_device_type } , .report_buffer = consumer_report_buffer , @@ -91,7 +91,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_SYS_CONTROL +#ifdef USB_HID_REPORT_ID_SYS_CONTROL { .base = { .type = &usb_hid_device_type } , .report_buffer = sys_control_report_buffer , @@ -102,7 +102,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_GAMEPAD +#ifdef USB_HID_REPORT_ID_GAMEPAD { .base = { .type = &usb_hid_device_type } , .report_buffer = gamepad_report_buffer , @@ -113,7 +113,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_DIGITIZER +#ifdef USB_HID_REPORT_ID_DIGITIZER { .base = { .type = &usb_hid_device_type } , .report_buffer = digitizer_report_buffer , diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 4693bfcedb..649c390ac7 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -75,6 +75,7 @@ #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 1 +#define CFG_TUD_CUSTOM_CLASS 0 /*------------------------------------------------------------------*/ /* CLASS DRIVER diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index d870f799fa..ac982d2773 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -66,10 +66,14 @@ 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: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) +$(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 - $(PYTHON3) ../../tools/gen_usb_descriptor.py \ + $(Q)$(PYTHON3) ../../tools/gen_usb_descriptor.py \ --manufacturer $(USB_MANUFACTURER)\ --product $(USB_PRODUCT)\ --vid $(USB_VID)\ From be6b49c7128c9a09117aaa417b895767ebea924a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 00:27:18 -0800 Subject: [PATCH 3/5] Add back internal flash header and slim it down. --- ports/atmel-samd/supervisor/internal_flash.c | 2 ++ ports/atmel-samd/supervisor/internal_flash.h | 19 ------------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/ports/atmel-samd/supervisor/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c index bf12ad0cd4..6e097b214b 100644 --- a/ports/atmel-samd/supervisor/internal_flash.c +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include "supervisor/internal_flash.h" + #include #include diff --git a/ports/atmel-samd/supervisor/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h index 88c105386f..b1074d93f5 100644 --- a/ports/atmel-samd/supervisor/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 From 688f0e388bbb0ae4420c8e3145e83cb15d9b3829 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 00:49:02 -0800 Subject: [PATCH 4/5] Update MKR1300 board definition too --- ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h index ad9dc43b40..1e8d926fd4 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) From 43f7ca7985768c974b6881957b21d687c34413ba Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 11:33:56 -0800 Subject: [PATCH 5/5] Incorporate feedback: * Clean up board defines. * Add flush on eject and stay ejected. * Swith back to NONE protocol for CDC. --- lib/tinyusb | 2 +- ports/atmel-samd/boards/arduino_zero/mpconfigboard.h | 2 +- .../boards/circuitplayground_express/mpconfigboard.h | 1 - .../boards/hallowing_m0_express/mpconfigboard.h | 2 ++ .../boards/metro_m0_express/mpconfigboard.h | 7 ++++--- ports/atmel-samd/boards/trinket_m0/mpconfigboard.h | 2 +- ports/atmel-samd/common-hal/microcontroller/Pin.c | 5 ----- supervisor/shared/external_flash/external_flash.h | 2 +- supervisor/shared/usb/usb_msc_flash.c | 12 +++++++++++- tools/gen_usb_descriptor.py | 4 ++-- 10 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index 537a29273c..299a2f12de 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 537a29273c08b1e047004e1bd71c37af82937dd4 +Subproject commit 299a2f12de2ddb76b9a488b23e7e562058faee90 diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h index 56e4dbcec7..9a6256c68f 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -5,7 +5,7 @@ #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) diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 6dfaf87e91..2ad13e81c0 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -14,7 +14,6 @@ #define SPI_FLASH_CS_PIN &pin_PB22 // These are pins not to reset. -// PA24 and PA25 are USB. #define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h index 7dd4bf7c43..5869c01ffe 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h @@ -9,7 +9,9 @@ #define SPI_FLASH_CS_PIN &pin_PA07 // These are pins not to reset. +// 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 ) diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h index 28bb1f2931..f08d129dc8 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h @@ -1,8 +1,9 @@ #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) @@ -15,7 +16,7 @@ #define SPI_FLASH_CS_PIN &pin_PA13 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h index 24f3004e90..c311f540c3 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -5,7 +5,7 @@ #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) diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 9af5aeaf7b..7dd9c6b09a 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -53,12 +53,7 @@ void reset_all_pins(void) { // 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] &= ~(PORT_PA31); pin_mask[i] &= ~never_reset_pins[i]; } diff --git a/supervisor/shared/external_flash/external_flash.h b/supervisor/shared/external_flash/external_flash.h index 852d183a7f..72b619a2a8 100644 --- a/supervisor/shared/external_flash/external_flash.h +++ b/supervisor/shared/external_flash/external_flash.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 diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 72dc40204c..13b5c3966e 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -38,6 +38,8 @@ #define MSC_FLASH_BLOCK_SIZE 512 +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 @@ -60,7 +62,7 @@ static fs_user_mount_t* get_vfs(int lun) { // - 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: @@ -73,6 +75,9 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, if (current_mount == NULL) { resplen = -1; } + if (ejected[lun]) { + resplen = -1; + } } break; @@ -96,6 +101,11 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, if (current_mount == NULL) { resplen = -1; } + if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) { + resplen = -1; + } else { + ejected[lun] = true; + } } } } diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index b50c0798ff..2cb06ec2f2 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -80,7 +80,7 @@ cdc_comm_interface = standard.InterfaceDescriptor( description="CDC comm", bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bInterfaceProtocol=cdc.CDC_PROTOCOL_V25TER, + bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, iInterface=StringIndex.index("CircuitPython CDC control"), subdescriptors=[ cdc.Header( @@ -254,7 +254,7 @@ cdc_iad = standard.InterfaceAssociationDescriptor( bInterfaceCount=len(cdc_interfaces), bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bFunctionProtocol=cdc.CDC_PROTOCOL_V25TER) # TODO(tannewt): can this be NONE (aka 0)? + bFunctionProtocol=cdc.CDC_PROTOCOL_NONE) # audio_iad = standard.InterfaceAssociationDescriptor( # description="Audio IAD",