From 4dd7363ee9f9c0aba1d83ab18dee6f9418db03e7 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 24 Dec 2024 14:32:29 +0100 Subject: [PATCH] mr-tropic LittleFS on NOR flash storag --- boards/nxp/mr-tropic/default.px4board | 2 +- .../nxp/mr-tropic/nuttx-config/nsh/defconfig | 5 +- .../scripts/itcm_static_functions.ld | 14 +++ .../mr-tropic/nuttx-config/scripts/script.ld | 2 +- .../mr-tropic/src/imxrt_flexspi_nor_flash.c | 23 ---- .../nxp/mr-tropic/src/imxrt_flexspi_storage.c | 119 +++++++++++++++--- 6 files changed, 123 insertions(+), 42 deletions(-) diff --git a/boards/nxp/mr-tropic/default.px4board b/boards/nxp/mr-tropic/default.px4board index 38665129aa..af8a30fd97 100644 --- a/boards/nxp/mr-tropic/default.px4board +++ b/boards/nxp/mr-tropic/default.px4board @@ -5,7 +5,7 @@ CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS2" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS3" -CONFIG_BOARD_PARAM_FILE="/fs/microsd/mtd_params" +CONFIG_BOARD_PARAM_FILE="/fs/nor/mtd_params" CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP388=y CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y diff --git a/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig b/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig index 5e956f84e3..8020691687 100644 --- a/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig +++ b/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig @@ -60,6 +60,8 @@ CONFIG_FS_BINFS=y CONFIG_FS_CROMFS=y CONFIG_FS_FAT=y CONFIG_FS_FATTIME=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=2 CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_MAX_TASKS=64 CONFIG_FS_PROCFS_REGISTER=y @@ -81,6 +83,7 @@ CONFIG_IMXRT_ENET_PHYINIT=y CONFIG_IMXRT_FLEXCAN3=y CONFIG_IMXRT_FLEXCAN_TXMB=1 CONFIG_IMXRT_FLEXSPI2=y +CONFIG_IMXRT_FLEXSPI2_XIP=y CONFIG_IMXRT_GPIO1_0_15_IRQ=y CONFIG_IMXRT_GPIO1_16_31_IRQ=y CONFIG_IMXRT_GPIO2_0_15_IRQ=y @@ -118,7 +121,7 @@ CONFIG_INTELHEX_BINARY=y CONFIG_IOB_NBUFFERS=24 CONFIG_IOB_THROTTLE=0 CONFIG_IPCFG_BINARY=y -CONFIG_IPCFG_PATH="/fs/microsd" +CONFIG_IPCFG_PATH="/fs/nor" CONFIG_LIBC_MAX_EXITFUNS=1 CONFIG_LIBC_STRERROR=y CONFIG_LPI2C1_DMA=y diff --git a/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld b/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld index 8b228a22f8..6f294b812d 100644 --- a/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld +++ b/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld @@ -117,3 +117,17 @@ *(.text.ipv4_input) *(.text.work_thread) *(.text.work_queue) + +/* Flash Storage */ +*(.text.imxrt_flexspi_transfer_blocking) +*(.text.imxrt_flexspi_transfer_blocking_private) +*(.text.imxrt_flexspi_write_blocking) +*(.text.imxrt_flexspi_read_blocking) +*(.text.imxrt_flexspi_check_and_clear_error) +*(.text.imxrt_flexspi_get_bus_idle_status) +*(.text.imxrt_flexspi_storage_write_enable) +*(.text.imxrt_flexspi_storage_wait_bus_busy) +*(.text.imxrt_flexspi_storage_read_status) +*(.text.imxrt_flexspi_storage_erase) +*(.text.imxrt_flexspi_storage_bwrite) +*(.text.imxrt_flexspi_storage_page_program) diff --git a/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld b/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld index a7b9e175f3..9edbcadc88 100644 --- a/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld +++ b/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld @@ -22,7 +22,7 @@ MEMORY { - flash (rx) : ORIGIN = 0x70000000, LENGTH = 3968K + flash (rx) : ORIGIN = 0x70000000, LENGTH = 4194304 - 128K sram (rwx) : ORIGIN = 0x20200000, LENGTH = 512K itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 384K dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c index 291616d571..efc6af661f 100644 --- a/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c @@ -50,29 +50,6 @@ const struct flexspi_nor_config_s g_flash_config = { [0 + 1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), - /* Read Status Register-1 */ - [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, - READ_SDR, FLEXSPI_1PAD, 0x04), - - /* Write Status Register-1 */ - [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x0), - - /* Sector Erase (4KB) */ - [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, - RADDR_SDR, FLEXSPI_1PAD, 0x18), - - /* Block Erase (64KB) */ - [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xd8, - RADDR_SDR, FLEXSPI_1PAD, 0x18), - - /* Page Program */ - [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, - RADDR_SDR, FLEXSPI_1PAD, 0x18), - [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, - STOP, FLEXSPI_1PAD, 0x0), - - /* Chip Erase */ - [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0), }, }, diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c b/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c index 3ecfb25b01..4082f85a9a 100644 --- a/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c @@ -43,12 +43,13 @@ #ifdef CONFIG_IMXRT_FLEXSPI -#define NOR_USED_SECTORS 0x0040U /* 64 * 4KB = 256KB */ - -#define NOR_TOTAL_SECTORS 0x0400U +#define NOR_USED_SECTORS (0x20U) /* 32 * 4KB = 128KB */ +#define NOR_TOTAL_SECTORS (0x0400U) +#define NOR_PAGE_SIZE (0x0100U) /* 256 bytes */ +#define NOR_SECTOR_SIZE (0x1000U) /* 4KB */ #define NOR_START_SECTOR (NOR_TOTAL_SECTORS - NOR_USED_SECTORS) -#define NOR_PAGE_SIZE 0x0100U /* 256 bytes */ -#define NOR_SECTOR_SIZE 0x1000U /* 4KB */ +#define NOR_START_PAGE ((NOR_START_SECTOR * NOR_SECTOR_SIZE) / NOR_PAGE_SIZE) +#define NOR_STORAGE_ADDR (IMXRT_FLEX2CIPHER_BASE + NOR_START_SECTOR * NOR_SECTOR_SIZE) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -58,12 +59,79 @@ enum { READ_FAST = 0, READ_STATUS_REG = 1, WRITE_STATUS_REG = 3, + WRITE_ENABLE = 4, SECTOR_ERASE_4K = 5, - SECTOR_ERASE_64K = 8, + READ_FAST_QUAD_OUTPUT = 6, + PAGE_PROGRAM_QUAD_INPUT = 7, PAGE_PROGRAM = 9, CHIP_ERASE = 11, }; +static const uint32_t g_flexspi_nor_lut[][4] = { + [READ_FAST] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0xeb, + FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x06, + FLEXSPI_COMMAND_READ_SDR, FLEXSPI_4PAD, 0x04), + }, + + [READ_STATUS_REG] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x05, + FLEXSPI_COMMAND_READ_SDR, FLEXSPI_1PAD, 0x04), + }, + + [WRITE_STATUS_REG] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x01, + FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04), + }, + + [WRITE_ENABLE] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x06, + FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), + }, + + [SECTOR_ERASE_4K] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x20, + FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), + }, + + [CHIP_ERASE] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0xc7, + FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), + }, + + [PAGE_PROGRAM] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x02, + FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04, + FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0x0), + }, + + [READ_FAST_QUAD_OUTPUT] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x6b, + FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x08, + FLEXSPI_COMMAND_READ_SDR, FLEXSPI_4PAD, 0x04), + }, + + [PAGE_PROGRAM_QUAD_INPUT] = + { + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x32, + FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_4PAD, 0x04, + FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), + }, + +}; + /**************************************************************************** * Private Types ****************************************************************************/ @@ -141,7 +209,7 @@ static struct imxrt_flexspi_storage_dev_s g_flexspi_nor = { .name = "imxrt_flexspi_storage" }, .flexspi = (void *)0, - .ahb_base = (uint8_t *) IMXRT_FLEX2CIPHER_BASE, + .ahb_base = (uint8_t *) NOR_STORAGE_ADDR, .port = FLEXSPI_PORT_A1, .config = &g_flexspi_device_config }; @@ -205,7 +273,6 @@ static int imxrt_flexspi_nor_write_status( static int imxrt_flexspi_storage_write_enable( const struct imxrt_flexspi_storage_dev_s *dev) { -#if 0 int stat; struct flexspi_transfer_s transfer = { @@ -224,7 +291,6 @@ static int imxrt_flexspi_storage_write_enable( return -EIO; } -#endif return 0; } @@ -293,7 +359,7 @@ static int imxrt_flexspi_storage_page_program( .port = dev->port, .cmd_type = FLEXSPI_WRITE, .seq_number = 1, - .seq_index = PAGE_PROGRAM, + .seq_index = PAGE_PROGRAM_QUAD_INPUT, .data = (uint32_t *) buffer, .data_size = len, }; @@ -412,7 +478,7 @@ static ssize_t imxrt_flexspi_storage_bwrite(struct mtd_dev_s *dev, struct imxrt_flexspi_storage_dev_s *priv = (struct imxrt_flexspi_storage_dev_s *)dev; size_t len = nblocks * NOR_PAGE_SIZE; - off_t offset = startblock * NOR_PAGE_SIZE; + off_t offset = (startblock + NOR_START_PAGE) * NOR_PAGE_SIZE; uint8_t *src = (uint8_t *) buffer; #ifdef CONFIG_ARMV7M_DCACHE uint8_t *dst = priv->ahb_base + startblock * NOR_PAGE_SIZE; @@ -421,16 +487,24 @@ static ssize_t imxrt_flexspi_storage_bwrite(struct mtd_dev_s *dev, finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, false); + + irqstate_t flags = enter_critical_section(); + while (len) { i = MIN(NOR_PAGE_SIZE, len); imxrt_flexspi_storage_write_enable(priv); imxrt_flexspi_storage_page_program(priv, offset, src, i); imxrt_flexspi_storage_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); offset += i; + src += i; len -= i; } + FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, true); + + leave_critical_section(flags); + #ifdef CONFIG_ARMV7M_DCACHE up_invalidate_dcache((uintptr_t)dst, (uintptr_t)dst + nblocks * NOR_PAGE_SIZE); @@ -450,18 +524,27 @@ static int imxrt_flexspi_storage_erase(struct mtd_dev_s *dev, uint8_t *dst = priv->ahb_base + startblock * NOR_SECTOR_SIZE; #endif + startblock += NOR_START_SECTOR; + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, false); + + irqstate_t flags = enter_critical_section(); + while (blocksleft-- > 0) { /* Erase each sector */ imxrt_flexspi_storage_write_enable(priv); imxrt_flexspi_storage_erase_sector(priv, startblock * NOR_SECTOR_SIZE); imxrt_flexspi_storage_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); startblock++; } + FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, true); + + leave_critical_section(flags); + #ifdef CONFIG_ARMV7M_DCACHE up_invalidate_dcache((uintptr_t)dst, (uintptr_t)dst + nblocks * NOR_SECTOR_SIZE); @@ -515,7 +598,7 @@ static int imxrt_flexspi_storage_ioctl(struct mtd_dev_s *dev, if (info != NULL) { info->numsectors = (NOR_USED_SECTORS * NOR_SECTOR_SIZE) / NOR_PAGE_SIZE; info->sectorsize = NOR_PAGE_SIZE; - info->startsector = NOR_START_SECTOR; + info->startsector = 0; info->parent[0] = '\0'; ret = OK; } @@ -528,7 +611,6 @@ static int imxrt_flexspi_storage_ioctl(struct mtd_dev_s *dev, imxrt_flexspi_storage_write_enable(priv); imxrt_flexspi_storage_erase_chip(priv); imxrt_flexspi_storage_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); ret = OK; } break; @@ -585,6 +667,11 @@ int imxrt_flexspi_storage_initialize(void) ret = OK; } + FLEXSPI_UPDATE_LUT(g_flexspi_nor.flexspi, + 0, + (const uint32_t *)g_flexspi_nor_lut, + sizeof(g_flexspi_nor_lut) / 4); + /* Register the MTD driver so that it can be accessed from the * VFS. */ @@ -600,7 +687,7 @@ int imxrt_flexspi_storage_initialize(void) /* Mount the LittleFS file system */ - ret = nx_mount("/dev/nor", "/mnt/lfs", "littlefs", 0, + ret = nx_mount("/dev/nor", "/fs/nor", "littlefs", 0, "autoformat"); if (ret < 0) {