From 1074c784b0b35c826e0c65b36d2e77ea17970103 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 20 Jul 2021 08:18:18 +0200 Subject: [PATCH] mimxrt: Add support for Hyperflash chips. Hyperflash is used by the MIMXRT1050_EVKB, MIMXRT1060_EVK and MIMXRT1064_EVK boards. This commit includes: - add support for Hyperflash - modify MIMXRT1060_EVK and MIMXRT1064_EVK to change from QSPI to hyperflash. - minor incidental changes to other boards so they still build Note: Erasing a sector on the hyperflash is slow. It takes about a second, which seems too long, but matches the data sheet. --- ports/mimxrt/Makefile | 3 +- .../boards/MIMXRT1010_EVK/mpconfigboard.h | 1 + .../boards/MIMXRT1010_EVK/mpconfigboard.mk | 3 + .../boards/MIMXRT1020_EVK/mpconfigboard.h | 1 + .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 3 + .../boards/MIMXRT1050_EVK/mpconfigboard.h | 1 + .../boards/MIMXRT1050_EVK/mpconfigboard.mk | 3 + ports/mimxrt/boards/MIMXRT1052.ld | 4 +- .../boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld | 2 +- .../evkmimxrt1060_flexspi_nor_config.h | 10 +- .../boards/MIMXRT1060_EVK/flash_config.c | 230 ++++++++++------ .../boards/MIMXRT1060_EVK/mpconfigboard.h | 1 + .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 3 + ports/mimxrt/boards/MIMXRT1064.ld | 6 +- .../boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld | 2 +- .../evkmimxrt1064_flexspi_nor_config.h | 15 +- .../boards/MIMXRT1064_EVK/flash_config.c | 229 ++++++++++------ .../boards/MIMXRT1064_EVK/mpconfigboard.h | 1 + .../boards/MIMXRT1064_EVK/mpconfigboard.mk | 3 + ports/mimxrt/boards/TEENSY40/mpconfigboard.h | 1 + ports/mimxrt/boards/TEENSY40/mpconfigboard.mk | 3 + ports/mimxrt/boards/TEENSY41/mpconfigboard.h | 1 + ports/mimxrt/boards/TEENSY41/mpconfigboard.mk | 3 + ports/mimxrt/boards/common.ld | 5 + ports/mimxrt/hal/flexspi_hyper_flash.c | 247 ++++++++++++++++++ ports/mimxrt/hal/flexspi_hyper_flash.h | 71 +++++ ports/mimxrt/hal/flexspi_nor_flash.h | 21 ++ ports/mimxrt/mimxrt_flash.c | 25 +- ports/mimxrt/mpconfigport.h | 1 + 29 files changed, 713 insertions(+), 186 deletions(-) create mode 100644 ports/mimxrt/hal/flexspi_hyper_flash.c create mode 100644 ports/mimxrt/hal/flexspi_hyper_flash.h diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 580dc32c7e..818a2a3c84 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -133,7 +133,7 @@ SRC_HAL_IMX_C += \ $(MCU_DIR)/drivers/fsl_snvs_lp.c \ $(MCU_DIR)/drivers/fsl_trng.c \ -SRC_C = \ +SRC_C += \ main.c \ led.c \ pin.c \ @@ -156,7 +156,6 @@ SRC_C = \ modmimxrt.c \ moduos.c \ mphalport.c \ - hal/flexspi_nor_flash.c \ shared/libc/printf.c \ shared/libc/string0.c \ shared/readline/readline.c \ diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index 756eaf85eb..2cdb433e18 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -8,6 +8,7 @@ #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" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (2 * 32) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index ca8efcd5bf..ccc8ffeb41 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1011DAE5A MICROPY_FLOAT_IMPL = single +SRC_C += \ + hal/flexspi_nor_flash.c \ + JLINK_PATH = /media/RT1010-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index b0574fad0f..d2a2cbbdbd 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -9,6 +9,7 @@ #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" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (3 * 32) diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index b0bbd705cb..f8f66b0dff 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1021DAG5A MICROPY_FLOAT_IMPL = double +SRC_C += \ + hal/flexspi_nor_flash.c \ + JLINK_PATH ?= /media/RT1020-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index 5d920d5286..af0975bc17 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -8,6 +8,7 @@ #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" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk index e338ec6cf8..61826b6f60 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk @@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1052DVL6B MICROPY_FLOAT_IMPL = double +SRC_C += \ + hal/flexspi_nor_flash.c \ + JLINK_PATH ?= /media/RT1050-EVK/ deploy: $(BUILD)/firmware.bin diff --git a/ports/mimxrt/boards/MIMXRT1052.ld b/ports/mimxrt/boards/MIMXRT1052.ld index f78773531a..7519297940 100644 --- a/ports/mimxrt/boards/MIMXRT1052.ld +++ b/ports/mimxrt/boards/MIMXRT1052.ld @@ -8,8 +8,8 @@ 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_start = 0x60100000; +text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; itcm_size = 0x00020000; diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld index fd1bf32ede..f616178a9b 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/MIMXRT1060_EVK.ld @@ -1 +1 @@ -flash_size = 8M; \ No newline at end of file +flash_size = 64M; \ 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 03bdac1f1c..cff520e0e2 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/evkmimxrt1060_flexspi_nor_config.h @@ -10,7 +10,7 @@ #include #include -#include "fsl_common.h" +#include "fsl_flexspi.h" /*! @name Driver version */ /*@{*/ @@ -224,6 +224,14 @@ typedef struct _FlexSPIConfig #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 #define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 + /* * Serial NOR configuration block */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c index 3fa584b73a..e28f581547 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/flash_config.c @@ -25,98 +25,162 @@ __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .memConfig = { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_100MHz, - .sflashA1Size = 8u * 1024u * 1024u, + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = 64u * 1024u * 1024u, + .dataValidTime = {16u, 16u}, .lookupTable = { - // 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 + /* 0 Read Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - // 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 + /* 1 Write Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - // 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 + /* 2 Read Status */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - // 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 Write Enable */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // 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 + /* 6 Erase Sector */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - // 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 + /* 10 program page with word program command sequence */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - // 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 + /* 12 Erase chip */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), }, }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, - .blockSize = 64u * 1024u, - .isUniformBlockSize = false, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, }; + #endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index f849cba966..c207da832e 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -8,6 +8,7 @@ #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" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_hyper_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index b7ea5fcbe1..f5eaf3eab5 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double +SRC_C += \ + hal/flexspi_hyper_flash.c \ + JLINK_PATH ?= /media/RT1060-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1064.ld b/ports/mimxrt/boards/MIMXRT1064.ld index 236d984293..8203930017 100644 --- a/ports/mimxrt/boards/MIMXRT1064.ld +++ b/ports/mimxrt/boards/MIMXRT1064.ld @@ -8,8 +8,8 @@ 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_start = 0x60100000; +text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); itcm_start = 0x00000000; itcm_size = 0x00020000; @@ -25,4 +25,4 @@ _sstack = __StackLimit; /* Use second OCRAM bank for GC heap. */ _gc_heap_start = ORIGIN(m_ocrm); -_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); \ No newline at end of file +_gc_heap_end = ORIGIN(m_ocrm) + LENGTH(m_ocrm); diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld index fd1bf32ede..f616178a9b 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/MIMXRT1064_EVK.ld @@ -1 +1 @@ -flash_size = 8M; \ No newline at end of file +flash_size = 64M; \ 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 3c433f3be9..7560f24836 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/evkmimxrt1064_flexspi_nor_config.h @@ -10,7 +10,7 @@ #include #include -#include "fsl_common.h" +#include "fsl_flexspi.h" /*! @name Driver version */ /*@{*/ @@ -19,9 +19,9 @@ /*@}*/ /* FLEXSPI memory config block related defintions */ -#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 -#define FLEXSPI_CFG_BLK_SIZE (512) +#define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 @@ -223,6 +223,15 @@ typedef struct _FlexSPIConfig #define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10 #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 #define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 + +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 + /* * Serial NOR configuration block */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c b/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c index 9338c6948a..f308b7f8ad 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/flash_config.c @@ -25,99 +25,162 @@ __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .memConfig = { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, - .csHoldTime = 3u, - .csSetupTime = 3u, - // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock - .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_100MHz, - .sflashA1Size = 8u * 1024u * 1024u, + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = 64u * 1024u * 1024u, + .dataValidTime = {16u, 16u}, .lookupTable = { - // 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 + /* 0 Read Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), - // 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 + /* 1 Write Data */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02), - // 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 + /* 2 Read Status */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), - // 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 Write Enable */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), - // 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 + /* 6 Erase Sector */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), - // 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 + /* 10 program page with word program command sequence */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0 + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80), - // 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 + /* 12 Erase chip */ + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), + // +1 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + // +2 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55), + // +3 + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05), + [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] = + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10), }, }, - .pageSize = 256u, - .sectorSize = 4u * 1024u, + .pageSize = 512u, + .sectorSize = 256u * 1024u, .blockSize = 256u * 1024u, - .isUniformBlockSize = false, + .isUniformBlockSize = true, }; + #endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index 2301f34131..59f28b0e2a 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -6,6 +6,7 @@ #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" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_hyper_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk index bd4c496416..444fe99672 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk @@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1064DVL6A MICROPY_FLOAT_IMPL = double +SRC_C += \ + hal/flexspi_hyper_flash.c \ + JLINK_PATH ?= /media/RT1064-EVK/ CFLAGS += -DBOARD_FLASH_SIZE=0x400000 diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h index b6c81a4229..aacee4623c 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -8,6 +8,7 @@ #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" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk index beab16c086..a15dd78128 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk @@ -3,5 +3,8 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double +SRC_C += \ + hal/flexspi_nor_flash.c \ + deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h index 17d2751682..a72bd127b6 100644 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.h @@ -8,6 +8,7 @@ #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 "teensy41_flexspi_nor_config.h" +#define BOARD_FLASH_OPS_HEADER_H "hal/flexspi_nor_flash.h" #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk index beab16c086..a15dd78128 100755 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk @@ -3,5 +3,8 @@ MCU_VARIANT = MIMXRT1062DVJ6A MICROPY_FLOAT_IMPL = double +SRC_C += \ + hal/flexspi_nor_flash.c \ + deploy: $(BUILD)/firmware.hex teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/ports/mimxrt/boards/common.ld b/ports/mimxrt/boards/common.ld index e5d91f1191..6f45da24d1 100644 --- a/ports/mimxrt/boards/common.ld +++ b/ports/mimxrt/boards/common.ld @@ -178,12 +178,14 @@ SECTIONS . = ALIGN(4); __DATA_RAM = .; __data_start__ = .; /* create a global symbol at data start */ + __data_section_table = .; *(m_usb_dma_init_data) *(.data) /* .data sections */ *(.data*) /* .data* sections */ KEEP(*(.jcr*)) . = ALIGN(4); __data_end__ = .; /* define a global symbol at data end */ + __data_section_table_end = .; } > m_dtcm __RAM_FUNCTIONS_ROM = __DATA_ROM + (__data_end__ - __data_start__); @@ -224,12 +226,14 @@ SECTIONS . = ALIGN(4); __START_BSS = .; __bss_start__ = .; + __bss_section_table = .; *(m_usb_dma_noninit_data) *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; + __bss_section_table_end = .; __END_BSS = .; } > m_dtcm @@ -253,6 +257,7 @@ SECTIONS /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_dtcm) + LENGTH(m_dtcm); __StackLimit = __StackTop - STACK_SIZE; + _vStackTop = __StackTop; PROVIDE(__stack = __StackTop); .ARM.attributes 0 : { *(.ARM.attributes) } diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.c b/ports/mimxrt/hal/flexspi_hyper_flash.c new file mode 100644 index 0000000000..fb71d4d941 --- /dev/null +++ b/ports/mimxrt/hal/flexspi_hyper_flash.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_clock.h" +#include "flexspi_hyper_flash.h" + +// Copy of a few (pseudo-)functions from fsl_clock.h, which were nor reliably +// inlined when they should be. That caused DEBUG mode to fail. +// It does not increase the code size, since they were supposed to be inline. + +__attribute__((always_inline)) static inline void clock_set_div(clock_div_t divider, uint32_t value) { + uint32_t busyShift; + + busyShift = CCM_TUPLE_BUSY_SHIFT(divider); + CCM_TUPLE_REG(CCM, divider) = (CCM_TUPLE_REG(CCM, divider) & (~CCM_TUPLE_MASK(divider))) | + (((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider)); + + /* Clock switch need Handshake? */ + if (CCM_NO_BUSY_WAIT != busyShift) { + /* Wait until CCM internal handshake finish. */ + while (CCM->CDHIPR & (1U << busyShift)) {} + } +} + +__attribute__((always_inline)) static inline void clock_control_gate(clock_ip_name_t name, clock_gate_value_t value) { + uint32_t index = ((uint32_t)name) >> 8U; + uint32_t shift = ((uint32_t)name) & 0x1FU; + volatile uint32_t *reg; + + reg = ((volatile uint32_t *)&CCM->CCGR0) + index; + *reg = ((*reg) & ~(3U << shift)) | (((uint32_t)value) << shift); +} + +__attribute__((always_inline)) static inline void clock_enable_clock(clock_ip_name_t name) { + clock_control_gate(name, kCLOCK_ClockNeededRunWait); +} + +__attribute__((always_inline)) static inline void clock_disable_clock(clock_ip_name_t name) { + clock_control_gate(name, kCLOCK_ClockNotNeeded); +} + +#define DIV_PAGE_PGM 4 +#define DIV_ERASE_PGM 4 +#define DIV_READ 0 + +static void SetFlexSPIDiv(uint32_t div) __attribute__((section(".ram_functions"))); +static void SetFlexSPIDiv(uint32_t div) { + FLEXSPI_Enable(FLEXSPI, false); + clock_disable_clock(kCLOCK_FlexSpi); + clock_set_div(kCLOCK_FlexspiDiv, div); /* flexspi clock 332M, DDR mode, internal clock 166M. */ + clock_enable_clock(kCLOCK_FlexSpi); + FLEXSPI_Enable(FLEXSPI, true); +} + +status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) __attribute__((section(".ram_functions"))); +status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) { + flexspi_transfer_t flashXfer; + status_t status; + + flashXfer.deviceAddress = addr * 2; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Read; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA; + flashXfer.data = buffer; + flashXfer.dataSize = bytes; + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + return status; +} + +status_t flexspi_nor_hyperbus_write(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) __attribute__((section(".ram_functions"))); +status_t flexspi_nor_hyperbus_write(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) { + flexspi_transfer_t flashXfer; + status_t status; + + flashXfer.deviceAddress = addr * 2; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Write; + flashXfer.SeqNumber = 1; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA; + flashXfer.data = buffer; + flashXfer.dataSize = bytes; + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + return status; +} + +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 enable */ + flashXfer.deviceAddress = baseAddr; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Command; + flashXfer.SeqNumber = 2; + flashXfer.seqIndex = HYPERFLASH_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 = 2; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS; + flashXfer.data = &readValue; + flashXfer.dataSize = 2; + + do { + status = FLEXSPI_TransferBlocking(base, &flashXfer); + + if (status != kStatus_Success) { + return status; + } + if (readValue & 0x8000) { + isBusy = false; + } else { + isBusy = true; + } + + if (readValue & 0x3200) { + status = kStatus_Fail; + break; + } + + } while (isBusy); + + 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; + } + + flashXfer.deviceAddress = address; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Command; + flashXfer.SeqNumber = 4; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR; + 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_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size ) __attribute__((section(".ram_functions"))); +status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size) { + status_t status; + flexspi_transfer_t flashXfer; + + /* Speed down flexspi clock */ + SetFlexSPIDiv(DIV_PAGE_PGM); + + /* Write enable */ + status = flexspi_nor_write_enable(base, address); + + if (status != kStatus_Success) { + return status; + } + + /* Prepare page program command */ + flashXfer.deviceAddress = address; + flashXfer.port = kFLEXSPI_PortA1; + flashXfer.cmdType = kFLEXSPI_Write; + flashXfer.SeqNumber = 2; + flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM; + 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); + + SetFlexSPIDiv(DIV_READ); + + return status; +} + +status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))); +status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base) { + /* + * Read ID-CFI Parameters + */ + // CFI Entry + status_t status; + uint32_t buffer[2]; + uint8_t data[4] = {0x00, 0x98}; + status = flexspi_nor_hyperbus_write(base, 0x555, (uint32_t *)data, 2); + if (status != kStatus_Success) { + return status; + } + + // ID-CFI Read + // Read Query Unique ASCII String + status = flexspi_nor_hyperbus_read(base, 0x10, &buffer[0], sizeof(buffer)); + if (status != kStatus_Success) { + return status; + } + buffer[1] &= 0xFFFF; + // Check that the data read out is unicode "QRY" in big-endian order + if ((buffer[0] != 0x52005100) || (buffer[1] != 0x5900)) { + status = kStatus_Fail; + return status; + } + // ASO Exit 0xF000 + data[1] = 0xF0; + status = flexspi_nor_hyperbus_write(base, 0x0, (uint32_t *)data, 2); + if (status != kStatus_Success) { + return status; + } + + return status; +} diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.h b/ports/mimxrt/hal/flexspi_hyper_flash.h new file mode 100644 index 0000000000..bba76c1324 --- /dev/null +++ b/ports/mimxrt/hal/flexspi_hyper_flash.h @@ -0,0 +1,71 @@ +/* + * 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_HYPER_FLASH_H +#define MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H + +#include "mpconfigboard.h" +#include "fsl_flexspi.h" +#include BOARD_FLASH_CONFIG_HEADER_H + +// Defined in boards flash_config.c +extern flexspi_nor_config_t qspiflash_config; + +status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base); +void flexspi_hyper_flash_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); + +static inline uint32_t flexspi_get_frequency(void) { + uint32_t div; + uint32_t fre; + + /* Clock divider: + 000 divided by 1 + 001 divided by 2 + 010 divided by 3 + 011 divided by 4 + 100 divided by 5 + 101 divided by 6 + 110 divided by 7 + 111 divided by 8 + */ + div = CLOCK_GetDiv(kCLOCK_FlexspiDiv); + /* Get frequency */ + fre = CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (div + 0x01U); + + return fre; +} + +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10 +#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12 + +#endif // MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H diff --git a/ports/mimxrt/hal/flexspi_nor_flash.h b/ports/mimxrt/hal/flexspi_nor_flash.h index a9a9bbe700..c34df74168 100644 --- a/ports/mimxrt/hal/flexspi_nor_flash.h +++ b/ports/mimxrt/hal/flexspi_nor_flash.h @@ -39,4 +39,25 @@ 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); +static inline uint32_t flexspi_get_frequency(void) { + uint32_t div; + uint32_t fre; + + /* Clock divider: + 000 divided by 1 + 001 divided by 2 + 010 divided by 3 + 011 divided by 4 + 100 divided by 5 + 101 divided by 6 + 110 divided by 7 + 111 divided by 8 + */ + div = CLOCK_GetDiv(kCLOCK_FlexspiDiv); + /* Get frequency */ + fre = CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (div + 0x01U); + + return fre; +} + #endif // MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index bf054c87f4..79c4e676dc 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -30,9 +30,10 @@ #include "py/runtime.h" #include "extmod/vfs.h" #include "modmimxrt.h" -#include "hal/flexspi_nor_flash.h" +#include BOARD_FLASH_OPS_HEADER_H // BOARD_FLASH_SIZE is defined in mpconfigport.h + #define SECTOR_SIZE_BYTES (qspiflash_config.sectorSize) #define PAGE_SIZE_BYTES (qspiflash_config.pageSize) @@ -62,7 +63,7 @@ STATIC mimxrt_flash_obj_t mimxrt_flash_obj = { }; // flash_erase_block(erase_addr_bytes) -// erases the 4k sector starting at adddr +// erases the sector starting at addr. Sector size according to the flash properties. 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; @@ -77,21 +78,31 @@ status_t flash_erase_block(uint32_t erase_addr) { // 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; + uint32_t size; + uint32_t next_addr; + SCB_CleanInvalidateDCache(); SCB_DisableDCache(); - // write sector in page size chunks - for (int i = 0; i < length; i += PAGE_SIZE_BYTES) { + // write data in chunks not crossing a page boundary + while (length > 0) { + next_addr = dest_addr - (dest_addr % PAGE_SIZE_BYTES) + PAGE_SIZE_BYTES; // next page boundary + size = next_addr - dest_addr; // maximal chunk length + if (size > length) { // compare against remaining data size + size = length; + } __disable_irq(); - status = flexspi_nor_flash_page_program(FLEXSPI, dest_addr + i, (uint32_t *)(src + i), PAGE_SIZE_BYTES); + status = flexspi_nor_flash_page_program(FLEXSPI, dest_addr, (uint32_t *)src, size); __enable_irq(); if (status != kStatus_Success) { break; } + length -= size; + src += size; + dest_addr += size; } SCB_EnableDCache(); return status; @@ -105,7 +116,7 @@ STATIC mp_obj_t mimxrt_flash_make_new(const mp_obj_type_t *type, size_t n_args, // 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])); + ARRAY_SIZE(qspiflash_config.memConfig.lookupTable)); // Configure FLEXSPI IP FIFO access. FLEXSPI->MCR0 &= ~(FLEXSPI_MCR0_ARDFEN_MASK); diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index e1e102797a..1066b93e16 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -145,6 +145,7 @@ __attribute__((always_inline)) static inline void enable_irq(uint32_t state) { __attribute__((always_inline)) static inline uint32_t disable_irq(void) { uint32_t state = __get_PRIMASK(); + __disable_irq(); return state; }