From dfd4324eb1b758e37cfc77da8467e7f5d72f519c Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 7 May 2021 15:21:09 +0200 Subject: [PATCH] mimxrt: Add flash storage support with VFS and littlefs filesystem. This commit adds full support for a filesystem on all boards, with a block device object mimxrt.Flash() and uos.VfsLfs2 enabled. Main changes are: - Refactoring of linker scripts to accomodate reserved area for VFS. VFS will take up most of the available flash. 1M is reserved for code. 9K is reserved for flash configuration, interrupts, etc. - Addition of _boot.py with filesystem init code, called from main.c. - Definition of the mimxrt module with a Flash class in modmimxrt.[ch]. - Implementation of a flash driver class in mimxrt_flash.c. All flashing related functions are stored in ITCM RAM. - Addition of the uos module with filesystem functions. - Implementation of uos.urandom() for the sake of completeness of the uos module. It uses sample code from CircuitPython supplied under MIT license, which uses the NXP SDK example code. Done in collaboration with Philipp Ebensberger aka @alphaFred who contributed the essential part to enable writing to flash while code is executing, among other things. --- ports/mimxrt/Makefile | 17 +- .../boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld | 1 + .../evkmimxrt1010_flexspi_nor_config.h | 44 ++- .../boards/MIMXRT1010_EVK/flash_config.c | 76 ++++- .../boards/MIMXRT1010_EVK/mpconfigboard.h | 1 + ports/mimxrt/boards/MIMXRT1011.ld | 28 +- .../boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld | 1 + .../evkmimxrt1020_flexspi_nor_config.h | 44 ++- .../boards/MIMXRT1020_EVK/flash_config.c | 89 +++++- .../boards/MIMXRT1020_EVK/mpconfigboard.h | 1 + ports/mimxrt/boards/MIMXRT1021.ld | 24 +- .../boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld | 1 + .../evkmimxrt1050_flexspi_nor_config.h | 44 ++- .../boards/MIMXRT1050_EVK/flash_config.c | 81 +++++- .../boards/MIMXRT1050_EVK/mpconfigboard.h | 1 + ports/mimxrt/boards/MIMXRT1052.ld | 25 +- .../boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld | 1 + .../evkmimxrt1060_flexspi_nor_config.h | 44 ++- .../boards/MIMXRT1060_EVK/flash_config.c | 76 ++++- .../boards/MIMXRT1060_EVK/mpconfigboard.h | 1 + ports/mimxrt/boards/MIMXRT1062.ld | 24 +- ports/mimxrt/boards/MIMXRT1064.ld | 24 +- .../boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld | 1 + .../evkmimxrt1064_flexspi_nor_config.h | 45 ++- .../boards/MIMXRT1064_EVK/flash_config.c | 76 ++++- .../boards/MIMXRT1064_EVK/mpconfigboard.h | 1 + ports/mimxrt/boards/TEENSY40/TEENSY40.ld | 2 + ports/mimxrt/boards/TEENSY40/flash_config.c | 99 ++++++- ports/mimxrt/boards/TEENSY40/mpconfigboard.h | 1 + .../TEENSY40/teensy40_flexspi_nor_config.h | 47 ++-- ports/mimxrt/boards/common.ld | 262 ++++++++++++++++++ ports/mimxrt/hal/flexspi_nor_flash.c | 219 +++++++++++++++ ports/mimxrt/hal/flexspi_nor_flash.h | 42 +++ ports/mimxrt/main.c | 33 ++- ports/mimxrt/mimxrt_flash.c | 221 +++++++++++++++ ports/mimxrt/modmimxrt.c | 39 +++ ports/mimxrt/modmimxrt.h | 34 +++ ports/mimxrt/modules/_boot.py | 15 + ports/mimxrt/moduos.c | 129 +++++++++ ports/mimxrt/mpconfigport.h | 27 +- ports/mimxrt/mphalport.c | 9 + ports/mimxrt/mphalport.h | 5 + 42 files changed, 1745 insertions(+), 210 deletions(-) create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld create mode 100644 ports/mimxrt/boards/TEENSY40/TEENSY40.ld create mode 100644 ports/mimxrt/boards/common.ld create mode 100644 ports/mimxrt/hal/flexspi_nor_flash.c create mode 100644 ports/mimxrt/hal/flexspi_nor_flash.h create mode 100644 ports/mimxrt/mimxrt_flash.c create mode 100644 ports/mimxrt/modmimxrt.c create mode 100644 ports/mimxrt/modmimxrt.h create mode 100644 ports/mimxrt/modules/_boot.py create mode 100644 ports/mimxrt/moduos.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index b4f581ccdc..7feab6cd75 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -17,6 +17,7 @@ QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h # MicroPython feature configurations FROZEN_MANIFEST ?= boards/manifest.py +MICROPY_VFS_LFS2 ?= 1 # Include py core make definitions include $(TOP)/py/py.mk @@ -24,7 +25,7 @@ include $(TOP)/py/py.mk GIT_SUBMODULES = lib/tinyusb lib/nxp_driver MCU_DIR = lib/nxp_driver/sdk/devices/$(MCU_SERIES) -LD_FILES = boards/$(MCU_SERIES).ld $(TOP)/$(MCU_DIR)/gcc/$(MCU_SERIES)xxxxx_flexspi_nor.ld +LD_FILES = boards/$(BOARD)/$(BOARD).ld boards/$(MCU_SERIES).ld boards/common.ld MAKE_PINS = boards/make-pins.py BOARD_PINS = $(BOARD_DIR)/pins.csv @@ -59,8 +60,10 @@ CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX \ -D__STARTUP_CLEAR_BSS \ + -D__STARTUP_INITIALIZE_RAMFUNCTION \ -D__START=main \ -DCPU_HEADER_H='<$(MCU_SERIES).h>' +CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref --print-memory-usage LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) @@ -101,6 +104,8 @@ SRC_TINYUSB_IMX_C += \ $(MCU_DIR)/drivers/fsl_common.c \ $(MCU_DIR)/drivers/fsl_lpuart.c \ $(MCU_DIR)/drivers/fsl_flexram.c \ + $(MCU_DIR)/drivers/fsl_flexspi.c \ + $(MCU_DIR)/drivers/fsl_trng.c \ SRC_C = \ main.c \ @@ -112,15 +117,20 @@ SRC_C = \ $(BOARD_DIR)/flash_config.c \ machine_led.c \ machine_pin.c \ + mimxrt_flash.c \ modutime.c \ modmachine.c \ + modmimxrt.c \ + moduos.c \ mphalport.c \ + hal/flexspi_nor_flash.c \ lib/mp-readline/readline.c \ lib/libc/string0.c \ lib/utils/gchelper_native.c \ lib/utils/printf.c \ lib/utils/pyexec.c \ lib/utils/stdout_helpers.c \ + lib/utils/sys_stdio_mphal.c \ $(SRC_TINYUSB_C) \ $(SRC_TINYUSB_IMX_C) \ @@ -132,15 +142,20 @@ SRC_S = lib/utils/gchelper_m3.s \ SRC_QSTR += \ machine_led.c \ machine_pin.c \ + mimxrt_flash.c \ modutime.c \ modmachine.c \ + modmimxrt.c \ + moduos.c \ pin.c \ + lib/utils/sys_stdio_mphal.c \ $(GEN_PINS_SRC) \ OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) OBJ += $(BUILD)/pins_gen.o # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld b/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld new file mode 100644 index 0000000000..83da7ec73c --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/MIMXRT1010_EVK.ld @@ -0,0 +1 @@ +flash_size = 16M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h index 8fa31c8320..2cb4535edc 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/evkmimxrt1010_flexspi_nor_config.h @@ -211,34 +211,19 @@ typedef struct _FlexSPIConfig } flexspi_mem_config_t; /* */ -#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 -#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 -#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 -#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 -#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 -#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 -#define NOR_CMD_INDEX_DUMMY 6 //!< 6 -#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 - -#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ - CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ - 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ - CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ - 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ - CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ - 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ - 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 /* * Serial NOR configuration block @@ -259,6 +244,9 @@ typedef struct _flexspi_nor_config uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c index a03ee07865..5e7e5dcf15 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/flash_config.c @@ -37,9 +37,83 @@ const flexspi_nor_config_t qspiflash_config = { .sflashA1Size = 16u * 1024u * 1024u, .lookupTable = { - // Read LUTs + // 0 Read LUTs 0 -> 0 FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }, }, .pageSize = 256u, diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index 5a89423b50..3eb3268125 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -7,3 +7,4 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_11) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) +#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1010_flexspi_nor_config.h" diff --git a/ports/mimxrt/boards/MIMXRT1011.ld b/ports/mimxrt/boards/MIMXRT1011.ld index 9db30adee8..d9a4956856 100644 --- a/ports/mimxrt/boards/MIMXRT1011.ld +++ b/ports/mimxrt/boards/MIMXRT1011.ld @@ -1,5 +1,25 @@ -/* 24kiB stack. */ -__stack_size__ = 0x4000; +/* Memory configuration */ +flash_start = 0x60000000; +flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); +flash_config_start = 0x60000400; +flash_config_size = 0x00000C00; +ivt_start = 0x60001000; +ivt_size = 0x00001000; +interrupts_start = 0x60002000; +interrupts_size = 0x00000400; +text_start = 0x60002400; +text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ +vfs_start = (text_start) + (text_size); +vfs_size = ((flash_end) - (vfs_start)); +itcm_start = 0x00000000; +itcm_size = 0x00008000; +dtcm_start = 0x20000000; +dtcm_size = 0x00008000; +ocrm_start = 0x20200000; +ocrm_size = 0x00010000; + +/* 20kiB stack. */ +__stack_size__ = 0x5000; _estack = __StackTop; _sstack = __StackLimit; @@ -7,5 +27,5 @@ _sstack = __StackLimit; __heap_size__ = 0; /* Use second OCRAM bank for GC heap. */ -_gc_heap_start = ORIGIN(m_data2); -_gc_heap_end = ORIGIN(m_data2) + LENGTH(m_data2); +_gc_heap_start = ORIGIN(m_ocrm); +_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld b/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld new file mode 100644 index 0000000000..fd1bf32ede --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/MIMXRT1020_EVK.ld @@ -0,0 +1 @@ +flash_size = 8M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h index c0c6ea2436..195c0c225e 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/evkmimxrt1020_flexspi_nor_config.h @@ -212,34 +212,19 @@ typedef struct _FlexSPIConfig } flexspi_mem_config_t; /* */ -#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 -#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 -#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 -#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 -#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 -#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 -#define NOR_CMD_INDEX_DUMMY 6 //!< 6 -#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 - -#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ - CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ - 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ - CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ - 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ - CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ - 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ - 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 /* * Serial NOR configuration block @@ -260,6 +245,9 @@ typedef struct _flexspi_nor_config uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c index 56007931a9..5377cc1b25 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/flash_config.c @@ -32,20 +32,105 @@ const flexspi_nor_config_t qspiflash_config = { .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, + .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. + .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. + .deviceModeCfgEnable = 1u, + .deviceModeType = kDeviceConfigCmdType_QuadEnable, + .deviceModeSeq = { + .seqId = 4u, + .seqNum = 1u, + }, + .deviceModeArg = 0x40, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_100MHz, + .serialClkFreq = kFlexSpiSerialClk_30MHz, .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { - // Read LUTs + // 0 Read LUTs 0 -> 0 FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, + .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, }; #endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index d8c0f00e27..a025c85bf3 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -8,3 +8,4 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_05) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) +#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1020_flexspi_nor_config.h" diff --git a/ports/mimxrt/boards/MIMXRT1021.ld b/ports/mimxrt/boards/MIMXRT1021.ld index 6b59649fca..de0f259dcc 100644 --- a/ports/mimxrt/boards/MIMXRT1021.ld +++ b/ports/mimxrt/boards/MIMXRT1021.ld @@ -1,8 +1,28 @@ +/* Memory configuration */ +flash_start = 0x60000000; +flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); +flash_config_start = flash_start; +flash_config_size = 0x00001000; +ivt_start = 0x60001000; +ivt_size = 0x00001000; +interrupts_start = 0x60002000; +interrupts_size = 0x00000400; +text_start = 0x60002400; +text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ +vfs_start = (text_start) + (text_size); +vfs_size = ((flash_end) - (vfs_start)); +itcm_start = 0x00000000; +itcm_size = 0x00010000; +dtcm_start = 0x20000000; +dtcm_size = 0x00010000; +ocrm_start = 0x20200000; +ocrm_size = 0x00020000; + /* 24kiB stack. */ __stack_size__ = 0x6000; _estack = __StackTop; _sstack = __StackLimit; /* Use second OCRAM bank for GC heap. */ -_gc_heap_start = ORIGIN(m_data2); -_gc_heap_end = ORIGIN(m_data2) + LENGTH(m_data2); +_gc_heap_start = ORIGIN(m_ocrm); +_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld b/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld new file mode 100644 index 0000000000..fd1bf32ede --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/MIMXRT1050_EVK.ld @@ -0,0 +1 @@ +flash_size = 8M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h index d8e842452e..e038967e17 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/evkmimxrt1050_flexspi_nor_config.h @@ -209,34 +209,19 @@ typedef struct _FlexSPIConfig } flexspi_mem_config_t; /* */ -#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 -#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 -#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 -#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 -#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 -#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 -#define NOR_CMD_INDEX_DUMMY 6 //!< 6 -#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 - -#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ - CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ - 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ - CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ - 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ - CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ - 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ - 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 /* * Serial NOR configuration block @@ -257,6 +242,9 @@ typedef struct _flexspi_nor_config uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c index 8203f4811a..2a9303fc98 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/flash_config.c @@ -41,10 +41,83 @@ const flexspi_nor_config_t qspiflash_config = { .dataValidTime = {16u, 16u}, .lookupTable = { - // Read LUTs - FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18), - FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x06), - FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), + // 0 Read LUTs 0 -> 0 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }, }, .pageSize = 512u, diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index 2337496d2a..9b7664841e 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -7,3 +7,4 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) +#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1050_flexspi_nor_config.h" diff --git a/ports/mimxrt/boards/MIMXRT1052.ld b/ports/mimxrt/boards/MIMXRT1052.ld index 836a119e5e..f78773531a 100644 --- a/ports/mimxrt/boards/MIMXRT1052.ld +++ b/ports/mimxrt/boards/MIMXRT1052.ld @@ -1,7 +1,28 @@ +/* Memory configuration */ +flash_start = 0x60000000; +flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); +flash_config_start = flash_start; +flash_config_size = 0x00001000; +ivt_start = 0x60001000; +ivt_size = 0x00001000; +interrupts_start = 0x60002000; +interrupts_size = 0x00000400; +text_start = 0x60002400; +text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ +vfs_start = (text_start) + (text_size); +vfs_size = ((flash_end) - (vfs_start)); +itcm_start = 0x00000000; +itcm_size = 0x00020000; +dtcm_start = 0x20000000; +dtcm_size = 0x00020000; +ocrm_start = 0x20200000; +ocrm_size = 0x00040000; + +/* 24kiB stack. */ __stack_size__ = 0x6000; _estack = __StackTop; _sstack = __StackLimit; /* Use second OCRAM bank for GC heap. */ -_gc_heap_start = ORIGIN(m_data2); -_gc_heap_end = ORIGIN(m_data2) + LENGTH(m_data2); +_gc_heap_start = ORIGIN(m_ocrm); +_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld new file mode 100644 index 0000000000..fd1bf32ede --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld @@ -0,0 +1 @@ +flash_size = 8M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h index 8bb771fd8a..03bdac1f1c 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h @@ -210,34 +210,19 @@ typedef struct _FlexSPIConfig } flexspi_mem_config_t; /* */ -#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 -#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 -#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 -#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 -#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 -#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 -#define NOR_CMD_INDEX_DUMMY 6 //!< 6 -#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 - -#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ - CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ - 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ - CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ - 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ - CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ - 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ - 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 /* * Serial NOR configuration block @@ -258,6 +243,9 @@ typedef struct _flexspi_nor_config uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c index 095a922e9e..3fa584b73a 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c @@ -35,9 +35,83 @@ const flexspi_nor_config_t qspiflash_config = { .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { - // Read LUTs + // 0 Read LUTs 0 -> 0 FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }, }, .pageSize = 256u, diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index c9e6d8bf2c..3974f93257 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -7,3 +7,4 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) +#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1060_flexspi_nor_config.h" diff --git a/ports/mimxrt/boards/MIMXRT1062.ld b/ports/mimxrt/boards/MIMXRT1062.ld index 23520b5624..5ab7e15332 100644 --- a/ports/mimxrt/boards/MIMXRT1062.ld +++ b/ports/mimxrt/boards/MIMXRT1062.ld @@ -1,8 +1,28 @@ +/* Memory configuration */ +flash_start = 0x60000000; +flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); +flash_config_start = flash_start; +flash_config_size = 0x00001000; +ivt_start = 0x60001000; +ivt_size = 0x00001000; +interrupts_start = 0x60002000; +interrupts_size = 0x00000400; +text_start = 0x60002400; +text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ +vfs_start = (text_start) + (text_size); +vfs_size = ((flash_end) - (vfs_start)); +itcm_start = 0x00000000; +itcm_size = 0x00020000; +dtcm_start = 0x20000000; +dtcm_size = 0x00020000; +ocrm_start = 0x20200000; +ocrm_size = 0x000C0000; + /* 32kiB stack. */ __stack_size__ = 0x8000; _estack = __StackTop; _sstack = __StackLimit; /* Use second OCRAM bank for GC heap. */ -_gc_heap_start = ORIGIN(m_data2); -_gc_heap_end = ORIGIN(m_data2) + LENGTH(m_data2); +_gc_heap_start = ORIGIN(m_ocrm); +_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); diff --git a/ports/mimxrt/boards/MIMXRT1064.ld b/ports/mimxrt/boards/MIMXRT1064.ld index bf37c21802..236d984293 100644 --- a/ports/mimxrt/boards/MIMXRT1064.ld +++ b/ports/mimxrt/boards/MIMXRT1064.ld @@ -1,8 +1,28 @@ +/* Memory configuration */ +flash_start = 0x60000000; +flash_end = DEFINED(reserved_size) ? ((flash_start) + (flash_size - reserved_size)) : ((flash_start) + (flash_size)); +flash_config_start = flash_start; +flash_config_size = 0x00001000; +ivt_start = 0x60001000; +ivt_size = 0x00001000; +interrupts_start = 0x60002000; +interrupts_size = 0x00000400; +text_start = 0x60002400; +text_size = ((((text_start) + 1M) + (4k - 1)) & ~(4k - 1)) - (text_start); /* reserve 1M for code but align on 4k boundary */ +vfs_start = (text_start) + (text_size); +vfs_size = ((flash_end) - (vfs_start)); +itcm_start = 0x00000000; +itcm_size = 0x00020000; +dtcm_start = 0x20000000; +dtcm_size = 0x00020000; +ocrm_start = 0x20200000; +ocrm_size = 0x000C0000; + /* 24kiB stack. */ __stack_size__ = 0x6000; _estack = __StackTop; _sstack = __StackLimit; /* Use second OCRAM bank for GC heap. */ -_gc_heap_start = ORIGIN(m_data2); -_gc_heap_end = ORIGIN(m_data2) + LENGTH(m_data2); \ No newline at end of file +_gc_heap_start = ORIGIN(m_ocrm); +_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld new file mode 100644 index 0000000000..fd1bf32ede --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld @@ -0,0 +1 @@ +flash_size = 8M; \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h b/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h index efdfe583fb..3c433f3be9 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h @@ -210,35 +210,19 @@ typedef struct _FlexSPIConfig } flexspi_mem_config_t; /* */ -#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 -#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 -#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 -#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 -#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 -#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 -#define NOR_CMD_INDEX_DUMMY 6 //!< 6 -#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 - -#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ - CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ - 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ - CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ - 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ - CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ - 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ - 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk - +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 /* * Serial NOR configuration block */ @@ -258,6 +242,9 @@ typedef struct _flexspi_nor_config uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c index bfb1c2d59a..9338c6948a 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c @@ -36,9 +36,83 @@ const flexspi_nor_config_t qspiflash_config = { .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { - // Read LUTs + // 0 Read LUTs 0 -> 0 FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }, }, .pageSize = 256u, diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index 3eddb41021..01e2e10bb5 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -6,3 +6,4 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) +#define BOARD_FLASH_CONFIG_HEADER_H "evkmimxrt1064_flexspi_nor_config.h" diff --git a/ports/mimxrt/boards/TEENSY40/TEENSY40.ld b/ports/mimxrt/boards/TEENSY40/TEENSY40.ld new file mode 100644 index 0000000000..a3b696db66 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/TEENSY40.ld @@ -0,0 +1,2 @@ +flash_size = 2M; +reserved_size = 4K; \ No newline at end of file diff --git a/ports/mimxrt/boards/TEENSY40/flash_config.c b/ports/mimxrt/boards/TEENSY40/flash_config.c index 39a6b91088..7a63cf825d 100644 --- a/ports/mimxrt/boards/TEENSY40/flash_config.c +++ b/ports/mimxrt/boards/TEENSY40/flash_config.c @@ -32,20 +32,113 @@ const flexspi_nor_config_t qspiflash_config = { .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, + + .busyOffset = FLASH_BUSY_STATUS_OFFSET, // Status bit 0 indicates busy. + .busyBitPolarity = FLASH_BUSY_STATUS_POL, // Busy when the bit is 1. + + .deviceModeCfgEnable = 1u, + .deviceModeType = kDeviceConfigCmdType_QuadEnable, + .deviceModeSeq = { + .seqId = 4u, + .seqNum = 1u, + }, + .deviceModeArg = 0x0200, + .configCmdEnable = 1u, + .configModeType[0] = kDeviceConfigCmdType_Generic, + .configCmdSeqs[0] = { + .seqId = 2u, + .seqNum = 1u, + }, + .deviceType = kFlexSpiDeviceType_SerialNOR, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_100MHz, + .serialClkFreq = kFlexSpiSerialClk_60MHz, .sflashA1Size = 2u * 1024u * 1024u, .lookupTable = { - // Read LUTs + // 0 Read LUTs 0 -> 0 FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 1 Read status register -> 1 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 2 Fast read quad mode - SDR + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 3 Write Enable -> 3 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 4 Read extend parameters + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 5 Erase Sector -> 5 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 6 Write Status Reg + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 7 Page Program - quad mode (-> 9) + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 8 Read ID + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 9 Page Program - single mode -> 9 + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 10 Enter QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 11 Erase Chip + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + + // 12 Exit QPI mode + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_4PAD, 0xF5, STOP, FLEXSPI_1PAD, 0), + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler + FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, - .blockSize = 256u * 1024u, + .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .blockSize = 0x00010000, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h index e3d7c6a129..c6f11b51d1 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -7,3 +7,4 @@ #define MICROPY_HW_LED1_PIN (pin_GPIO_B0_03) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) +#define BOARD_FLASH_CONFIG_HEADER_H "teensy40_flexspi_nor_config.h" diff --git a/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h index 2c7bf48b62..445a0baccc 100644 --- a/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h +++ b/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h @@ -28,7 +28,7 @@ /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 -/* Lookup table related defintions */ +/* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 @@ -37,6 +37,7 @@ #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_ERASE 5 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 @@ -212,34 +213,19 @@ typedef struct _FlexSPIConfig } flexspi_mem_config_t; /* */ -#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 -#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 -#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 -#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 -#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 -#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 -#define NOR_CMD_INDEX_DUMMY 6 //!< 6 -#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 - -#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ - CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ - 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ - CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ - 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ - CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block -#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ - 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block -#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ - 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk +#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 0 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 1 +#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 2 +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 4 +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 6 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 7 +#define NOR_CMD_LUT_SEQ_IDX_READID 8 +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 +#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 /* * Serial NOR configuration block @@ -260,6 +246,9 @@ typedef struct _flexspi_nor_config uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; +#define FLASH_BUSY_STATUS_POL 0 +#define FLASH_BUSY_STATUS_OFFSET 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/ports/mimxrt/boards/common.ld b/ports/mimxrt/boards/common.ld new file mode 100644 index 0000000000..e5d91f1191 --- /dev/null +++ b/ports/mimxrt/boards/common.ld @@ -0,0 +1,262 @@ +/* +** ################################################################### +** Linker script inspired by NXP linker script for MIMXRT10xx +** +** Copyright for original linker script: +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Integrated ideas from CircuitPython: +** SPDX-License-Identifier: The MIT License (MIT) +** SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft (tannewt) +** +** Copyright (c) 2021 Philipp Ebensberger +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; + +/* Reserved Area + * Users can create a reserved area at the end of the flash memory via + * 'reserved_size' variable. The size of the reserved area should be a multiple + * of the sector size of the flash memory! + */ +reserved_size = DEFINED(reserved_size) ? reserved_size : 0k; + +/* Specify the memory areas */ +MEMORY +{ + m_flash_config (RX) : ORIGIN = flash_config_start, LENGTH = flash_config_size + m_ivt (RX) : ORIGIN = ivt_start, LENGTH = ivt_size + m_interrupts (RX) : ORIGIN = interrupts_start, LENGTH = interrupts_size + m_text (RX) : ORIGIN = text_start, LENGTH = text_size + m_vfs (RX) : ORIGIN = vfs_start, LENGTH = vfs_size + /* Teensy uses the last bit of flash for recovery. */ + m_reserved (RX) : ORIGIN = (vfs_start + vfs_size), LENGTH = reserved_size + m_itcm (RX) : ORIGIN = itcm_start, LENGTH = itcm_size + m_dtcm (RW) : ORIGIN = dtcm_start, LENGTH = dtcm_size + m_ocrm (RW) : ORIGIN = ocrm_start, LENGTH = ocrm_size +} + +/* Define output sections */ +SECTIONS +{ + __flash_start = flash_start; + __vfs_start = ORIGIN(m_vfs); + __vfs_end = __vfs_start + LENGTH(m_vfs); + + .flash_config : + { + . = ALIGN(4); + __FLASH_BASE = .; + KEEP(* (.boot_hdr.conf)) /* flash config section */ + . = ALIGN(4); + } > m_flash_config + + ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config); + + .ivt : AT(ivt_begin) + { + . = ALIGN(4); + KEEP(* (.boot_hdr.ivt)) /* ivt section */ + KEEP(* (.boot_hdr.boot_data)) /* boot section */ + KEEP(* (.boot_hdr.dcd_data)) /* dcd section */ + . = ALIGN(4); + } > m_ivt + + /* The startup code goes first into internal RAM */ + .interrupts : + { + __VECTOR_TABLE = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + __VECTOR_RAM = __VECTOR_TABLE; + __RAM_VECTOR_TABLE_SIZE_BYTES = 0x0; + + /* The program code and other data goes into internal RAM */ + .text : + { + . = ALIGN(4); + *(EXCLUDE_FILE(*fsl_flexspi.o) .text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(m_usb_dma_init_data) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_dtcm + + __RAM_FUNCTIONS_ROM = __DATA_ROM + (__data_end__ - __data_start__); + .ram_functions : AT(__RAM_FUNCTIONS_ROM) + { + . = ALIGN(4); + __ram_function_start__ = .; + *fsl_flexspi.o(.text*) + *(.ram_functions*) + . = ALIGN(4); + __ram_function_end__ = .; + } > m_itcm + + __NDATA_ROM = __DATA_ROM + (__ram_function_end__ - __data_start__); + .ncache.init : AT(__NDATA_ROM) + { + __noncachedata_start__ = .; /* create a global symbol at ncache data start */ + *(NonCacheable.init) + . = ALIGN(4); + __noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */ + } > m_dtcm + . = __noncachedata_init_end__; + .ncache : + { + *(NonCacheable) + . = ALIGN(4); + __noncachedata_end__ = .; /* define a global symbol at ncache data end */ + } > m_dtcm + + __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(m_usb_dma_noninit_data) + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_dtcm + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_dtcm + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_dtcm + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_dtcm) + LENGTH(m_dtcm); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_dtcm overflowed with stack and heap") +} + diff --git a/ports/mimxrt/hal/flexspi_nor_flash.c b/ports/mimxrt/hal/flexspi_nor_flash.c new file mode 100644 index 0000000000..a70d234d6e --- /dev/null +++ b/ports/mimxrt/hal/flexspi_nor_flash.c @@ -0,0 +1,219 @@ +/* + * Based largely on examples provided by NXP: + * + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Port-specific extensions and adaptions: + * + * The MIT License (MIT) + * This file is part of the MicroPython project, http://micropython.org/ + * + * Copyright (c) 2021 Damien P. George + * Copyright (c) 2021 Philipp Ebensberger + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include "fsl_common.h" +#include "flexspi_nor_flash.h" + +void flexspi_nor_reset(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))); +void flexspi_nor_reset(FLEXSPI_Type *base) { + // Using content of FLEXSPI_SoftwareReset directly to prevent issues when compiler does not inline function + base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; + while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) + { + } +} + +status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr) __attribute__((section(".ram_functions"))); +status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr) { + flexspi_transfer_t flashXfer; + status_t status; + + /* Write neable */ + flashXfer.deviceAddress = baseAddr; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Command; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE; + + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + return status; +} + +status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) { + /* Wait status ready. */ + bool isBusy; + uint32_t readValue; + status_t status; + flexspi_transfer_t flashXfer; + + flashXfer.deviceAddress = 0; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Read; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG; + flashXfer.data = &readValue; + flashXfer.dataSize = 1; + + do { + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + if (status != kStatus_Success) { + return status; + } + if (FLASH_BUSY_STATUS_POL) { + if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { + isBusy = false; + } else { + isBusy = true; + } + } else { + if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { + isBusy = true; + } else { + isBusy = false; + } + } + } while (isBusy); + + return status; +} + +status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) { + flexspi_transfer_t flashXfer; + status_t status; + uint32_t writeValue = 0x40; + + /* Write neable */ + status = flexspi_nor_write_enable(base, 0); + + if (status != kStatus_Success) { + return status; + } + + /* Enable quad mode. */ + flashXfer.deviceAddress = 0; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Write; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG; + flashXfer.data = &writeValue; + flashXfer.dataSize = 1; + + status = FLEXSPI_TransferBlocking(base, &flashXfer); + if (status != kStatus_Success) { + return status; + } + + status = flexspi_nor_wait_bus_busy(base); + + return status; +} + +status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { + status_t status; + flexspi_transfer_t flashXfer; + + /* Write enable */ + status = flexspi_nor_write_enable(base, address); + + if (status != kStatus_Success) { + return status; + } + + /* Erase sector */ + flashXfer.deviceAddress = address; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Command; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR; + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + if (status != kStatus_Success) { + return status; + } + + status = flexspi_nor_wait_bus_busy(base); + + flexspi_nor_reset(base); + + return status; +} + +status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t size) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t size) { + status_t status; + flexspi_transfer_t flashXfer; + + /* Write enable */ + status = flexspi_nor_write_enable(base, dstAddr); + + if (status != kStatus_Success) { + return status; + } + + /* Prepare page program command */ + flashXfer.deviceAddress = dstAddr; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Write; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD; + flashXfer.data = (uint32_t *) src; + flashXfer.dataSize = size; + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + if (status != kStatus_Success) { + return status; + } + + status = flexspi_nor_wait_bus_busy(base); + + flexspi_nor_reset(FLEXSPI); + + return status; +} + +status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId) __attribute__((section(".ram_functions"))) ; +status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId) { + uint32_t temp; + flexspi_transfer_t flashXfer; + flashXfer.deviceAddress = 0; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Read; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READID; + flashXfer.data = &temp; + flashXfer.dataSize = 2; + + status_t status = FLEXSPI_TransferBlocking(base, &flashXfer); + + *vendorId = temp; + + return status; +} diff --git a/ports/mimxrt/hal/flexspi_nor_flash.h b/ports/mimxrt/hal/flexspi_nor_flash.h new file mode 100644 index 0000000000..43cd7efdc7 --- /dev/null +++ b/ports/mimxrt/hal/flexspi_nor_flash.h @@ -0,0 +1,42 @@ +/* + * 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_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H +#define MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H + +#include "fsl_flexspi.h" +#include "mpconfigport.h" +#include BOARD_FLASH_CONFIG_HEADER_H + +// Defined in boards flash_config.c +extern flexspi_nor_config_t qspiflash_config; + +status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId); +status_t flexspi_nor_init(void); +void flexspi_nor_update_lut(void); +status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); +status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size); + +#endif // MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index 387c96ef33..76fd7ef76c 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -30,6 +30,7 @@ #include "py/gc.h" #include "py/mperrno.h" #include "py/stackctrl.h" +#include "lib/mp-readline/readline.h" #include "lib/utils/gchelper.h" #include "lib/utils/pyexec.h" #include "ticks.h" @@ -57,6 +58,24 @@ int main(void) { mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); + // Initialise sub-systems. + readline_init0(); + + // Execute _boot.py to set up the filesystem. + pyexec_frozen_module("_boot.py"); + + // Execute user scripts. + int ret = pyexec_file_if_exists("boot.py"); + if (ret & PYEXEC_FORCED_EXIT) { + goto soft_reset_exit; + } + if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { + ret = pyexec_file_if_exists("main.py"); + if (ret & PYEXEC_FORCED_EXIT) { + goto soft_reset_exit; + } + } + for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { @@ -69,6 +88,7 @@ int main(void) { } } + soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); gc_sweep_all(); mp_deinit(); @@ -83,19 +103,6 @@ void gc_collect(void) { gc_collect_end(); } -mp_lexer_t *mp_lexer_new_from_file(const char *filename) { - mp_raise_OSError(MP_ENOENT); -} - -mp_import_stat_t mp_import_stat(const char *path) { - return MP_IMPORT_STAT_NO_EXIST; -} - -mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); - void nlr_jump_fail(void *val) { for (;;) { } diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c new file mode 100644 index 0000000000..6b89bfa532 --- /dev/null +++ b/ports/mimxrt/mimxrt_flash.c @@ -0,0 +1,221 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * Copyright (c) 2021 Philipp Ebensberger + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "extmod/vfs.h" +#include "modmimxrt.h" +#include "hal/flexspi_nor_flash.h" + +// BOARD_FLASH_SIZE is defined in mpconfigport.h +#define SECTOR_SIZE_BYTES (qspiflash_config.sectorSize) +#define PAGE_SIZE_BYTES (qspiflash_config.pageSize) + +#ifndef MICROPY_HW_FLASH_STORAGE_BYTES +#define MICROPY_HW_FLASH_STORAGE_BYTES (((uint32_t)&__vfs_end) - ((uint32_t)&__vfs_start)) +#endif + +#ifndef MICROPY_HW_FLASH_STORAGE_BASE +#define MICROPY_HW_FLASH_STORAGE_BASE (((uint32_t)&__vfs_start) - ((uint32_t)&__flash_start)) +#endif + +// Linker symbols +extern uint8_t __vfs_start; +extern uint8_t __vfs_end; +extern uint8_t __flash_start; + +extern flexspi_nor_config_t qspiflash_config; + +typedef struct _mimxrt_flash_obj_t { + mp_obj_base_t base; + uint32_t flash_base; + uint32_t flash_size; +} mimxrt_flash_obj_t; + +STATIC mimxrt_flash_obj_t mimxrt_flash_obj = { + .base = { &mimxrt_flash_type } +}; + +// flash_erase_block(erase_addr_bytes) +// erases the 4k sector starting at adddr +status_t flash_erase_block(uint32_t erase_addr) __attribute__((section(".ram_functions"))); +status_t flash_erase_block(uint32_t erase_addr) { + status_t status; + SCB_CleanInvalidateDCache(); + SCB_DisableDCache(); + __disable_irq(); + status = flexspi_nor_flash_erase_sector(FLEXSPI, erase_addr); + __enable_irq(); + SCB_EnableDCache(); + return status; +} + +// flash_write_block(flash_dest_addr_bytes, data_source, length_bytes) +// writes length_byte data to the destination address +// length is a multiple of the page size = 256 +// the vfs driver takes care for erasing the sector if required +status_t flash_write_block(uint32_t dest_addr, const uint8_t *src, uint32_t length) __attribute__((section(".ram_functions"))); +status_t flash_write_block(uint32_t dest_addr, const uint8_t *src, uint32_t length) { + status_t status; + SCB_CleanInvalidateDCache(); + SCB_DisableDCache(); + // write sector in page size chunks + for (int i = 0; i < length; i += PAGE_SIZE_BYTES) { + __disable_irq(); + status = flexspi_nor_flash_page_program(FLEXSPI, dest_addr + i, (uint32_t *)(src + i), PAGE_SIZE_BYTES); + __enable_irq(); + if (status != kStatus_Success) { + break; + } + } + SCB_EnableDCache(); + return status; +} + +STATIC mp_obj_t mimxrt_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + // Check args. + mp_arg_check_num(n_args, n_kw, 0, 0, false); + + // Upload the custom flash configuration + // This should be performed by the boot ROM but for some reason it is not. + FLEXSPI_UpdateLUT(FLEXSPI, 0, + qspiflash_config.memConfig.lookupTable, + sizeof(qspiflash_config.memConfig.lookupTable) / sizeof(qspiflash_config.memConfig.lookupTable[0])); + + // Configure FLEXSPI IP FIFO access. + FLEXSPI->MCR0 &= ~(FLEXSPI_MCR0_ARDFEN_MASK); + FLEXSPI->MCR0 &= ~(FLEXSPI_MCR0_ATDFEN_MASK); + FLEXSPI->MCR0 |= FLEXSPI_MCR0_ARDFEN(0); + FLEXSPI->MCR0 |= FLEXSPI_MCR0_ATDFEN(0); + + // Update information based on linker symbols. + mimxrt_flash_obj.flash_base = MICROPY_HW_FLASH_STORAGE_BASE; + mimxrt_flash_obj.flash_size = MICROPY_HW_FLASH_STORAGE_BYTES; + + // Return singleton object. + return MP_OBJ_FROM_PTR(&mimxrt_flash_obj); +} + +// readblocks(block_num, buf, [offset]) +// read size of buffer number of bytes from block (with offset) into buffer +STATIC mp_obj_t mimxrt_flash_readblocks(size_t n_args, const mp_obj_t *args) { + mimxrt_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE); + // if (n_args == 4) { + // mp_printf(MP_PYTHON_PRINTER, "readblocks: nargs = %d, block = %d, offset = %d, len = %d\n", + // n_args, mp_obj_get_int(args[1]), mp_obj_get_int(args[3]), bufinfo.len); + // } else { + // mp_printf(MP_PYTHON_PRINTER, "readblocks: nargs = %d, block = %d, len = %d\n", + // n_args, mp_obj_get_int(args[1]), bufinfo.len); + // } + // Calculate read offset from block number. + uint32_t offset = mp_obj_get_int(args[1]) * SECTOR_SIZE_BYTES; + // Add optional offset + if (n_args == 4) { + offset += mp_obj_get_int(args[3]); + } + memcpy(bufinfo.buf, (uint8_t *)(FlexSPI_AMBA_BASE + self->flash_base + offset), bufinfo.len); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mimxrt_flash_readblocks_obj, 3, 4, mimxrt_flash_readblocks); + +// writeblocks(block_num, buf, [offset]) +// Erase block based on block_num and write buffer size number of bytes from buffer into block. If additional offset +// parameter is provided only write operation at block start + offset will be performed. +// This requires a prior erase operation of the block! +STATIC mp_obj_t mimxrt_flash_writeblocks(size_t n_args, const mp_obj_t *args) { + status_t status; + mimxrt_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); + + // Calculate read offset from block number. + uint32_t offset = mp_obj_get_int(args[1]) * SECTOR_SIZE_BYTES; + + if (n_args == 3) { + status = flash_erase_block(self->flash_base + offset); + + if (status != kStatus_Success) { + mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("flash erase command failed with %d"), status); + } + } else { + // Add optional offset + offset += mp_obj_get_int(args[3]); + } + + status = flash_write_block(self->flash_base + offset, bufinfo.buf, bufinfo.len); + + if (status != kStatus_Success) { + mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("flash block write command failed with %d"), status); + } + + return MP_OBJ_NEW_SMALL_INT(status != kStatus_Success); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mimxrt_flash_writeblocks_obj, 3, 4, mimxrt_flash_writeblocks); + +// ioctl(op, arg) +STATIC mp_obj_t mimxrt_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) { + mimxrt_flash_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t cmd = mp_obj_get_int(cmd_in); + status_t status; + switch (cmd) { + case MP_BLOCKDEV_IOCTL_INIT: + return MP_OBJ_NEW_SMALL_INT(0); + case MP_BLOCKDEV_IOCTL_DEINIT: + return MP_OBJ_NEW_SMALL_INT(0); + case MP_BLOCKDEV_IOCTL_SYNC: + return MP_OBJ_NEW_SMALL_INT(0); + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + return MP_OBJ_NEW_SMALL_INT(self->flash_size / SECTOR_SIZE_BYTES); + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + return MP_OBJ_NEW_SMALL_INT(SECTOR_SIZE_BYTES); + case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: { + uint32_t offset = mp_obj_get_int(arg_in) * SECTOR_SIZE_BYTES; + status = flash_erase_block(self->flash_base + offset); + return MP_OBJ_NEW_SMALL_INT(status != kStatus_Success); + } + default: + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(mimxrt_flash_ioctl_obj, mimxrt_flash_ioctl); + +STATIC const mp_rom_map_elem_t mimxrt_flash_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&mimxrt_flash_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&mimxrt_flash_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mimxrt_flash_ioctl_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(mimxrt_flash_locals_dict, mimxrt_flash_locals_dict_table); + +const mp_obj_type_t mimxrt_flash_type = { + { &mp_type_type }, + .name = MP_QSTR_Flash, + .make_new = mimxrt_flash_make_new, + .locals_dict = (mp_obj_dict_t *)&mimxrt_flash_locals_dict, +}; diff --git a/ports/mimxrt/modmimxrt.c b/ports/mimxrt/modmimxrt.c new file mode 100644 index 0000000000..addd4ba4d2 --- /dev/null +++ b/ports/mimxrt/modmimxrt.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "modmimxrt.h" + +STATIC const mp_rom_map_elem_t mimxrt_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mimxrt) }, + { MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&mimxrt_flash_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(mimxrt_module_globals, mimxrt_module_globals_table); + +const mp_obj_module_t mp_module_mimxrt = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mimxrt_module_globals, +}; diff --git a/ports/mimxrt/modmimxrt.h b/ports/mimxrt/modmimxrt.h new file mode 100644 index 0000000000..e047716691 --- /dev/null +++ b/ports/mimxrt/modmimxrt.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_MIMXRT_MODMIMXRT_H +#define MICROPY_INCLUDED_MIMXRT_MODMIMXRT_H + +#include "py/obj.h" + +extern const mp_obj_type_t mimxrt_flash_type; +extern const mp_obj_module_t mp_module_mimxrt; + +#endif // MICROPY_INCLUDED_MIMXRT_MODMIMXRT_H diff --git a/ports/mimxrt/modules/_boot.py b/ports/mimxrt/modules/_boot.py new file mode 100644 index 0000000000..892d004735 --- /dev/null +++ b/ports/mimxrt/modules/_boot.py @@ -0,0 +1,15 @@ +# _boot.py +# Try to mount the filesystem, and format the flash if it doesn't exist. +# Note: the flash requires the programming size to be aligned to 256 bytes. + +import os +import mimxrt + +bdev = mimxrt.Flash() + +try: + vfs = os.VfsLfs2(bdev, progsize=256) +except: + os.VfsLfs2.mkfs(bdev, progsize=256) + vfs = os.VfsLfs2(bdev, progsize=256) +os.mount(vfs, "/") diff --git a/ports/mimxrt/moduos.c b/ports/mimxrt/moduos.c new file mode 100644 index 0000000000..fe914ce610 --- /dev/null +++ b/ports/mimxrt/moduos.c @@ -0,0 +1,129 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * use of the TRNG by + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Artur Pacholec + * + * 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/objstr.h" +#include "py/runtime.h" +#include "extmod/vfs.h" +#include "extmod/vfs_lfs.h" +#include "genhdr/mpversion.h" +#include "fsl_trng.h" + +STATIC const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + +STATIC MP_DEFINE_ATTRTUPLE( + os_uname_info_obj, + os_uname_info_fields, + 5, + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + (mp_obj_t)&os_uname_info_release_obj, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj + ); + +STATIC mp_obj_t os_uname(void) { + return (mp_obj_t)&os_uname_info_obj; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname); + +STATIC mp_obj_t os_urandom(mp_obj_t num) { + mp_int_t n = mp_obj_get_int(num); + static bool initialized = false; + vstr_t vstr; + vstr_init_len(&vstr, n); + + if (!initialized) { + trng_config_t trngConfig; + + TRNG_GetDefaultConfig(&trngConfig); + trngConfig.sampleMode = kTRNG_SampleModeVonNeumann; + + TRNG_Init(TRNG, &trngConfig); + initialized = true; + } + TRNG_GetRandomData(TRNG, vstr.buf, n); + + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); + +STATIC const mp_rom_map_elem_t os_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, + + { MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) }, + { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) }, + + #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, + { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, + { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) }, + { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, + #endif + + // The following are MicroPython extensions. + + #if MICROPY_PY_OS_DUPTERM + { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) }, + #endif + + #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, + #if MICROPY_VFS_FAT + { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, + #endif + #if MICROPY_VFS_LFS1 + { MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) }, + #endif + #if MICROPY_VFS_LFS2 + { MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) }, + #endif + #endif +}; +STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); + +const mp_obj_module_t mp_module_uos = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&os_module_globals, +}; diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 63ee5ea5cc..db1944a9b8 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -34,20 +34,26 @@ #define MICROPY_GC_ALLOC_THRESHOLD (0) #define MICROPY_ALLOC_PARSE_CHUNK_INIT (32) #define MICROPY_ALLOC_PATH_MAX (256) -#define MICROPY_QSTR_BYTES_IN_HASH (1) // Compiler configuration #define MICROPY_COMP_CONST (0) // Python internal features +#define MICROPY_READER_VFS (1) #define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_STACK_CHECK (1) +#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_KBD_EXCEPTION (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_ENABLE_SOURCE_LINE (1) -#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_STREAMS_NON_BLOCK (1) +#define MICROPY_MODULE_BUILTIN_INIT (1) +#define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) +#define MICROPY_VFS (1) #define MICROPY_MODULE_FROZEN_MPY (1) #define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool @@ -68,22 +74,39 @@ #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_IO_IOBASE (1) +#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_SYS_MAXSIZE (1) +#define MICROPY_PY_SYS_PLATFORM "mimxrt" +#define MICROPY_PY_SYS_STDFILES (1) +#define MICROPY_PY_SYS_STDIO_BUFFER (1) // Extended modules #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_MACHINE (1) +// Use VfsLfs2's types for fileio/textio +#define mp_type_fileio mp_type_vfs_lfs2_fileio +#define mp_type_textio mp_type_vfs_lfs2_textio + +// Use VFS's functions for import stat and builtin open +#define mp_import_stat mp_vfs_import_stat +#define mp_builtin_open_obj mp_vfs_open_obj + // Hooks to add builtins #define MICROPY_PORT_BUILTINS \ { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, extern const struct _mp_obj_module_t mp_module_machine; +extern const struct _mp_obj_module_t mp_module_mimxrt; +extern const struct _mp_obj_module_t mp_module_uos; extern const struct _mp_obj_module_t mp_module_utime; #define MICROPY_PORT_BUILTIN_MODULES \ { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ + { MP_ROM_QSTR(MP_QSTR_mimxrt), (mp_obj_t)&mp_module_mimxrt }, \ + { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \ { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \ #define MICROPY_PORT_ROOT_POINTERS \ diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c index 02a61a4f2a..faecafbbcd 100644 --- a/ports/mimxrt/mphalport.c +++ b/ports/mimxrt/mphalport.c @@ -26,6 +26,7 @@ */ #include "py/runtime.h" +#include "py/stream.h" #include "py/mphal.h" #include "ticks.h" #include "tusb.h" @@ -47,6 +48,14 @@ void mp_hal_set_interrupt_char(int c) { #endif +uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { + uintptr_t ret = 0; + if (tud_cdc_connected() && tud_cdc_available()) { + ret |= MP_STREAM_POLL_RD; + } + return ret; +} + int mp_hal_stdin_rx_chr(void) { for (;;) { // TODO diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 78b390b4eb..fd664346dd 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -73,4 +73,9 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } +static inline uint64_t mp_hal_time_ns(void) { + // TODO: Implement this function. + return 0UL; +} + #endif // MICROPY_INCLUDED_MIMXRT_MPHALPORT_H