From 9d5b13cd0e0ed61c651d7d98811260777de2fcd7 Mon Sep 17 00:00:00 2001 From: Abdelatif Guettouche Date: Thu, 3 Mar 2022 10:21:31 +0100 Subject: [PATCH] xtensa/esp32s3: Add SPI-Flash support. Signed-off-by: Abdelatif Guettouche --- arch/xtensa/src/esp32s3/Kconfig | 34 + arch/xtensa/src/esp32s3/Make.defs | 8 + arch/xtensa/src/esp32s3/esp32s3_spiflash.c | 151 +++ arch/xtensa/src/esp32s3/esp32s3_spiflash.h | 68 ++ .../xtensa/src/esp32s3/esp32s3_spiflash_mtd.c | 577 ++++++++++ .../xtensa/src/esp32s3/esp32s3_spiflash_mtd.h | 91 ++ .../xtensa/src/esp32s3/rom/esp32s3_spiflash.h | 1020 +++++++++++++++++ boards/xtensa/esp32s3/common/src/Make.defs | 4 + .../common/src/esp32s3_board_spiflash.c | 354 ++++++ boards/xtensa/esp32s3/esp32s3-devkit/Kconfig | 43 + .../esp32s3-devkit/configs/spiflash/defconfig | 50 + .../esp32s3-devkit/src/esp32s3-devkit.h | 12 + .../esp32s3-devkit/src/esp32s3_bringup.c | 8 + 13 files changed, 2420 insertions(+) create mode 100644 arch/xtensa/src/esp32s3/esp32s3_spiflash.c create mode 100644 arch/xtensa/src/esp32s3/esp32s3_spiflash.h create mode 100644 arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.c create mode 100644 arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.h create mode 100644 arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h create mode 100644 boards/xtensa/esp32s3/common/src/esp32s3_board_spiflash.c create mode 100644 boards/xtensa/esp32s3/esp32s3-devkit/configs/spiflash/defconfig diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 3bcabf0d37..8334464bc2 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -496,6 +496,40 @@ config ESP32S3_TICKLESS select ARCH_HAVE_TICKLESS select SCHED_TICKLESS +config ESP32S3_SPIFLASH + bool "SPI Flash MTD Partition" + default n + +menu "SPI Flash configuration" + depends on ESP32S3_SPIFLASH + +comment "General storage MTD configuration" + +config ESP32S3_MTD + bool "MTD driver" + default y + select MTD + select MTD_BYTE_WRITE + select MTD_PARTITION + ---help--- + Initialize an MTD driver for the ESP32-S3 SPI Flash, which will + add an entry at /dev for application access from userspace. + +config ESP32S3_SPIFLASH_MTD_BLKSIZE + int "Storage MTD block size" + default 256 + depends on ESP32S3_MTD + +config ESP32S3_STORAGE_MTD_DEBUG + bool "Storage MTD Debug" + default n + depends on ESP32S3_MTD && DEBUG_FS_INFO + ---help--- + If this option is enabled, Storage MTD driver read and write functions + will output input parameters and return values (if applicable). + +endmenu # SPI Flash configuration + menu "Application Image Configuration" choice diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index 202ac2e953..25de0f6d69 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -100,3 +100,11 @@ endif ifeq ($(CONFIG_ESP32S3_FREERUN),y) CHIP_CSRCS += esp32s3_freerun.c endif + +ifeq ($(CONFIG_ESP32S3_SPIFLASH),y) +CHIP_CSRCS += esp32s3_spiflash.c +ifeq ($(CONFIG_ESP32S3_MTD),y) +CHIP_CSRCS += esp32s3_spiflash_mtd.c +endif +endif + diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c new file mode 100644 index 0000000000..5378beee59 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_spiflash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "hardware/esp32s3_soc.h" + +#include "esp32s3_irq.h" + +#include "esp32s3_spiflash.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Structure holding SPI flash access critical sections management + * functions. + */ + +struct spiflash_guard_funcs_s +{ + void (*start)(void); /* critical section start function */ + void (*end)(void); /* critical section end function */ + void (*op_lock)(void); /* flash access API lock function */ + void (*op_unlock)(void); /* flash access API unlock function */ + + /* checks flash write addresses */ + + bool (*address_is_safe)(size_t addr, size_t size); + + void (*yield)(void); /* yield to the OS during flash erase */ +}; + +struct spiflash_cachestate_s +{ + uint32_t value; + irqstate_t flags; +}; + +/**************************************************************************** + * Private Functions Declaration + ****************************************************************************/ + +static void spiflash_start(void); +static void spiflash_end(void); + +/**************************************************************************** + * Public Functions Declaration + ****************************************************************************/ + +extern void spi_flash_guard_set(const struct spiflash_guard_funcs_s *funcs); +extern uint32_t cache_suspend_icache(void); +extern void cache_resume_icache(uint32_t val); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct spiflash_guard_funcs_s g_spi_flash_guard_funcs = +{ + .start = spiflash_start, + .end = spiflash_end, + .op_lock = NULL, + .op_unlock = NULL, + .address_is_safe = NULL, + .yield = NULL, +}; + +struct spiflash_cachestate_s g_state; + +/**************************************************************************** + * Name: spiflash_opstart + * + * Description: + * Prepare for an SPIFLASH operation. + * + ****************************************************************************/ + +static IRAM_ATTR void spiflash_start(void) +{ + g_state.flags = enter_critical_section(); + g_state.value = cache_suspend_icache() << 16; +} + +/**************************************************************************** + * Name: spiflash_opdone + * + * Description: + * Undo all the steps of opstart. + * + ****************************************************************************/ + +static IRAM_ATTR void spiflash_end(void) +{ + cache_resume_icache(g_state.value >> 16); + leave_critical_section(g_state.flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_spiflash_init + * + * Description: + * Initialize ESP32-S3 SPI flash driver. + * + * Returned Value: + * OK if success or a negative value if fail. + * + ****************************************************************************/ + +int esp32s3_spiflash_init(void) +{ + spi_flash_guard_set(&g_spi_flash_guard_funcs); + + return OK; +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.h b/arch/xtensa/src/esp32s3/esp32s3_spiflash.h new file mode 100644 index 0000000000..b2eb6a8c29 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_spiflash.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPIFLASH_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPIFLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_spiflash_init + * + * Description: + * Initialize ESP32-S3 SPI flash driver. + * + * Returned Value: + * OK if success or a negative value if fail. + * + ****************************************************************************/ + +int esp32s3_spiflash_init(void); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPIFLASH_H */ diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.c b/arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.c new file mode 100644 index 0000000000..862befcf31 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.c @@ -0,0 +1,577 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hardware/esp32s3_soc.h" + +#include "xtensa_attr.h" +#include "esp32s3_spiflash.h" + +#include "rom/esp32s3_spiflash.h" +#include "esp32s3_spiflash_mtd.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MTD_BLK_SIZE CONFIG_ESP32S3_SPIFLASH_MTD_BLKSIZE +#define MTD_ERASE_SIZE 4096 +#define MTD_ERASED_STATE (0xff) + +#define MTD2PRIV(_dev) ((struct esp32s3_mtd_dev_s *)_dev) +#define MTD_SIZE(_priv) ((*(_priv)->data)->chip.chip_size) +#define MTD_BLK2SIZE(_priv, _b) (MTD_BLK_SIZE * (_b)) +#define MTD_SIZE2BLK(_priv, _s) ((_s) / MTD_BLK_SIZE) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* ESP32-S3 SPI Flash device private data */ + +struct esp32s3_mtd_dev_s +{ + struct mtd_dev_s mtd; + + /* SPI Flash data */ + + const struct spiflash_legacy_data_s **data; +}; + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +/* MTD driver methods */ + +static int esp32s3_erase(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t esp32s3_read(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, uint8_t *buffer); +static ssize_t esp32s3_bread(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, uint8_t *buffer); +static ssize_t esp32s3_write(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, const uint8_t *buffer); +static ssize_t esp32s3_bwrite(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, const uint8_t *buffer); +static int esp32s3_ioctl(struct mtd_dev_s *dev, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct esp32s3_mtd_dev_s g_esp32s3_spiflash = +{ + .mtd = + { + .erase = esp32s3_erase, + .bread = esp32s3_bread, + .bwrite = esp32s3_bwrite, + .read = esp32s3_read, + .ioctl = esp32s3_ioctl, +#ifdef CONFIG_MTD_BYTE_WRITE + .write = esp32s3_write, +#endif + .name = "esp32s3_spiflash" + }, + .data = &rom_spiflash_legacy_data, +}; + +/* Ensure exclusive access to the driver */ + +static sem_t g_exclsem = SEM_INITIALIZER(1); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_erase + * + * Description: + * Erase SPI Flash designated sectors. + * + * Input Parameters: + * dev - MTD device data + * startblock - start block number, it is not equal to SPI Flash's block + * nblocks - Number of blocks + * + * Returned Value: + * Erased blocks if success or a negative value if fail. + * + ****************************************************************************/ + +static int esp32s3_erase(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks) +{ + ssize_t ret; + uint32_t offset = startblock * MTD_ERASE_SIZE; + uint32_t nbytes = nblocks * MTD_ERASE_SIZE; + struct esp32s3_mtd_dev_s *priv = (struct esp32s3_mtd_dev_s *)dev; + + if ((offset > MTD_SIZE(priv)) || ((offset + nbytes) > MTD_SIZE(priv))) + { + return -EINVAL; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d)\n", __func__, dev, startblock, nblocks); + + finfo("spi_flash_erase_range(0x%x, %d)\n", offset, nbytes); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_erase_range(offset, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + else + { +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("Failed to erase the flash range!\n"); +#endif + ret = -1; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32s3_read + * + * Description: + * Read data from SPI Flash at designated address. + * + * Input Parameters: + * dev - MTD device data + * offset - target address offset + * nbytes - data number + * buffer - data buffer pointer + * + * Returned Value: + * Read data bytes if success or a negative value if fail. + * + ****************************************************************************/ + +static ssize_t esp32s3_read(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, uint8_t *buffer) +{ + ssize_t ret; + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); + + finfo("spi_flash_read(0x%x, %p, %d)\n", offset, buffer, nbytes); +#endif + + /* Acquire the semaphore. */ + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + goto error_with_buffer; + } + + ret = spi_flash_read(offset, buffer, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nbytes; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + +error_with_buffer: + + return ret; +} + +/**************************************************************************** + * Name: esp32s3_bread + * + * Description: + * Read data from designated blocks. + * + * Input Parameters: + * dev - MTD device data + * startblock - start block number, it is not equal to SPI Flash's block + * nblocks - blocks number + * buffer - data buffer pointer + * + * Returned Value: + * Read block number if success or a negative value if fail. + * + ****************************************************************************/ + +static ssize_t esp32s3_bread(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, uint8_t *buffer) +{ + ssize_t ret; + uint32_t addr = startblock * MTD_BLK_SIZE; + uint32_t size = nblocks * MTD_BLK_SIZE; + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks, + buffer); + + finfo("spi_flash_read(0x%x, %p, %d)\n", addr, buffer, size); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_read(addr, buffer, size); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32s3_write + * + * Description: + * write data to SPI Flash at designated address. + * + * Input Parameters: + * dev - MTD device data + * offset - target address offset + * nbytes - data number + * buffer - data buffer pointer + * + * Returned Value: + * Writen bytes if success or a negative value if fail. + * + ****************************************************************************/ + +static ssize_t esp32s3_write(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, const uint8_t *buffer) +{ + int ret; + struct esp32s3_mtd_dev_s *priv = (struct esp32s3_mtd_dev_s *)dev; + + ASSERT(buffer); + + if ((offset > MTD_SIZE(priv)) || ((offset + nbytes) > MTD_SIZE(priv))) + { + return -EINVAL; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); + + finfo("spi_flash_write(0x%x, %p, %d)\n", offset, buffer, nbytes); +#endif + + /* Acquire the semaphore. */ + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + goto error_with_buffer; + } + + ret = spi_flash_write(offset, buffer, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nbytes; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + +error_with_buffer: + + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: esp32s3_bwrite + * + * Description: + * Write data to designated blocks. + * + * Input Parameters: + * dev - MTD device data + * startblock - start MTD block number, + * it is not equal to SPI Flash's block + * nblocks - blocks number + * buffer - data buffer pointer + * + * Returned Value: + * Writen block number if success or a negative value if fail. + * + ****************************************************************************/ + +static ssize_t esp32s3_bwrite(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, const uint8_t *buffer) +{ + ssize_t ret; + uint32_t addr = startblock * MTD_BLK_SIZE; + uint32_t size = nblocks * MTD_BLK_SIZE; + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, + nblocks, buffer); + + finfo("spi_flash_write(0x%x, %p, %d)\n", addr, buffer, size); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_write(addr, buffer, size); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + +#ifdef CONFIG_ESP32S3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32s3_ioctl + * + * Description: + * Set/Get option to/from ESP32-S3 SPI Flash MTD device data. + * + * Input Parameters: + * dev - ESP32-S3 MTD device data + * cmd - operation command + * arg - operation argument + * + * Returned Value: + * 0 if success or a negative value if fail. + * + ****************************************************************************/ + +static int esp32s3_ioctl(struct mtd_dev_s *dev, int cmd, + unsigned long arg) +{ + int ret = OK; + finfo("cmd: %d\n", cmd); + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + struct esp32s3_mtd_dev_s *priv = (struct esp32s3_mtd_dev_s *)dev; + struct mtd_geometry_s *geo = (struct mtd_geometry_s *)arg; + if (geo) + { + geo->blocksize = MTD_BLK_SIZE; + geo->erasesize = MTD_ERASE_SIZE; + geo->neraseblocks = MTD_SIZE(priv) / MTD_ERASE_SIZE; + ret = OK; + + finfo("blocksize: %" PRId32 " erasesize: %" PRId32 \ + " neraseblocks: %" PRId32 "\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + } + break; + + case BIOC_PARTINFO: + { + struct esp32s3_mtd_dev_s *priv = (struct esp32s3_mtd_dev_s *)dev; + struct partition_info_s *info = (struct partition_info_s *)arg; + if (info != NULL) + { + info->numsectors = MTD_SIZE(priv) / MTD_BLK_SIZE; + info->sectorsize = MTD_BLK_SIZE; + info->startsector = 0; + info->parent[0] = '\0'; + } + } + break; + + case MTDIOC_ERASESTATE: + { + uint8_t *result = (uint8_t *)arg; + *result = MTD_ERASED_STATE; + + ret = OK; + } + break; + + default: + ret = -ENOTTY; + break; + } + + finfo("return %d\n", ret); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_spiflash_alloc_mtdpart + * + * Description: + * Allocate an MTD partition from the ESP32-S3 SPI Flash. + * + * Input Parameters: + * mtd_offset - MTD Partition offset from the base address in SPI Flash. + * mtd_size - Size for the MTD partition. + * + * Returned Value: + * ESP32-S3 SPI Flash MTD data pointer if success or NULL if fail. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32s3_spiflash_alloc_mtdpart(uint32_t mtd_offset, + uint32_t mtd_size) +{ + const struct esp32s3_mtd_dev_s *priv; + const esp32s3_spiflash_chip_t *chip; + struct mtd_dev_s *mtd_part; + uint32_t blocks; + uint32_t startblock; + uint32_t size; + + priv = &g_esp32s3_spiflash; + + chip = &(*priv->data)->chip; + + finfo("ESP32-S3 SPI Flash information:\n"); + finfo("\tID = 0x%" PRIx32 "\n", chip->device_id); + finfo("\tStatus mask = 0x%" PRIx32 "\n", chip->status_mask); + finfo("\tChip size = %" PRId32 " KB\n", chip->chip_size / 1024); + finfo("\tPage size = %" PRId32 " B\n", chip->page_size); + finfo("\tSector size = %" PRId32 " KB\n", chip->sector_size / 1024); + finfo("\tBlock size = %" PRId32 " KB\n", chip->block_size / 1024); + + ASSERT((mtd_offset + mtd_size) <= chip->chip_size); + ASSERT((mtd_offset % chip->sector_size) == 0); + ASSERT((mtd_size % chip->sector_size) == 0); + + if (mtd_size == 0) + { + size = chip->chip_size - mtd_offset; + } + else + { + size = mtd_size; + } + + finfo("\tMTD offset = 0x%" PRIx32 "\n", mtd_offset); + finfo("\tMTD size = 0x%" PRIx32 "\n", size); + + startblock = MTD_SIZE2BLK(priv, mtd_offset); + blocks = MTD_SIZE2BLK(priv, size); + + mtd_part = mtd_partition((struct mtd_dev_s *)&priv->mtd, startblock, + blocks); + if (!mtd_part) + { + ferr("ERROR: Failed to create MTD partition\n"); + return NULL; + } + + return mtd_part; +} + +/**************************************************************************** + * Name: esp32s3_spiflash_mtd + * + * Description: + * Get SPI Flash MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * ESP32-S3 SPI Flash MTD pointer. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32s3_spiflash_mtd(void) +{ + struct esp32s3_mtd_dev_s *priv = + (struct esp32s3_mtd_dev_s *)&g_esp32s3_spiflash; + + return &priv->mtd; +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.h b/arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.h new file mode 100644 index 0000000000..2742c9cdc6 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_spiflash_mtd.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPIFLASH_MTD_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPIFLASH_MTD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_spiflash_mtd + * + * Description: + * Get SPI Flash MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * ESP32-S3 SPI Flash MTD pointer. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32s3_spiflash_mtd(void); + +/**************************************************************************** + * Name: esp32s3_spiflash_alloc_mtdpart + * + * Description: + * Allocate an MTD partition from the ESP32-S3 SPI Flash. + * + * Input Parameters: + * mtd_offset - MTD Partition offset from the base address in SPI Flash. + * mtd_size - Size for the MTD partition. + * encrypted - Flag indicating whether the newly allocated partition will + * have its content encrypted. + * + * Returned Value: + * SPI Flash MTD data pointer if success or NULL if fail. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32s3_spiflash_alloc_mtdpart(uint32_t mtd_offset, + uint32_t mtd_size); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_SPIFLASH_MTD_H */ diff --git a/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h b/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h new file mode 100644 index 0000000000..77ddde1f4e --- /dev/null +++ b/arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h @@ -0,0 +1,1020 @@ +/***************************************************************************** + * arch/xtensa/src/esp32s3/rom/esp32s3_spiflash.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + *****************************************************************************/ + +#ifndef _ROM_SPI_FLASH_H_ +#define _ROM_SPI_FLASH_H_ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +#define PERIPHS_SPI_FLASH_CMD SPI_CMD_REG(1) +#define PERIPHS_SPI_FLASH_ADDR SPI_ADDR_REG(1) +#define PERIPHS_SPI_FLASH_CTRL SPI_CTRL_REG(1) +#define PERIPHS_SPI_FLASH_CTRL1 SPI_CTRL1_REG(1) +#define PERIPHS_SPI_FLASH_STATUS SPI_RD_STATUS_REG(1) +#define PERIPHS_SPI_FLASH_USRREG SPI_USER_REG(1) +#define PERIPHS_SPI_FLASH_USRREG1 SPI_USER1_REG(1) +#define PERIPHS_SPI_FLASH_USRREG2 SPI_USER2_REG(1) +#define PERIPHS_SPI_FLASH_C0 SPI_W0_REG(1) +#define PERIPHS_SPI_FLASH_C1 SPI_W1_REG(1) +#define PERIPHS_SPI_FLASH_C2 SPI_W2_REG(1) +#define PERIPHS_SPI_FLASH_C3 SPI_W3_REG(1) +#define PERIPHS_SPI_FLASH_C4 SPI_W4_REG(1) +#define PERIPHS_SPI_FLASH_C5 SPI_W5_REG(1) +#define PERIPHS_SPI_FLASH_C6 SPI_W6_REG(1) +#define PERIPHS_SPI_FLASH_C7 SPI_W7_REG(1) +#define PERIPHS_SPI_FLASH_TX_CRC SPI_TX_CRC_REG(1) + +#define SPI0_R_QIO_DUMMY_CYCLELEN 3 +#define SPI0_R_QIO_ADDR_BITSLEN 31 +#define SPI0_R_FAST_DUMMY_CYCLELEN 7 +#define SPI0_R_DIO_DUMMY_CYCLELEN 1 +#define SPI0_R_DIO_ADDR_BITSLEN 27 +#define SPI0_R_FAST_ADDR_BITSLEN 23 +#define SPI0_R_SIO_ADDR_BITSLEN 23 + +#define SPI1_R_QIO_DUMMY_CYCLELEN 3 +#define SPI1_R_QIO_ADDR_BITSLEN 31 +#define SPI1_R_FAST_DUMMY_CYCLELEN 7 +#define SPI1_R_DIO_DUMMY_CYCLELEN 3 +#define SPI1_R_DIO_ADDR_BITSLEN 31 +#define SPI1_R_FAST_ADDR_BITSLEN 23 +#define SPI1_R_SIO_ADDR_BITSLEN 23 + +#define ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN 23 + +#define ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN SPI_WRSR_2B + +/* SPI address register */ + +#define ESP_ROM_SPIFLASH_BYTES_LEN 24 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM 32 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM 64 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_BITS 0x3f + +/* SPI status register */ + +#define ESP_ROM_SPIFLASH_BUSY_FLAG BIT0 +#define ESP_ROM_SPIFLASH_WRENABLE_FLAG BIT1 +#define ESP_ROM_SPIFLASH_BP0 BIT2 +#define ESP_ROM_SPIFLASH_BP1 BIT3 +#define ESP_ROM_SPIFLASH_BP2 BIT4 +#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|\ + ESP_ROM_SPIFLASH_BP1|\ + ESP_ROM_SPIFLASH_BP2) +#define ESP_ROM_SPIFLASH_QE BIT9 + +/* Extra dummy for flash read */ + +#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M 0 +#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M 1 +#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M 2 + +#define FLASH_ID_GD25LQ32C 0xC86016 + +/***************************************************************************** + * Public Types + *****************************************************************************/ + +typedef enum +{ + ESP_ROM_SPIFLASH_QIO_MODE = 0, + ESP_ROM_SPIFLASH_QOUT_MODE, + ESP_ROM_SPIFLASH_DIO_MODE, + ESP_ROM_SPIFLASH_DOUT_MODE, + ESP_ROM_SPIFLASH_FASTRD_MODE, + ESP_ROM_SPIFLASH_SLOWRD_MODE +} esp_rom_spiflash_read_mode_t; + +typedef enum +{ + ESP_ROM_SPIFLASH_RESULT_OK, + ESP_ROM_SPIFLASH_RESULT_ERR, + ESP_ROM_SPIFLASH_RESULT_TIMEOUT +} esp_rom_spiflash_result_t; + +typedef struct +{ + uint32_t device_id; + uint32_t chip_size; /* chip size in bytes */ + uint32_t block_size; + uint32_t sector_size; + uint32_t page_size; + uint32_t status_mask; +} esp32s3_spiflash_chip_t; + +typedef struct +{ + uint8_t data_length; + uint8_t read_cmd0; + uint8_t read_cmd1; + uint8_t write_cmd; + uint16_t data_mask; + uint16_t data; +} esp_rom_spiflash_common_cmd_t; + +/** + * Global ROM spiflash data, as used by legacy SPI flash functions + */ + +struct spiflash_legacy_data_s +{ + esp32s3_spiflash_chip_t chip; + uint8_t dummy_len_plus[3]; + uint8_t sig_matrix; +}; + +/** + * Structure holding SPI flash access critical sections management functions. + * + * Flash API uses two types of functions for flash access management: + * 1) Functions which prepare/restore flash cache and interrupts before + * calling appropriate ROM functions (SPIWrite, SPIRead and + * SPIEraseBlock): + * - 'start' function should disable flash cache and non-IRAM interrupts + * and is invoked before the call to one of ROM functions from + * "struct spiflash_guard_funcs_s". + * - 'end' function should restore state of flash cache and non-IRAM + * interrupts and is invoked after the call to one of ROM + * functions from "struct spiflash_guard_funcs_s". + * These two functions are not reentrant. + * 2) Functions which synchronizes access to internal data used by flash API. + * These functions are mostly intended to synchronize access to flash API + * internal data in multithreaded environment and use OS primitives: + * - 'op_lock' locks access to flash API internal data. + * - 'op_unlock' unlocks access to flash API internal data. + * These two functions are reentrant and can be used around the outside of + * multiple calls to 'start' & 'end', in order to create atomic multi-part + * flash operations. + * + * Different versions of the guarding functions should be used depending on + * the context of execution (with or without functional OS). In normal + * conditions when flash API is called from task the functions use OS + * primitives. + * When there is no OS at all or when it is not guaranteed that OS is + * functional (accessing flash from exception handler) these functions cannot + * use OS primitives or even does not need them (multithreaded access is + * not possible). + * + * @note Structure and corresponding guard functions should not reside + * in flash. For example structure can be placed in DRAM and functions + * in IRAM sections. + */ + +struct spiflash_guard_funcs +{ + void (*start)(void); /* critical section start function */ + void (*end)(void); /* critical section end function */ + void (*op_lock)(void); /* flash access API lock function */ + void (*op_unlock)(void); /* flash access API unlock function */ + + /* checks flash write addresses */ + + bool (*address_is_safe)(size_t addr, size_t size); + + void (*yield)(void); /* yield to the OS during flash erase */ +}; + +/***************************************************************************** + * Public Function Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Name: esp_rom_spiflash_fix_dummylen + * + * Description: + * Fix the bug in SPI hardware communication with Flash/Ext-SRAM in High + * Speed. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint8_t spi: 0 for SPI0(Cache Access), 1 for SPI1(Flash read/write). + * + * uint8_t freqdiv: Pll is 80M, 4 for 20M, 3 for 26.7M, 2 for 40M, + * 1 for 80M. + * + * Returned Value: + * None + * + *****************************************************************************/ + +void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); + +/***************************************************************************** + * Name: esp_rom_spiflash_select_qiomode + * + * Description: + * Select SPI Flash to QIO mode when WP pad is read from Flash. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint8_t wp_gpio_num: WP gpio number. + * + * uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, + * bit[23:18] spics0, bit[29:24] spihd + * + * Returned Value: + * None + *****************************************************************************/ + +void esp_rom_spiflash_select_qiomode(uint8_t wp_gpio_num, + uint32_t ishspi); + +/***************************************************************************** + * Name: esp_rom_spiflash_set_drvs + * + * Description: + * Set SPI Flash pad drivers. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint8_t wp_gpio_num: WP gpio number. + * + * uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, + * bit[23:18] spics0, bit[29:24] spihd + * + * uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, + * drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid + * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. + * Values usually read from flash by rom code, function + * usually callde by rom code. + * if value with bit(3) set, the value is valid, bit[2:0] + * is the real value. + * + * Returned Value: + * None + * + *****************************************************************************/ + +void esp_rom_spiflash_set_drvs(uint8_t wp_gpio_num, + uint32_t ishspi, + uint8_t *drvs); + +/***************************************************************************** + * Name: esp_rom_spiflash_select_padsfunc + * + * Description: + * Select SPI Flash function for pads. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, + * bit[23:18] spics0, bit[29:24] spihd + * + * Returned Value: + * None + * + *****************************************************************************/ + +void esp_rom_spiflash_select_padsfunc(uint32_t ishspi); + +/***************************************************************************** + * Name: esp_rom_spiflash_attach + * + * Description: + * SPI Flash init, clock divisor is 4, use 1 line Slow read mode. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, + * bit[23:18] spics0, bit[29:24] spihd + * + * uint8_t legacy: In legacy mode, more SPI command is used in line. + * + * Returned Value: + * None + * + *****************************************************************************/ + +void esp_rom_spiflash_attach(uint32_t ishspi, bool legacy); + +/***************************************************************************** + * Name: esp_rom_spiflash_read_status + * + * Description: + * SPI Read Flash status register. We use CMD 0x05 (RDSR). + * + * Please do not call this function in SDK. + * + * Input Parameters: + * esp32s3_spiflash_chip_t *spi : The information for Flash, which is + * exported from ld file. + * + * uint32_t *status : The pointer to which to return the Flash status value. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_read_status(esp32s3_spiflash_chip_t *spi, + uint32_t *status); + +/***************************************************************************** + * Name: esp32s3_spiflash_read_statushigh + * + * Description: + * SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2). + * + * Please do not call this function in SDK. + * + * Input Parameters: + * esp32s3_spiflash_chip_t *spi : The information for Flash, which is + * exported from ld file. + * + * uint32_t *status : The pointer to which to return the Flash status value. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp32s3_spiflash_read_statushigh(esp32s3_spiflash_chip_t *spi, + uint32_t *status); + +/***************************************************************************** + * Name: esp32s3_spiflash_write_status + * + * Description: + * Write status to Falsh status register. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * esp32s3_spiflash_chip_t *spi : The information for Flash, which is + * exported from ld file. + * + * uint32_t status_value : Value to . + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : write OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : write timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp32s3_spiflash_write_status(esp32s3_spiflash_chip_t *spi, + uint32_t status_value); + +/***************************************************************************** + * Name: esp_rom_spiflash_read_user_cmd + * + * Description: + * Use a command to Read Flash status register. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * esp32s3_spiflash_chip_t *spi : The information for Flash, which is + * exported from ld file. + * + * uint32_t*status : The pointer to which to return the Flash status value. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_read_user_cmd(uint32_t *status, + uint8_t cmd); + +/***************************************************************************** + * Name: esp_rom_spiflash_config_readmode + * + * Description: + * Config SPI Flash read mode when init. + * + * Please do not call this function in SDK. + * + * Input Parameter: + * esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD. + * + * This function does not try to set the QIO Enable bit in the status + * register, caller is responsible for this. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : config OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : config error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode); + +/***************************************************************************** + * Name: esp_rom_spiflash_config_clk + * + * Description: + * Config SPI Flash clock divisor. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint8_t freqdiv: clock divisor. + * + * uint8_t spi: 0 for SPI0, 1 for SPI1. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : config OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : config error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_config_clk(uint8_t freqdiv, + uint8_t spi); + +/***************************************************************************** + * Name: esp_rom_spiflash_common_cmd + * + * Description: + * Send CommonCmd to Flash so that is can go into QIO mode, some Flash use + * different CMD. + * + * Please do not call this function in SDK. + * + * Input Paramater: + * esp_rom_spiflash_common_cmd_t *cmd : A struct to show the action of a + * command. + * + * Returned Value: + * uint16_t 0 : do not send command any more. + * 1 : go to the next command. + * n > 1 : skip (n - 1) commands. + * + *****************************************************************************/ + +uint16_t esp_rom_spiflash_common_cmd(esp_rom_spiflash_common_cmd_t *cmd); + +/***************************************************************************** + * Name: esp_rom_spiflash_unlock + * + * Description: + * Unlock SPI write protect. + * + * Please do not call this function in SDK. + * + * Input Value: + * None. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void); + +/***************************************************************************** + * Name: esp_rom_spiflash_lock + * + * Description: + * SPI write protect. + * + * Please do not call this function in SDK. + * + * Input Parameter: + * None. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Lock OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Lock error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Lock timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t esp_rom_spiflash_lock(void); + +/***************************************************************************** + * Name: esp_rom_spiflash_config_param + * + * Description: + * Update SPI Flash parameter. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t deviceId : Device ID read from SPI, the low 32 bit. + * + * uint32_t chip_size : The Flash size. + * + * uint32_t block_size : The Flash block size. + * + * uint32_t sector_size : The Flash sector size. + * + * uint32_t page_size : The Flash page size. + * + * uint32_t status_mask : The Mask used when read status from Flash + * (use single CMD). + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Update OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Update error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Update timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_config_param(uint32_t deviceid, + uint32_t chip_size, + uint32_t block_size, + uint32_t sector_size, + uint32_t page_size, + uint32_t status_mask); + +/***************************************************************************** + * Name: esp_rom_spiflash_erase_chip + * + * Description: + * Erase whole flash chip. + * + * Please do not call this function in SDK. + * + * Input Parameter: + * None + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void); + +/***************************************************************************** + * Name: esp_rom_spiflash_erase_block + * + * Description: + * Erase a 64KB block of flash + * Uses SPI flash command D8H. + * + * Please do not call this function in SDK. + * + * Input Parameter: + * uint32_t block_num : Which block to erase. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num); + +/***************************************************************************** + * Name: esp_rom_spiflash_erase_sector + * + * Description: + * Erase a sector of flash. + * Uses SPI flash command 20H. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t sector_num : Which sector to erase. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num); + +/***************************************************************************** + * Name: esp_rom_spiflash_erase_area + * + * Description: + * Erase some sectors. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t start_addr : Start addr to erase, should be sector aligned. + * + * uint32_t area_len : Length to erase, should be sector aligned. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_erase_area(uint32_t start_addr, + uint32_t area_len); + +/***************************************************************************** + * Name: esp_rom_spiflash_write + * + * Description: + * Write Data to Flash, you should Erase it yourself if need. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t dest_addr : Address to write, should be 4 bytes aligned. + * + * const uint32_t *src : The pointer to data which is to write. + * + * uint32_t len : Length to write, should be 4 bytes aligned. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Write OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Write timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_write(uint32_t dest_addr, + const uint32_t *src, + int32_t len); + +/***************************************************************************** + * Name: esp_rom_spiflash_read + * + * Description: + * Read Data from Flash, you should Erase it yourself if need. + * + * Please do not call this function in SDK. + * + * Input Values: + * uint32_t src_addr : Address to read, should be 4 bytes aligned. + * + * uint32_t *dest : The buf to read the data. + * + * uint32_t len : Length to read, should be 4 bytes aligned. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Read timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_read(uint32_t src_addr, + uint32_t *dest, + int32_t len); + +/***************************************************************************** + * Name: esp_rom_spiflash_write_encrypted_enable + * + * Description: + * SPI1 go into encrypto mode. + * + * Please do not call this function in SDK. + * + *****************************************************************************/ + +void esp_rom_spiflash_write_encrypted_enable(void); + +/***************************************************************************** + * Name: esp_rom_spiflash_prepare_encrypted_data + * + * Description: + * Prepare 32 Bytes data to encrpto writing, you should Erase it yourself + * if need. + * + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t flash_addr : Address to write, should be 32 bytes aligned. + * + * uint32_t *data : The pointer to data which is to write. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Prepare OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Prepare error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Prepare timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_prepare_encrypted_data(uint32_t flash_addr, + uint32_t *data); + +/***************************************************************************** + * Name: esp_rom_spiflash_write_encrypted_disable + * + * Description: + * SPI1 go out of encrypto mode. + * + * Please do not call this function in SDK. + * + *****************************************************************************/ + +void esp_rom_spiflash_write_encrypted_disable(void); + +/***************************************************************************** + * Name: esp_rom_spiflash_write_encrypted + * + * Description: + * Write data to flash with transparent encryption. + * Sectors to be written should already be erased. + * Please do not call this function in SDK. + * + * Input Parameters: + * uint32_t flash_addr : Address to write, should be 32 byte aligned. + * + * uint32_t *data : The pointer to data to write. Note, this pointer must + * be 32 bit aligned and the content of the data will be + * modified by the encryption function. + * + * uint32_t len : Length to write, should be 32 bytes aligned. + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Data written successfully. + * ESP_ROM_SPIFLASH_RESULT_ERR : Encryption write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Encrypto write timeout. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t +esp_rom_spiflash_write_encrypted(uint32_t flash_addr, + uint32_t *data, + uint32_t len); + +/***************************************************************************** + * Name: esp_rom_spiflash_wait_idle + * + * Description: + * Wait until SPI flash write operation is complete + * + * Please do not call this function in SDK. + * + * Reads the Write In Progress bit of the SPI flash status register, + * repeats until this bit is zero (indicating write complete). + * + * Returned Value: + * ESP_ROM_SPIFLASH_RESULT_OK : Write is complete + * ESP_ROM_SPIFLASH_RESULT_ERR : Error while reading status. + * + *****************************************************************************/ + +esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp32s3_spiflash_chip_t + *spi); + +/***************************************************************************** + * Name: esp_rom_spiflash_select_qio_pins + * + * Description: + * Enable Quad I/O pin functions + * + * Please do not call this function in SDK. + * + * Sets the HD & WP pin functions for Quad I/O modes, based on the + * efuse SPI pin configuration. + * + * Input Parameters: + * wp_gpio_num - Number of the WP pin to reconfigure for quad I/O. + * spiconfig - Pin configuration, as returned from + * ets_efuse_get_spiconfig(). + * - If this parameter is 0, default SPI pins are used and + * wp_gpio_num parameter is ignored. + * - If this parameter is 1, default HSPI pins are used and + * wp_gpio_num parameter is ignored. + * - For other values, this parameter encodes the HD pin number + * and also the CLK pin number. CLK pin selection is used to + * determine if HSPI or SPI peripheral will be used (use HSPI + * if CLK pin is the HSPI clock pin, otherwise use SPI). + * Both HD & WP pins are configured via GPIO matrix to map to the selected + * peripheral. + * + *****************************************************************************/ + +void esp_rom_spiflash_select_qio_pins(uint8_t wp_gpio_num, + uint32_t spiconfig); + +/***************************************************************************** + * Name: spi_flash_guard_set + * + * Description: + * Sets guard functions to access flash. + * + * Input Parameters: + * funcs - funcs pointer to structure holding flash access guard functions + * + * Returned Value: + * None + * + *****************************************************************************/ + +void spi_flash_guard_set(const struct spiflash_guard_funcs *funcs); + +/***************************************************************************** + * Name: spi_flash_write_encrypted + * + * Description: + * Write data encrypted to Flash. + * + * Flash encryption must be enabled for this function to work. + * + * Flash encryption must be enabled when calling this function. + * If flash encryption is disabled, the function returns + * ESP_ERR_INVALID_STATE. Use esp_flash_encryption_enabled() + * function to determine if flash encryption is enabled. + * + * Both dest_addr and size must be multiples of 16 bytes. For + * absolute best performance, both dest_addr and size arguments should + * be multiples of 32 bytes. + * + * Input Parameters: + * dest_addr - Destination address in Flash. Must be a multiple of 16 + * bytes. + * src - Pointer to the source buffer. + * size - Length of data, in bytes. Must be a multiple of 16 bytes. + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_write_encrypted(uint32_t dest_addr, const void *src, + uint32_t size); + +/***************************************************************************** + * Name: spi_flash_write + * + * Description: + * + * Write data to Flash. + * + * Note: For fastest write performance, write a 4 byte aligned size at a + * 4 byte aligned offset in flash from a source buffer in DRAM. Varying + * any of these parameters will still work, but will be slower due to + * buffering. + * + * Writing more than 8KB at a time will be split into multiple + * write operations to avoid disrupting other tasks in the system. + * + * Parameters: + * dest_addr - Destination address in Flash. + * src - Pointer to the source buffer. + * size - Length of data, in bytes. + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_write(uint32_t dest_addr, const void *src, uint32_t size); + +/***************************************************************************** + * Name: spi_flash_read + * + * Description: + * Read data from Flash. + * + * Note: For fastest read performance, all parameters should be + * 4 byte aligned. If source address and read size are not 4 byte + * aligned, read may be split into multiple flash operations. If + * destination buffer is not 4 byte aligned, a temporary buffer will + * be allocated on the stack. + * + * Reading more than 16KB of data at a time will be split + * into multiple reads to avoid disruption to other tasks in the + * system. Consider using spi_flash_mmap() to read large amounts + * of data. + * + * Parameters: + * src_addr - source address of the data in Flash. + * dest - pointer to the destination buffer + * size - length of data + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_read(uint32_t src_addr, void *dest, uint32_t size); + +/***************************************************************************** + * Name: spi_flash_erase_sector + * + * Description: + * Erase the Flash sector. + * + * Parameters: + * sector - Sector number, the count starts at sector 0, 4KB per sector. + * + * Returned Values: esp_err_t + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_erase_sector(uint32_t sector); + +/***************************************************************************** + * Name: spi_flash_erase_range + * + * Description: + * Erase a range of flash sectors + * + * Parameters: + * start_address - Address where erase operation has to start. + * Must be 4kB-aligned + * size - Size of erased range, in bytes. Must be divisible by + * 4kB. + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_erase_range(uint32_t start_address, uint32_t size); + +/***************************************************************************** + * Name: spi_flash_cache_enabled + * + * Description: + * Check at runtime if flash cache is enabled on both CPUs. + * + * Returned Values: + * Return true if both CPUs have flash cache enabled, false otherwise. + * + *****************************************************************************/ + +bool spi_flash_cache_enabled(void); + +/***************************************************************************** + * Name: spi_flash_enable_cache + * + * Description: + * Re-enable cache for the core defined as cpuid parameter. + * + * Parameters: + * cpuid - core number to enable instruction cache for. + * + *****************************************************************************/ + +void spi_flash_enable_cache(uint32_t cpuid); + +/***************************************************************************** + * Public Data + *****************************************************************************/ + +extern const struct spiflash_legacy_data_s *rom_spiflash_legacy_data; + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_SPI_FLASH_H_ */ diff --git a/boards/xtensa/esp32s3/common/src/Make.defs b/boards/xtensa/esp32s3/common/src/Make.defs index 7069365b02..da97e34c89 100644 --- a/boards/xtensa/esp32s3/common/src/Make.defs +++ b/boards/xtensa/esp32s3/common/src/Make.defs @@ -26,6 +26,10 @@ ifeq ($(CONFIG_WATCHDOG),y) CSRCS += esp32s3_board_wdt.c endif +ifeq ($(CONFIG_ESP32S3_SPIFLASH),y) + CSRCS += esp32s3_board_spiflash.c +endif + DEPPATH += --dep-path src VPATH += :src CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src) diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_board_spiflash.c b/boards/xtensa/esp32s3/common/src/esp32s3_board_spiflash.c new file mode 100644 index 0000000000..230c0d757d --- /dev/null +++ b/boards/xtensa/esp32s3/common/src/esp32s3_board_spiflash.c @@ -0,0 +1,354 @@ +/**************************************************************************** + * boards/xtensa/esp32s3/common/src/esp32s3_board_spiflash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "inttypes.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef CONFIG_BCH +#include +#endif + +#include "esp32s3_spiflash.h" +#include "esp32s3_spiflash_mtd.h" +#include "esp32s3-devkit.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: setup_smartfs + * + * Description: + * Provide a block driver wrapper around MTD partition and mount a + * SMART FS over it. + * + * Parameters: + * smartn - Number used to register the mtd partition: /dev/smartx, where + * x = smartn. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined (CONFIG_ESP32S3_SPIFLASH_SMARTFS) +static int setup_smartfs(int smartn, FAR struct mtd_dev_s *mtd, + const char *mnt_pt) +{ + int ret = OK; + char path[22]; + + ret = smart_initialize(smartn, mtd, NULL); + if (ret < 0) + { + finfo("smart_initialize failed, Trying to erase first...\n"); + ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0); + if (ret < 0) + { + ferr("ERROR: ioctl(BULKERASE) failed: %d\n", ret); + return ret; + } + + finfo("Erase successful, initializing it again.\n"); + ret = smart_initialize(smartn, mtd, NULL); + if (ret < 0) + { + ferr("ERROR: smart_initialize failed: %d\n", ret); + return ret; + } + } + + if (mnt_pt != NULL) + { + snprintf(path, sizeof(path), "/dev/smart%d", smartn); + + ret = nx_mount(path, mnt_pt, "smartfs", 0, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} + +#endif + +/**************************************************************************** + * Name: setup_littlefs + * + * Description: + * Register a mtd driver and mount a Little FS over it. + * + * Parameters: + * path - Path name used to register the mtd driver. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * priv - Privileges + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined (CONFIG_ESP32S3_SPIFLASH_LITTLEFS) +static int setup_littlefs(const char *path, FAR struct mtd_dev_s *mtd, + const char *mnt_pt, int priv) +{ + int ret = OK; + + ret = register_mtddriver(path, mtd, priv, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return ERROR; + } + + if (mnt_pt != NULL) + { + ret = nx_mount(path, mnt_pt, "littlefs", 0, NULL); + if (ret < 0) + { + ret = nx_mount(path, mnt_pt, "littlefs", 0, "forceformat"); + if (ret < 0) + { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: setup_spiffs + * + * Description: + * Register a mtd driver and mount a SPIFFS over it. + * + * Parameters: + * path - Path name used to register the mtd driver. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * priv - Privileges + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined (CONFIG_ESP32S3_SPIFLASH_SPIFFS) +static int setup_spiffs(const char *path, FAR struct mtd_dev_s *mtd, + const char *mnt_pt, int priv) +{ + int ret = OK; + + ret = register_mtddriver(path, mtd, priv, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return ERROR; + } + + if (mnt_pt != NULL) + { + ret = nx_mount(path, mnt_pt, "spiffs", 0, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: setup_nxffs + * + * Description: + * Register a mtd driver and mount a SPIFFS over it. + * + * Parameters: + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined (CONFIG_ESP32S3_SPIFLASH_NXFFS) +static int setup_nxffs(FAR struct mtd_dev_s *mtd, const char *mnt_pt) +{ + int ret = OK; + + ret = nxffs_initialize(mtd); + if (ret < 0) + { + ferr("ERROR: NXFFS init failed: %d\n", ret); + return ret; + } + + if (mnt_pt != NULL) + { + ret = nx_mount(NULL, mnt_pt, "nxffs", 0, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: init_storage_partition + * + * Description: + * Initialize partition that is dedicated to general use. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int init_storage_partition(void) +{ + int ret = OK; + FAR struct mtd_dev_s *mtd; + + mtd = esp32s3_spiflash_alloc_mtdpart(CONFIG_ESP32S3_STORAGE_MTD_OFFSET, + CONFIG_ESP32S3_STORAGE_MTD_SIZE); + if (!mtd) + { + ferr("ERROR: Failed to alloc MTD partition of SPI Flash\n"); + return ERROR; + } + +#if defined (CONFIG_ESP32S3_SPIFLASH_SMARTFS) + + ret = setup_smartfs(0, mtd, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to setup smartfs\n"); + return ret; + } + +#elif defined (CONFIG_ESP32S3_SPIFLASH_NXFFS) + + ret = setup_nxffs(mtd, "/mnt"); + if (ret < 0) + { + ferr("ERROR: Failed to setup nxffs\n"); + return ret; + } + +#elif defined (CONFIG_ESP32S3_SPIFLASH_LITTLEFS) + + const char *path = "/dev/esp32s3flash"; + ret = setup_littlefs(path, mtd, NULL, 0755); + if (ret < 0) + { + ferr("ERROR: Failed to setup littlefs\n"); + return ret; + } + +#elif defined (CONFIG_ESP32S3_SPIFLASH_SPIFFS) + + const char *path = "/dev/esp32s3flash"; + ret = setup_spiffs(path, mtd, NULL, 0755); + if (ret < 0) + { + ferr("ERROR: Failed to setup spiffs\n"); + return ret; + } + +#else + + ret = register_mtddriver("/dev/esp32s3flash", mtd, 0755, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return ret; + } + +#endif + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_spiflash_init + * + * Description: + * Initialize the SPIFLASH and register the MTD device. + * + ****************************************************************************/ + +int board_spiflash_init(void) +{ + int ret = OK; + + ret = esp32s3_spiflash_init(); + if (ret < 0) + { + return ret; + } + + ret = init_storage_partition(); + if (ret < 0) + { + return ret; + } + + return ret; +} + diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/Kconfig b/boards/xtensa/esp32s3/esp32s3-devkit/Kconfig index 24d2ea1144..9c3a0d9c6e 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/Kconfig +++ b/boards/xtensa/esp32s3/esp32s3-devkit/Kconfig @@ -5,4 +5,47 @@ if ARCH_BOARD_ESP32S3_DEVKIT +config ESP32S3_STORAGE_MTD_OFFSET + hex "Storage MTD base address in SPI Flash" + default 0x180000 + depends on ESP32S3_MTD + ---help--- + MTD base address in SPI Flash. + +config ESP32S3_STORAGE_MTD_SIZE + hex "Storage MTD size in SPI Flash" + default 0x100000 + depends on ESP32S3_MTD + ---help--- + MTD size in SPI Flash. + +choice ESP32S3_SPIFLASH_FS + prompt "Mount SPI Flash MTD on bring-up" + default ESP32S3_SPIFLASH_SMARTFS + depends on ESP32S3_MTD + optional + ---help--- + Mount the SPI Flash MTD with the selected File System format on board + bring-up. + If not selected, the MTD will be registered as a device node on /dev. + + config ESP32S3_SPIFLASH_SMARTFS + bool "SmartFS" + select FS_SMARTFS + select MTD_SMART + + config ESP32S3_SPIFLASH_NXFFS + bool "NXFFS" + select FS_NXFFS + + config ESP32S3_SPIFLASH_SPIFFS + bool "SPIFFS" + select FS_SPIFFS + + config ESP32S3_SPIFLASH_LITTLEFS + bool "LittleFS" + select FS_LITTLEFS + +endchoice + endif # ARCH_BOARD_ESP32S3_DEVKIT diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/spiflash/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/spiflash/defconfig new file mode 100644 index 0000000000..1dcc6a8f8a --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/spiflash/defconfig @@ -0,0 +1,50 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s3-devkit" +CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32s3" +CONFIG_ARCH_CHIP_ESP32S3=y +CONFIG_ARCH_CHIP_ESP32S3WROOM1=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ESP32S3_SPIFLASH=y +CONFIG_ESP32S3_SPIFLASH_LITTLEFS=y +CONFIG_ESP32S3_UART0=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_HOST_MACOS=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_MM_REGIONS=3 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3-devkit.h b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3-devkit.h index 509c514b61..5588ecc70b 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3-devkit.h +++ b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3-devkit.h @@ -63,5 +63,17 @@ int esp32s3_bringup(void); +/**************************************************************************** + * Name: board_spiflash_init + * + * Description: + * Initialize the SPIFLASH and register the MTD device. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32S3_SPIFLASH +int board_spiflash_init(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_SRC_ESP32S3_DEVKIT_H */ diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c index a5d54cd767..4c243a7b00 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c +++ b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c @@ -111,6 +111,14 @@ int esp32s3_bringup(void) } #endif +#ifdef CONFIG_ESP32S3_SPIFLASH + ret = board_spiflash_init(); + if (ret) + { + syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities.