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.
This commit is contained in:
robert-hh 2021-05-07 15:21:09 +02:00 committed by Damien George
parent c303b15f10
commit dfd4324eb1
42 changed files with 1745 additions and 210 deletions

View File

@ -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 };"

View File

@ -0,0 +1 @@
flash_size = 16M;

View File

@ -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

View File

@ -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,

View File

@ -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"

View File

@ -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);

View File

@ -0,0 +1 @@
flash_size = 8M;

View File

@ -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

View File

@ -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 */

View File

@ -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"

View File

@ -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);

View File

@ -0,0 +1 @@
flash_size = 8M;

View File

@ -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

View File

@ -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,

View File

@ -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"

View File

@ -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);

View File

@ -0,0 +1 @@
flash_size = 8M;

View File

@ -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

View File

@ -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,

View File

@ -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"

View File

@ -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);

View File

@ -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);
_gc_heap_start = ORIGIN(m_ocrm);
_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm);

View File

@ -0,0 +1 @@
flash_size = 8M;

View File

@ -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

View File

@ -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,

View File

@ -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"

View File

@ -0,0 +1,2 @@
flash_size = 2M;
reserved_size = 4K;

View File

@ -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 */

View File

@ -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"

View File

@ -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

View File

@ -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")
}

View File

@ -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 <assert.h>
#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;
}

View File

@ -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

View File

@ -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 (;;) {
}

221
ports/mimxrt/mimxrt_flash.c Normal file
View File

@ -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 <string.h>
#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,
};

39
ports/mimxrt/modmimxrt.c Normal file
View File

@ -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,
};

34
ports/mimxrt/modmimxrt.h Normal file
View File

@ -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

View File

@ -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, "/")

129
ports/mimxrt/moduos.c Normal file
View File

@ -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,
};

View File

@ -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 \

View File

@ -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

View File

@ -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