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.
This commit is contained in:
robert-hh 2021-07-20 08:18:18 +02:00 committed by Damien George
parent e29259d171
commit 1074c784b0
29 changed files with 713 additions and 186 deletions

View File

@ -133,7 +133,7 @@ SRC_HAL_IMX_C += \
$(MCU_DIR)/drivers/fsl_snvs_lp.c \ $(MCU_DIR)/drivers/fsl_snvs_lp.c \
$(MCU_DIR)/drivers/fsl_trng.c \ $(MCU_DIR)/drivers/fsl_trng.c \
SRC_C = \ SRC_C += \
main.c \ main.c \
led.c \ led.c \
pin.c \ pin.c \
@ -156,7 +156,6 @@ SRC_C = \
modmimxrt.c \ modmimxrt.c \
moduos.c \ moduos.c \
mphalport.c \ mphalport.c \
hal/flexspi_nor_flash.c \
shared/libc/printf.c \ shared/libc/printf.c \
shared/libc/string0.c \ shared/libc/string0.c \
shared/readline/readline.c \ shared/readline/readline.c \

View File

@ -8,6 +8,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(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_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) #define MICROPY_HW_NUM_PIN_IRQS (2 * 32)

View File

@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1011DAE5A
MICROPY_FLOAT_IMPL = single MICROPY_FLOAT_IMPL = single
SRC_C += \
hal/flexspi_nor_flash.c \
JLINK_PATH = /media/RT1010-EVK/ JLINK_PATH = /media/RT1010-EVK/
JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink

View File

@ -9,6 +9,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(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_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) #define MICROPY_HW_NUM_PIN_IRQS (3 * 32)

View File

@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1021DAG5A
MICROPY_FLOAT_IMPL = double MICROPY_FLOAT_IMPL = double
SRC_C += \
hal/flexspi_nor_flash.c \
JLINK_PATH ?= /media/RT1020-EVK/ JLINK_PATH ?= /media/RT1020-EVK/
JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink

View File

@ -8,6 +8,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(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_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) #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3)

View File

@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1052DVL6B
MICROPY_FLOAT_IMPL = double MICROPY_FLOAT_IMPL = double
SRC_C += \
hal/flexspi_nor_flash.c \
JLINK_PATH ?= /media/RT1050-EVK/ JLINK_PATH ?= /media/RT1050-EVK/
deploy: $(BUILD)/firmware.bin deploy: $(BUILD)/firmware.bin

View File

@ -8,8 +8,8 @@ ivt_size = 0x00001000;
interrupts_start = 0x60002000; interrupts_start = 0x60002000;
interrupts_size = 0x00000400; interrupts_size = 0x00000400;
text_start = 0x60002400; 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 = 0x60100000;
vfs_start = (text_start) + (text_size); text_size = ((vfs_start) - (text_start));
vfs_size = ((flash_end) - (vfs_start)); vfs_size = ((flash_end) - (vfs_start));
itcm_start = 0x00000000; itcm_start = 0x00000000;
itcm_size = 0x00020000; itcm_size = 0x00020000;

View File

@ -1 +1 @@
flash_size = 8M; flash_size = 64M;

View File

@ -10,7 +10,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "fsl_common.h" #include "fsl_flexspi.h"
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
@ -224,6 +224,14 @@ typedef struct _FlexSPIConfig
#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11
#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 #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 * Serial NOR configuration block
*/ */

View File

@ -25,98 +25,162 @@ __attribute__((section(".boot_hdr.conf")))
const flexspi_nor_config_t qspiflash_config = { const flexspi_nor_config_t qspiflash_config = {
.memConfig = .memConfig =
{ {
.tag = FLEXSPI_CFG_BLK_TAG, .tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION, .version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3u, .csHoldTime = 3u,
.csSetupTime = 3u, .csSetupTime = 3u,
.sflashPadType = kSerialFlash_4Pads, .columnAddressWidth = 3u,
.serialClkFreq = kFlexSpiSerialClk_100MHz, // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
.sflashA1Size = 8u * 1024u * 1024u, .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 = .lookupTable =
{ {
// 0 Read LUTs 0 -> 0 /* 0 Read Data */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] =
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04),
// 1 Read status register -> 1 /* 1 Write Data */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02),
// 2 Fast read quad mode - SDR /* 2 Read Status */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] =
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 4 Write Enable */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 6 Erase Sector */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 10 program page with word program command sequence */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 12 Erase chip */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] =
// 7 Page Program - quad mode (-> 9) FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] =
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler // +1
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
// 8 Read ID [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] =
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
// 9 Page Program - single mode -> 9 // +2
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] =
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] =
// 10 Enter QPI mode FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler // +3
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
// 11 Erase Chip [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] =
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10),
// 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, .pageSize = 512u,
.sectorSize = 4u * 1024u, .sectorSize = 256u * 1024u,
.blockSize = 64u * 1024u, .blockSize = 256u * 1024u,
.isUniformBlockSize = false, .isUniformBlockSize = true,
}; };
#endif /* XIP_BOOT_HEADER_ENABLE */ #endif /* XIP_BOOT_HEADER_ENABLE */

View File

@ -8,6 +8,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(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_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) #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3)

View File

@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1062DVJ6A
MICROPY_FLOAT_IMPL = double MICROPY_FLOAT_IMPL = double
SRC_C += \
hal/flexspi_hyper_flash.c \
JLINK_PATH ?= /media/RT1060-EVK/ JLINK_PATH ?= /media/RT1060-EVK/
JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink

View File

@ -8,8 +8,8 @@ ivt_size = 0x00001000;
interrupts_start = 0x60002000; interrupts_start = 0x60002000;
interrupts_size = 0x00000400; interrupts_size = 0x00000400;
text_start = 0x60002400; 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 = 0x60100000;
vfs_start = (text_start) + (text_size); text_size = ((vfs_start) - (text_start));
vfs_size = ((flash_end) - (vfs_start)); vfs_size = ((flash_end) - (vfs_start));
itcm_start = 0x00000000; itcm_start = 0x00000000;
itcm_size = 0x00020000; itcm_size = 0x00020000;

View File

@ -1 +1 @@
flash_size = 8M; flash_size = 64M;

View File

@ -10,7 +10,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "fsl_common.h" #include "fsl_flexspi.h"
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
@ -19,9 +19,9 @@
/*@}*/ /*@}*/
/* FLEXSPI memory config block related defintions */ /* 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_VERSION (0x56010400UL) // V1.4.0
#define FLEXSPI_CFG_BLK_SIZE (512) #define FLEXSPI_CFG_BLK_SIZE (512)
/* FLEXSPI Feature related definitions */ /* FLEXSPI Feature related definitions */
#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 #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_ENTERQPI 10
#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11
#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 12 #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 * Serial NOR configuration block
*/ */

View File

@ -25,99 +25,162 @@ __attribute__((section(".boot_hdr.conf")))
const flexspi_nor_config_t qspiflash_config = { const flexspi_nor_config_t qspiflash_config = {
.memConfig = .memConfig =
{ {
.tag = FLEXSPI_CFG_BLK_TAG, .tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION, .version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3u, .csHoldTime = 3u,
.csSetupTime = 3u, .csSetupTime = 3u,
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .columnAddressWidth = 3u,
.sflashPadType = kSerialFlash_4Pads, // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
.serialClkFreq = kFlexSpiSerialClk_100MHz, .controllerMiscOption =
.sflashA1Size = 8u * 1024u * 1024u, (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 = .lookupTable =
{ {
// 0 Read LUTs 0 -> 0 /* 0 Read Data */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] =
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04),
// 1 Read status register -> 1 /* 1 Write Data */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02),
// 2 Fast read quad mode - SDR /* 2 Read Status */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] =
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 4 Write Enable */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 6 Erase Sector */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, READ_SDR, FLEXSPI_1PAD, 0x04), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 10 program page with word program command sequence */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 24), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ(
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler 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 /* 12 Erase chip */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x04), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] =
// 7 Page Program - quad mode (-> 9) FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] =
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler // +1
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
// 8 Read ID [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] =
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x90, DUMMY_SDR, FLEXSPI_1PAD, 24), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x00, 0, 0, 0), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
// 9 Page Program - single mode -> 9 // +2
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 24), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] =
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0, 0, 0, 0), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] =
// 10 Enter QPI mode FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35, STOP, FLEXSPI_1PAD, 0), [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler // +3
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
// 11 Erase Chip [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] =
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0), FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] =
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10),
// 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, .pageSize = 512u,
.sectorSize = 4u * 1024u, .sectorSize = 256u * 1024u,
.blockSize = 256u * 1024u, .blockSize = 256u * 1024u,
.isUniformBlockSize = false, .isUniformBlockSize = true,
}; };
#endif /* XIP_BOOT_HEADER_ENABLE */ #endif /* XIP_BOOT_HEADER_ENABLE */

View File

@ -6,6 +6,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(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_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) #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3)

View File

@ -3,6 +3,9 @@ MCU_VARIANT = MIMXRT1064DVL6A
MICROPY_FLOAT_IMPL = double MICROPY_FLOAT_IMPL = double
SRC_C += \
hal/flexspi_hyper_flash.c \
JLINK_PATH ?= /media/RT1064-EVK/ JLINK_PATH ?= /media/RT1064-EVK/
CFLAGS += -DBOARD_FLASH_SIZE=0x400000 CFLAGS += -DBOARD_FLASH_SIZE=0x400000

View File

@ -8,6 +8,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(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_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) #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3)

View File

@ -3,5 +3,8 @@ MCU_VARIANT = MIMXRT1062DVJ6A
MICROPY_FLOAT_IMPL = double MICROPY_FLOAT_IMPL = double
SRC_C += \
hal/flexspi_nor_flash.c \
deploy: $(BUILD)/firmware.hex deploy: $(BUILD)/firmware.hex
teensy_loader_cli --mcu=imxrt1062 -v -w $< teensy_loader_cli --mcu=imxrt1062 -v -w $<

View File

@ -8,6 +8,7 @@
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(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_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) #define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3)

View File

@ -3,5 +3,8 @@ MCU_VARIANT = MIMXRT1062DVJ6A
MICROPY_FLOAT_IMPL = double MICROPY_FLOAT_IMPL = double
SRC_C += \
hal/flexspi_nor_flash.c \
deploy: $(BUILD)/firmware.hex deploy: $(BUILD)/firmware.hex
teensy_loader_cli --mcu=imxrt1062 -v -w $< teensy_loader_cli --mcu=imxrt1062 -v -w $<

View File

@ -178,12 +178,14 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
__DATA_RAM = .; __DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */ __data_start__ = .; /* create a global symbol at data start */
__data_section_table = .;
*(m_usb_dma_init_data) *(m_usb_dma_init_data)
*(.data) /* .data sections */ *(.data) /* .data sections */
*(.data*) /* .data* sections */ *(.data*) /* .data* sections */
KEEP(*(.jcr*)) KEEP(*(.jcr*))
. = ALIGN(4); . = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */ __data_end__ = .; /* define a global symbol at data end */
__data_section_table_end = .;
} > m_dtcm } > m_dtcm
__RAM_FUNCTIONS_ROM = __DATA_ROM + (__data_end__ - __data_start__); __RAM_FUNCTIONS_ROM = __DATA_ROM + (__data_end__ - __data_start__);
@ -224,12 +226,14 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
__START_BSS = .; __START_BSS = .;
__bss_start__ = .; __bss_start__ = .;
__bss_section_table = .;
*(m_usb_dma_noninit_data) *(m_usb_dma_noninit_data)
*(.bss) *(.bss)
*(.bss*) *(.bss*)
*(COMMON) *(COMMON)
. = ALIGN(4); . = ALIGN(4);
__bss_end__ = .; __bss_end__ = .;
__bss_section_table_end = .;
__END_BSS = .; __END_BSS = .;
} > m_dtcm } > m_dtcm
@ -253,6 +257,7 @@ SECTIONS
/* Initializes stack on the end of block */ /* Initializes stack on the end of block */
__StackTop = ORIGIN(m_dtcm) + LENGTH(m_dtcm); __StackTop = ORIGIN(m_dtcm) + LENGTH(m_dtcm);
__StackLimit = __StackTop - STACK_SIZE; __StackLimit = __StackTop - STACK_SIZE;
_vStackTop = __StackTop;
PROVIDE(__stack = __StackTop); PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) } .ARM.attributes 0 : { *(.ARM.attributes) }

View File

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

View File

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

View File

@ -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_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); 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 #endif // MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H

View File

@ -30,9 +30,10 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "extmod/vfs.h" #include "extmod/vfs.h"
#include "modmimxrt.h" #include "modmimxrt.h"
#include "hal/flexspi_nor_flash.h" #include BOARD_FLASH_OPS_HEADER_H
// BOARD_FLASH_SIZE is defined in mpconfigport.h // BOARD_FLASH_SIZE is defined in mpconfigport.h
#define SECTOR_SIZE_BYTES (qspiflash_config.sectorSize) #define SECTOR_SIZE_BYTES (qspiflash_config.sectorSize)
#define PAGE_SIZE_BYTES (qspiflash_config.pageSize) #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) // 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) __attribute__((section(".ram_functions")));
status_t flash_erase_block(uint32_t erase_addr) { status_t flash_erase_block(uint32_t erase_addr) {
status_t status; 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) // flash_write_block(flash_dest_addr_bytes, data_source, length_bytes)
// writes length_byte data to the destination address // 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 // 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) __attribute__((section(".ram_functions")));
status_t flash_write_block(uint32_t dest_addr, const uint8_t *src, uint32_t length) { status_t flash_write_block(uint32_t dest_addr, const uint8_t *src, uint32_t length) {
status_t status; status_t status;
uint32_t size;
uint32_t next_addr;
SCB_CleanInvalidateDCache(); SCB_CleanInvalidateDCache();
SCB_DisableDCache(); SCB_DisableDCache();
// write sector in page size chunks // write data in chunks not crossing a page boundary
for (int i = 0; i < length; i += PAGE_SIZE_BYTES) { 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(); __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(); __enable_irq();
if (status != kStatus_Success) { if (status != kStatus_Success) {
break; break;
} }
length -= size;
src += size;
dest_addr += size;
} }
SCB_EnableDCache(); SCB_EnableDCache();
return status; 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. // This should be performed by the boot ROM but for some reason it is not.
FLEXSPI_UpdateLUT(FLEXSPI, 0, FLEXSPI_UpdateLUT(FLEXSPI, 0,
qspiflash_config.memConfig.lookupTable, 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. // Configure FLEXSPI IP FIFO access.
FLEXSPI->MCR0 &= ~(FLEXSPI_MCR0_ARDFEN_MASK); FLEXSPI->MCR0 &= ~(FLEXSPI_MCR0_ARDFEN_MASK);

View File

@ -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) { __attribute__((always_inline)) static inline uint32_t disable_irq(void) {
uint32_t state = __get_PRIMASK(); uint32_t state = __get_PRIMASK();
__disable_irq();
return state; return state;
} }